设计模式

本篇是为了以后便于自己复习。

设计原则:

1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

简单来说,如果每次新的需求一来,就会使某方面的代码发生变化,那么这部分的代码就要被抽出来。"把会变化的部分取出并封装起来,以便以后可以轻易地改动或扩充此部分,而不影响不需要变化的其他部分。"

2.针对接口编程,而不是针对实现编程。

3.多用组合,少用继承。

使用组合,更具弹性,在运行时动态的改变行为。

4.为了交互对象之间的松耦合设计而努力。

5.开发-关闭原则:类应该对扩展开放,对修改关闭。

6.最少知识原则:只和你的密友谈(减少对象之间的交互)

意思就是说希望我们在设计中,不要让太多的类耦合在一起,免得修改系统中一部分,就会影响到其他部分。

7.依赖倒置原则:要依赖抽象,不要依赖具体类。(不能让高层组件依赖底层组件)

8.好莱坞原则:别调用我们(高层组件),我们来调用你。

问:好莱坞原则和依赖倒置原则有什么关系?

答:依赖倒置原则教我们尽量避免使用具体类,而多使用抽象。而好莱坞原则是在创建框架或组件上的一种技巧,让底层能被挂钩进计算中,而且又不会让高层组件依赖底层组件。

两者的目标都是在解耦,但是依赖倒置原则更加注意如何在设计中避免依赖;好莱坞原则教我们创建一个有弹性的设计,允许低层结构能够互相操作,而又防止其他类太过依赖它们。

9.一个类应该只有一个引起变化的原因。

内聚:当一个模块或一个类被设计成只支持一组相关的功能时,我们说它具有高内聚;反之,当被设计成支持一组不相关的功能时,我们说它是低内聚。

这个原则告诉我们一个责任只委派给一个类。听起来容易,但做起来并不简单。区分设计中的责任,是最困难的事情之一。我们的大脑很习惯看着一大群的行为,然后将他们集中在一起,尽管他们可能属于两个或多个不同的责任。

成功的唯一方法就是不断的检查你的设计,随着系统的成长,随时观察有没有迹象显示某个类改变的原因超过了一个。



设计模式介绍:

1.策略模式

策略模式定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。例如:鸭子游戏,针对接口编程。

2.观察者模式

定义了对象之间的一对多依赖,当一个对象改变时,它的所有依赖着都会收到通知并自动更新。例如:报社和订阅者,当报社有新消息时,会通知订阅的对象有新消息了,订阅对象也可以取消订阅。

3.装饰者模式

动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的代替方案。例如:我们点咖啡通常是配料加咖啡类型,我们要根据所加的不同配料来更改价格。于是就有了抽象组件(Beverage饮料)、具体组件(具体类型的咖啡如浓缩咖啡)、抽象装饰者(Condiment配料)、具体装饰者(具体类型的配料如奶泡、焦糖)。具体装饰者中包含了抽象对象(Beverage饮料)。

4.工厂模式

定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到了子类。

5.单例模式

确保一个类只有一个实例,并提供一个全局访问点。把某个类设置成自己管理的一个单独实例,同时避免其他类再自行产生实例。

6.命令模式

将"请求"封装为对象,以便使用不同的请求、队列或者日志参数化其他对象,命令模式也支持可撤销的操作。例如给遥控器的两个个插槽编写命令,有公共接口Command,有execute方法;然后有Open类和Close类实现这个Command并编写具体操作;然后有Control类来设置和运行命令:它包含Command接口属性引用为slot,有setCommand方法,有buttonWasPressed方法里面调用了slot.execute()。

7.适配器模式

将一个类的接口,转换成客户期望的另一种接口。适配器让原本接口不兼容的类可以合作无间。

对象适配器:例如你有Duck接口,它有quack()方法和fly()方法,现在客户想要Turkey适配Duck的方法,可以建一个TurkeyAdapter类实现Duck接口,然后它有Turkey属性,实现quack()和fly()方法里面都调用Turkey的方法。

类适配器:(java语言不支持多重继承)

8.外观模式

提供一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。最好遵循最少知识原则:client只有一个交互类,这个交互类封装类所有的组件,子系统也最好遵循最少知识原则。

9.模板方法模式

在一个方法中定义一个算法的骨架,而将一些具体步骤的实现延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

例如泡茶和冲咖啡,泡茶是烧水,浸泡茶叶,倒进杯子,加柠檬;冲咖啡是烧水,浸泡咖啡,倒进杯子,加糖。这两个非常相似,我们可以提取成公共方法:烧水和倒进杯子由抽象父类方法prepareRecipe()来做,(记得把它声明为final类型,以免子类改变这个算法的顺序)而冲泡和加调料也写父类中只不过是子类去具体实现。到时候,我们只需要新建Tea对象,直接调用Tea.prepareRecipe()。

如果子类不想做模板方法的某些动作,可以在父类模板方法下加一if语句,if(customerWantsCondiments()){addCondiments},父类返回一个true,子类可以重写customerWantsCondiments()方法返回false。

10.迭代器与组合模式

迭代器模式提供一种方法顺序访问一个聚合对象的各个元素,而又不暴露其内部的表示。

组合模式允许你将对象组合成树形结构来表现"整体/部分"层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

(组合、组件、树?组合包含组件,组件有两种:组合和叶节点。)

迭代器和组合模式配合,可以让客户不需要关心面对的是组合对象还是叶节点对象。

问题:组合内的所有对象都实现了相同的接口,也意味着某些对象具备一些没有意义的方法。

解决一:让这样的方法返回null

可以让createIterator()返回null,如果这么做,客户代码就需要条件语句判断返回值。

解决二:返回false

返回一个迭代器,而这个迭代器的hasNext()永远返回false。(这个更好用)。

所以让我们在叶子对象中的createIterator(){ return new NullIterator() },而我们的NullIterator对象有public Object next(){ return null },public boolean hasNext(){ return false },public void remove(){ throw new UnsupportedOperationException();}

11.状态模式

允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。


设计模式_第1张图片

类图基本一样,但是与策略模式的区别:

状态模式:将一曲行为封装在状态对象中,context的行为随时委托在那些状态对象中的一个。context内部状态经常改变但是客户对于状态对象了解不多。

策略模式:客户主动指定context所要组合的策略对象是哪一个。策略模式能够让我们在运行时改变策略,但对于某个context对象而言,通常都只有一个适当都策略对象。

11.代理模式

为另一个对象提供替身或占位符以控制对这个对象的访问。(也可以将代理描述成另一对象的代表。)

远程代理模式:

有客户端、客服端辅助对象(stub)、服务端辅助对象(skeleton)、服务端组成。

    糖果机简要流程:

    a.CEO执行监视器,先取得远程糖果机端代理,然后调用每个代理的getState()。


设计模式_第2张图片

    b.代理上的getState()被调用,此调用被转发到远程服务。Skeleton接受到请求,然后转发给糖果机。


设计模式_第3张图片

    c.糖果机将状态返回给skeleton,skeleton将状态序列化,通过网络传回给代理,代理将其反序列化,把他当作一个对象返回给监视器。

虚拟代理模式:

场景:例如你的应用想要加载网络上的图片,但是这个过程是有延迟的,在加载完之前显示"正在加载中,请耐心等待",一旦加载完成,则显示该图片。

保护代理模式(java中动态代理):

场景:有一个人物关系示例,PersonBean有姓名、爱好、评分属性,你可以设置自己的姓名、爱好,但是不能自己给自己打分;别人可以给你打分,但是不能修改你的姓名、爱好。这样,就需要用java创建两个代理,我们只需要编写Handler来处理转来的方法。


设计模式_第4张图片

现实中,代理还有太多的变体,需要我们去发现。

12.复合模式

13.定义设计模式

模式是在某种情境下,针对某种问题提出的解决方案。

总结

装饰者:包装一个对象以提供新行为。

状态:封装了基于状态的行为,并使用委托在行为之间切换。

迭代器:在对象的集合之中游走,而不暴露集合的实现。

外观:简化一群类的接口。

策略:封装可以呼唤的行为,并使用委托来决定使用哪一个。

代理:包装对象,以控制对此对象的访问。

工厂方法:由子类决定创建的具体类是哪一个。

适配器:封装对象,提供不同的接口。

观察者:让对象能够在状态改变时被通知。

模板方法:由子类决定如何实现一个算法中的步骤。

组合:客户用一致的方式处理对象集合和单个对象。

单件:确保有且只有一个对象被创建。

抽象工厂:允许客户创建对象的家族,而无需指定他们的具体类。

命令:封装请求成为对象。

你可能感兴趣的:(设计模式)