博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
常用设计模式概述
阅读量:2401 次
发布时间:2019-05-10

本文共 5670 字,大约阅读时间需要 18 分钟。

····································

学设计模式的时候刚学没多久,所以很多细节以及作图规范都没如何考虑,只能算记下了学习的一些过程和心得吧,请见谅。
····································

(一)简单工厂模式和工厂模式

客户端提供一个条件给工厂,工厂根据条件返回客户端需要的对象。

它根据客户端传入的参数,生成不同的对象,调用对象的方法。
简单工厂模式中可以通过反射机制来简化if…else或switch的大量繁琐引用。
它的调用如下:

Calc add = CalcFactory.createCalc("add");  calc.calc(2,5);  Calc reduce = CalcFactory.createCalc("add");  calc.calc(6,5);

它的基本思想结构图如下:

这里写图片描述

工厂模式是简单工厂模式的一种扩展,一个工厂生产一个对象,符合设计模式的开闭原则。简单工厂模式是工厂模式的一种简单版本,不属于23种设计模式之一,工厂模式是创建型模式的一种。

AddFactory addFactory = new AddFactory();Calc add=addFactory.createCalc();add.calc(2,5);ReduceFactory reduceFactory = new ReduceFactory();Calc reduce=reduceFactory.createCalc();reduce.calc(5,2);

它的基本思想结构图如下:

这里写图片描述

详解:

(二)抽象工厂模式

提供一个创建一系列相关或依赖对象的接口,而无需指定他们具体的类。

如果产品少而且基本不变动,用简单工厂模式。
如果产品单一,用工厂方法模式。
如果产品丰富,用抽象工厂模式。

抽象工厂模式引入了一个产品族与产品等级结构的概念。

它的基本思想结构图如下:
这里写图片描述
与工厂方法模式相比较,由一个具体工厂生产一个具体产品转化为一个具体工厂生产多个具体产品。
客户端的调用如下:

calcFactory = new AddFactory();  TwoNumberCalc twoAdd = calcFactory.createTwo();  ThreeNumberCalc threeAdd = calcFactory.createThree();  calcFactory = new MultiplyFactory();  TwoNumberCalc twoMultiply = calcFactory.createTwo();  ThreeNumberCalc threeMultiply = calcFactory.createThree();

详解:

(三)建造者模式

建造者模式将一个复杂的对象的具体构建过程封装,将构建与表示分离,使同一种构建方式能够创建不同的表现。

工厂模式是将不同产品的构建过程封装,而建造者模式是将同一产品的不同表示封装,他们都属于创建型模式,更关注于对象的创建。
建造者模式在这样的情况下使用:
1.当产品类的内部结构较复杂,不容易构建或易出错。
2.产品之间的属性相互依赖,即对产品的构造顺序有要求,

客户端通过一个指挥者类创建对象

PersonDirector pd = new PersonDirector();        Person person = pd.constructPerson(new FatPerson());        System.out.println(person.getHead()+person.getTummy()+person.getHand()+person.getFoot()+"的人");

详解:

(四)单例模式

对某个类来说,其实例化对象有且仅有一个,并只提供一个创建它的方式。

对于单例模式的写法很多,概述为
懒汉单例模式
饿汉单例模式
双重校验锁
静态内部类
枚举
详解:

(五)原型模式

原型模式就是从一个对象创建出另一个对象,而不必知道他的创建细节。或者可以把原型模式叫做-克隆。被复制的对象被叫做-原型。

原型模式分成浅复制和深复制。
浅复制是指复制了对象,数值类型的会直接复制,但是引用类型的变量复制的是对象的引用,所以浅复制对对象引用类型的改变也导致原对象的引用类型也同时改变,所以这被称作浅复制。
深复制的复制则代表产生一个新的与原有对象无关的复制对象。

深复制与浅复制的用法区别在深复制需要对类中用到的引用类型同时进行一次复制,需要引用类型也重写克隆方法。在克隆的类中同时调用引用类型的克隆方法。

@Override    protected Object clone() throws CloneNotSupportedException {        Resume resume = (Resume) super.clone();        resume.experience = (Experience) experience.clone();        return resume;    }

详解:

(六)策略模式

客户端提供一个对象策略给Context环境类,Context根据策略调用方法。

使用方法如下:

calcContest = new CalcContest(new AddStrategy());int addResult = calcContest.getResult(3, 2);calcContest = new CalcContest(new ReduceStrategy());int reduceResult = calcContest.getResult(3, 2);

策略模式是一种行为模式,它根据客户端传入的对象,实施不同的策略,再调用具体的行为。与简单工厂模式的不同在简单工厂根据参数暴露了对象给客户端,策略模式根据策略暴露具体的方法,但是要求客户知道策略的名称,可与与工厂模式一起使用。

详解:

(七)适配器模式

当开发后期,两个功能相似的接口因为都不太容易改,或当调用别人类似功能的接口时,通过适配器模式返回客户端一致的接口。

比如两个接口分别是:
void SayChinese();
void SayEnglish();
那么创建一个适配器Translator翻译 实现sayChinese接口

private English english;  public Translator (English english){      this.english=english;  }  public void sayChinese(){      english.sayEnglish();  }

最后的实现效果即为:

People a = new Chinese();  Translator b = new Translator b(new English());  a.sayChinese();  b.sayChinese();

通俗的说就是把sayEnglish让适配器以sayChinese的形式展示给客户端。

详解:

(八)代理模式

代理模式把客户端不容易进行交互的类通过代理与之进行交互

简单的代理运用可以理解为代购买东西,别人看到的是代购买了很多东西,代购其实花的是你的钱买东西。
代理模式是开放-封闭原则的具体实现之一。
可以理解为,代理扩展了原类的方法而不改变原类,
又或者说,代理保护了原类。
我将其放在适配器模式下是因为他们有一些地方比较像
以下是代理类

/*** @ClassName: Proxy * @Description: 代购,帮Person买苹果* @author cjd* @date 2017年12月18日 下午5:02:49   */public class Proxy implements BuyApple {    private Person person;    public Proxy(Person buyer) {        this.person = buyer;    }    @Override    public void buyApple() {        System.out.println("出国");        person.buyApple();        System.out.println("回国把苹果8交给" + person.getName());    }}

其中同样内置了一个对象,可代理模式是在实现Person的原功能下进行扩展,

而适配器模式是将一个接口转换成另一个接口,当类的功能多了,两者的差异也会变大。
详解:

(九)模板方法模式

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

举个常见的例子如:考试的时候我们都是在试卷上答题,而试卷就是一个模板,我们实现的过程不过是把我们的答案填充到模板上去。

当某些代码的大部分是不变的,而又一小部分需要经常进行变动,这时候就可以使用模板方法模式,将不变的代码作为一个模板,把经常需要改动的部分交给子类来实现。

这样做的结果自然使代码结构更加清晰,而且更易于看懂维护。
创建一个模板

public abstract class AbstractEatting {    public void eat(){        System.out.println("早餐:"+morningEat());        System.out.println("午餐:"+noonEat());        System.out.println("晚餐:"+eveningEat());    }    public abstract String morningEat();    public abstract String noonEat();    public abstract String eveningEat();}

模板的填充

public class CjdEatting extends AbstractEatting {    @Override    public String morningEat() {        return "鸡蛋";    }    @Override    public String noonEat() {        return "面条";    }    @Override    public String eveningEat() {        return "馄饨";    }}

模板方法避免了我们在类继承上进行一些错误的应用,也很好的规范了我们的代码

(十)桥接模式

桥接模式是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

比方说一个东西有颜色,形状,大小之分,若是要通过类继承的方式来实现,就会造成类数量的大量爆炸,也很难去维护新的实现,而通过桥接,将抽象与实现分离,只向客户端展示所关心的部分,而把其余部分抽象,通过注入持有的方式让他们结合使用。

这样使用的好处在,当我们需要一个新的颜色或者新的形状时,都只需要在原有上增加一个类即可,又或者以后需要增加大小的新判定等等….极大的维护了代码的易扩展性。

客户端只需要进行诸如以下的简单调用或是扩展即可

public class Main {    public static void main(String[] args) {        Color drawRed = new Red();        drawRed.setDrawShape(new DrawCircular());        //扩展一些其他的抽象,如大小 drawRed.setDrawSize(new DrawBig());        drawRed.draw();    }}

(十一)观察者模式

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

观察者模式有这样几种使用场景:

1.当一个对象的改变需要导致未知个未知对象的改变时。
2.一个对象的改变必须通知其他对象。
3.对象改变时其他对象知道改变而不需要知道细节。
4.几个方面的互相依赖关系
5.功能链的触发,A导致B B导致C C导致D……

比方说微博的通知,公众号的消息推送都是一种观察者模式的应用,他的应用场景在生活中也非常的常见。

定义好需要推送的主题,让观察者去订阅这个主题,调用主题通知所有订阅的观察者。

public class Main {    public static void main(String[] args) {        //具体需要通知的主题        Subject subject = new EntitySubject();        //观察者订阅主题        new EntityObserver(subject);        //主题通知所有观察者        subject.notifyObservers();    }}

在观察者模式的应用上需尽量避免相互的一个循环,容易导致系统缓慢或崩溃

你可能感兴趣的文章
安装、完善slackware的全部过程(转)
查看>>
Windows+Apache+resin配置(转)
查看>>
proxy 相关问题集(转)
查看>>
Linux下NFS网络文件系统设定及管理(转)
查看>>
ORACLE常用傻瓜问题1000问(之十二)(转)
查看>>
已经装了最新的binutils,为什么grub还是不能用(转)
查看>>
网络管理员指南 -10.网络信息系统 -1>熟悉NIS(转)
查看>>
巧用打印口制作笔记本密码破解器(转)
查看>>
Oracle 8 的函数介绍(转)
查看>>
CVSClient/Server连接设置(转)
查看>>
hosts.equiv和.rhosts文件(转)
查看>>
Linux关机命令详解(转)
查看>>
cron的使用(转)
查看>>
javascript动态隐藏显示技术(转)
查看>>
硬盘主引导记录详解(转)
查看>>
安装J2SE 1.3.1 for Linux的方法(转)
查看>>
Apche日志系列(5):高级技术(转)
查看>>
谈谈数据从sql server数据库导入mysql数据库的体验(转)
查看>>
解读startx(转)
查看>>
RMAN配置DATAGUARD完整案例(主库基于ASM存储)
查看>>