设计模式探秘-27-比较总结

创建类模式包括工厂方法模式、建造者模式、抽象工厂模式、单例模式和原型模式,都能够提供对象的创建和管理职责。单例模式要求在内存中只有一个对象,原型模式要求通过复制的方法产生一个新的对象。

工厂方法模式和建造者模式

工厂方法模式注重的是整体对象的创建方法,而建造者模式注重的是部件构建的过程,旨在通过一步一步的精准构造创建出一个复杂的对象。
工厂方法模式和建造者模式都属于对象创建类模式,都用来创建类的对象,但区别还是比较明显的:

  1. 意图不同,工厂方法模式中,关注产品整体,无须关心产品的各部分是如何创建出来的;在建造者模式中,一个具体产品的产生依赖各个部件的产生以及装配顺序,关注的是“由零件一步一步地组装出产品对象”。简单说:工厂模式是一个对象创建的粗线条应用,建造者模式则是通过细线条勾勒出一个复杂对象,关注产品组成部分的创建过程。
  2. 产品复杂度不同,工厂方法模式创建的产品一般都是单一性质产品,而建造者模式创建的都是复合产品,由哥哥不见复合而成,不见不同产品对象也不相同。工厂方法模式的对象粒度比较粗,而建造者模式的对象粒度比较粗。

抽象工厂模式和建造者模式

抽象工厂模式实现对产品家族的创建,一个产品家族是一系列的产品:具有不同分类维度的产品组合,采用抽象工厂模式则不需要关心构建过程,只关心什么产品由什么工厂生产即可,而建造者模式则是要求按照指定蓝图建造产品,主要目的是通过组装零部件而产生一个新产品。
抽象工厂模式比建造者模式的尺度要大,关注产品整体,建造者模式关注建造过程,因此建造者模式可以很容易构建出一个崭新产品。
抽象工厂模式适用于希望屏蔽对象的创建过程,只提供一个封装良好的对象,而建造者模式可以用在构建的装配方面,通过不同装配方案产生新对象,其可产生一个非常灵活的架构,方便地扩展和维护系统。

结构类模式包括适配器模式、桥梁模式、组合模式、装饰模式、门面模式、享元模式、代理模式。结构类模式:通过组合类或对象产生更大结构以适应更高层次的逻辑需求。

代理模式和装饰模式

装饰模式是代理模式的一种特殊应用。共同点:具有相同的接口。不同点:代理模式着重代理过程的控制,装饰模式则是对类的功能进行加强和减弱,着重类的功能变化。
代理模式把当前的行为或功能委托给其他对象执行,代理类负责接口限定:是否可以调用真实角色,以及是否对发送到真是角色的消息进行变形处理,不对被主题角色(被代理类)的功能做任何处理,保证原汁原味的调用。
装饰模式在保证接口不变的情况下加强类功能,保证被修饰对象功能比原始对象丰富,但不做准入条件判断和准入参数过滤。

装饰模式和适配器模式

装饰模式和适配器模式在功能上相似,都是包装作用,通过委托方式实现其功能,不同点是,装饰模式包装的是自己的兄弟类,隶属同一个家族(相同接口或父类),适配器模式则修饰非血缘关系类,把一个非本家族的对象伪装成本家族的对象,注意是伪装,其本质还是非相同接口的对象。

不同点:

  1. 意图不同
    1. 装饰模式的意图是加强对象的功能。
    2. 适配器模式关注的是转化,主要意图是两个对象间的转化。
  2. 施与对象不同
    1. 装饰模式装饰对象必须是自己的同宗,即有相同的接口或父类
    2. 适配器模式必须是两个不同的对象
  3. 场景不同
    1. 装饰模式在任何时候都可以用,只是相增强类的功能
    2. 适配器模式则是一个补救模式,一般出现在系统成熟或已经构建完毕的羡慕中。
  4. 扩展性不同
    1. 装饰器模式易于扩展
    2. 适配器模式建立容易,想去掉就不容易拉

行为类模式包括责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模版方法模式、访问者模式。

命令模式和策略模式

策略模式的意图是封装算法,让算法独立,并且可以相互替换,让行为的变化独立于拥有行为的客户。命令模式是对动作的解耦,把一个动作的执行分为执行对象(接受者角色)、执行行为(命令角色)、让两者相互独立而不相互影响。

不同:

  1. 关注点不同,策略模式关注算法的替换,而命令模式关注的是解耦问题。
  2. 角色功能不同,策略模式中的具体算法是负责一个完整算法逻辑,是不可再拆分的原子业务单元,一旦变更就是对算法整体的变更。命令模式关注命令的实现,也就是功能的实现。
  3. 使用场景不同,策略模式适用于算法要求变换的场景,命令模式适用于解耦两个有紧耦合关系的对象场合或者多命令多撤销的场景。

策略模式和状态模式

策略模式封装的是不同的算法,算法之间没有交互,以达到算法可以自由切换的目的,而状态模式封装的是不同的状态,已到达状态切换行为随之发生改变的目的。虽然都有变换的行为,但两者目标不同。

不同:

  1. 环境角色的职责不同 策略模式的环境角色只是一个委托作用,负责算法的替换,而状态模式的环境角色不仅仅是委托行为,还具有登记状态变化的功能,与具体状态类协作,共同完成状态切换行为随之切换的任务。
  2. 解决问题的重点不同 策略模式旨在解决内部算法如何改变的问题,将内部算法的改变对外界的影响降低到最小程度,保证的是算法可以自由地切换,状态模式旨在解决内在状态变化而引起行为改变的问题,出发点是事物的状态,封装状态而暴露行为,一个对象的状态改变,从外界看好像行为改变。
  3. 解决问题的方法不同 策略模式只是确保算法可以自由切换,什么时候用什么算法它不能决定,而状态模式对外暴露的是行为,状态的变化由环境角色和具体状态共同完成,状态模式封装了状态的变化而暴露了不同行为或行为结果。
  4. 应用场景不同 策略模式的算法必须是平行的,状态模式要求一系列状态发生变化的场景,要求是有状态且有行为的场景,一个对象必须具有二维(状态和行为)描述才能采用状态模式,如果只有状态而没有行为,则状态的变化就失去了意义。
  5. 复杂度不同 策略模式较简单(结构简单,扩展容易,代码容易阅读)。状态模式较复杂,要从两个角色看出对象状态和行为的改变,即封装的是变化。

观察者模式和责任链模式

触发链和责任链虽然都是链结构,但有所区别

  1. 链中的消息对象不同 从首节点开始到最终的尾节点,两个链中传递的消息对象是不同的。责任链模式基本不改变消息对象的结构,虽然每个节点都可以参与消费(一般不参与消费),但结构不会发生变化。触发链模式中链中对象可以自由变化,上下级之间传递对象了解即可,不要求链中消息对象不变化,只要求链中相邻两个节点的消息对象固定。
  2. 上下节点的关系不同 责任链模式中,上下节点没有关系,都接受相同的对象,所有传递的对象都是从链首传递过来,上一节点是没有什么关系,按照自己的逻辑处理即可。触发链模式上下级关系亲密,链中任意两个相邻节点都是一个牢固的独立团体。
  3. 消息分销渠道不同 责任链模式中,一个消息从链首传递进来后,沿着链条向链尾移动,方向是单一、固定的。触发链模式不同,采用观察者模式,非常灵活,一个消息传递到链首后,具体怎么传递不固定,可以广播方式传递,也可跳跃方式传递,取决于处理消息的逻辑。

创建类模式描述如何创建对象,行为类模式关注如何管理对象的行为,结构类模式着重如何建立软件结构。

策略模式和桥梁模式

策略模式是行为模式,旨在封装一系列的行为。桥梁模式解决在不破坏封装的情况下抽取出抽象部分和实现部分,前提是不破坏封装,让抽象部分和实现部分都可以独立的变化。策略模式使用继承和多态建立一套可以自由切换算法的模式,桥梁模式在不破坏封装性的前提下解决抽象和实现都可以独立扩展的模式。

门面模式和中介者模式

门面模式为复杂系统提供统一的访问界面,定义的是一个高层接口,该接口使子系统更加容易使用,避免外部模块深入到子系统内部,而产生与子系统内部细节耦合的问题。
中介者模式使用中介对象封装一系列同事对象的交互行为,使各个对象之间不再显式地引用,从而使其耦合松散,建立可扩展的应用架构。

不同:

  1. 功能区别 门面模式只是增加了一个门面,对子系统没有增加任何功能,子系统脱离门面模式完全可以独立运行,中介者模式增加了业务功能,把各个同事类中的原有耦合关系移植到中介者,同事类不可能脱离中介者而独立存在。
  2. 知晓状态不同 门面模式中子系统不知道门面的存在,对中介者来说,每个同事类都知道中介者存在,因为要依靠中介者调和同事间关系。
  3. 封装程度不同 门面模式是简单封装,所有请求处理都委托给子系统完成,中介者模式则需要有一个中心,由中心协调同事类完成,并且中心本身也完成部分业务,术语更进一步的业务功能封装。

包装模式比较

包装模式包括:装饰模式、适配器模式、门面模式、代理模式、桥梁模式。
包装模式都通过委托的方式对一个对象或一系列对象施行包装,使设计的系统更加灵活、稳定、具有扩展性。从实现角度看,都是代理的一种表现形式。

  1. 代理模式:主要用在不希望展示一个对象内部细节的场景中。
  2. 装饰模式:特殊的代理模式,倡导不改变接口的前提下为对象增强功能,或动态添加额外职责,就扩展性而言,比子类更加灵活。
  3. 适配器模式:主要意图是接口转换,把一个对象的接口转换成系统希望的另一种接口,避免外界深入系统内部,提高系统的稳定性和可靠性。
  4. 桥梁模式:在抽象层产生耦合,解决自行扩展的问题,使两个耦合关系的对象互不影响的扩展。
  5. 门面模式:一个粗粒度的封装,提供一个方便访问子系统的接口,不具有任何业务逻辑,仅仅是一个访问复杂系统的快速通道,没有门面,子系统也可正常运行。

参考资料

  1. 设计模式之禅
  2. GoF+23种设计模式解析