index
各模式关系总结
工厂模式
-
简单工厂->工厂方法: 由于简单工厂模式违背开闭原则,当系统复杂的时候不易扩展,使用工厂方法模式来替代简单工厂模式,将对象的构建延迟到子类。
-
工厂方法->抽象工厂: 由于工厂方法模式每个工厂类只能生产一种产品,如果产品种类过多会导致工厂类急剧增加,抽象工厂能够构建一个产品族的产品,极大的减少了由于产品种类过多,带来的问题。
-
工厂模式与单例模式: 通常情况下工厂方法模式、简单工厂模式会与单例模式结合使用,确保工厂对象唯一。
-
工厂方法与模板方法: 工厂方法模式是模板方法的一种特殊形式,工厂方法可以作为模板方法的中的一个步骤。
单例模式
抽象工厂模型、建造者模式、原型模式都可以用单例模式来实现。
- 单例与外观: 外观模式类通常可以转换为单例模式类,因为在大部分情况下一个外观对象就足够了。
建造者模式
-
建造者与抽象工厂: 建造者关注如何分布生成对象,在生成对象前允许执行一些额外的构造步骤。抽象工厂用于生产一系列相关对象,会返回完整的对象,不需要额外操作。
-
建造者与组合: 当你创建复杂的树形结构的时候,结合建造者模式以递归的方式构建。
原型模式
-
原型与工厂方法: 原型模式没有继承的特点,但是需要进行复杂原型对象的初始化工作才能使用。工厂方法模式基于继承,但它不需要初始化步骤。
-
原型与抽象工厂: 抽象工厂模式通常基于一组工厂方法,这也是它最大的缺点(需要构建与一个继承体系的产品类对应的复杂的工厂类继承体系)。也可以利用原型模式思想,把工厂方法合并到产品类中,就可以合并两个继承体系,其中对应的工厂方法就是
clone
。 -
原型与组合、装饰: 大量使用组合模式和装饰模式的设计,可以考虑搭配原型模式来复制复杂的结构,避免重新构建结构。
-
原型与命令: 在使用命令模式保存历史记录的时候,通常利用原型模式构建命令的副本。
-
原型与备忘录: 有时候可以把原型模式作为备忘录模式的一个简化版本,其条件是你需要在历史记录中存储的对象的状态比较简单, 不需要链接其他外部资源, 或者链接可以方便地重建。
适配器模式
-
适配器与桥接: 桥接模式通常在开发前期完成结构设计,确定可以独立开发的部分。适配器模式通常在已有程序结构的基础上,让互不兼容的类能协同工作。
-
适配器与装饰: 适配器可以对已有的对象接口进行修改。装饰能在不改变对象接口的前提下增强对象的功能,此外它还支持递归组合。
-
适配器与外观: 外观模式为现有对象定义新的接口,通常作用于多个对象子系统。适配器则是想要将已有的接口运用于系统,通常作用于单个对象。
-
适配器与代理: 适配器能为封装对象提供不同的接口。代理模式能为原对象提供相同的接口。
桥接模式
-
桥接与抽象工厂: 如果由桥接定义的抽象只能与特定实现结合,这一模式搭配就非常有用。在这种情况下,抽象工厂可以对这些关系进行封装,并且对客户端代码隐藏其复杂性。
-
桥接与建造者: 桥接类负责抽象工作,各种不同的生成器负责实现工作。
组合模式
桥接模式、 状态模式和策略模式(在某种程度上包括适配器模式) 的接口非常相似。实际上,它们都基于组合模式(即将工作委派给其他对象, 不过也各自解决了不同的问题)。
-
组合与职责链: 二者可以结合使用,在这种情况下, 叶组件接收到请求后, 可以将请求沿包含全体父组件的链一直传递至对象树的底部。
-
组合与迭代器: 可以使用迭代器模式来遍历组合树。
-
组合与访问者: 可以使用访问者模式对整个组合树进行操作。
-
组合与享元: 可以使用享元模式共享叶节点节省内存。
-
组合与装饰:
- 二者的结构非常相似,两者都是通过递归组合来组织无限数量的对象。
- 装饰模式只有一个子组件,它能为被装饰对象添加额外职责,而组合模式仅对其子节点的结果进行求和。
- 你可以使用装饰器来扩展组合树种特定对象的行为。
装饰模式
-
装饰与职责链:
- 二者的类结构非常相似,两者都是通过递归组合将需要执行的操作传递给一系列对象。
- 职责链的管理者可以相互独立地执行一切操作,也可以随时停止请求传递。
- 装饰可以在遵循基本接口的情况下扩展对象行为,但无法中断请求的传递。
-
装饰与代理:
- 二者拥有相似的结构,二者构建都是基于组合的原则(一个对象应有一部分工作委派给另一个对象)。
- 代理通常自行管理其服务对象的生命周期,装饰模式则由客户端进行管控。
-
装饰与策略: 装饰模式可以让你更改对象的外表,策略模式则是改变对对象的本质。
外观模式
-
外观与抽象工厂: 当只需要对客户端隐藏子系统创建对象方式时,可以使用抽象工厂模式代替外观模式。
-
外观与代理: 二者相似之处在于都缓存了一个复杂的实体并对其进行初始化,而代理模式需要遵循与其服务对象保持相同的接口,使得代理对象可以和服务对象进行互换。
-
外观与享元: 享元模式用于在相同的资源环境下如何生成大量小型对象,外观模式实现如何用一个对象来代表一个或多个子系统。
-
外观与中介者:
- 二者的职责类似,都尝试在大量紧耦合的类中起组织作用。
- 外观的目标为子系统提供一个简单的访问接口,子系统本身感知不到外观的存在,子系统中的类可以直接通讯。
- 中介者将系统中组件的沟通中心化,各组件都知道中介者的存在,且各组件无法直接通讯。
享元模式
- 享元与单例:
- 如果能够将对象的所有共享状态简化成一个享元对象,此时二者就是类似的。
- 单例类只能有一个实体,但享元类可以有多个实体,各实体的内在状态可以不同。
- 单例对象是可变的,享元对象是不可变的。
职责链模式
-
职责链与命令:
- 职责链的管理者可以使用命令模式实现,这样你可以对同一个请求执行不同的操作。
- 也可以把请求自身定义成命令对象,这样可以对不同的请求执行相同链式操作。
-
职责链模式、命令模式、中介者模式以及观察者模式处理发送者与接收者不同的连接方式:
- 职责链模式按照一定顺序将请求传递给一系列潜在接收者,直到有一个请求者处理为止。
- 命令模式在发送者与接收者直接建立单向连接。
- 中介者消除了发送者和接收者的直接连接,强制通过中介对象进行通讯。
- 观察模式允许接收者动态的订阅和取消接收请求。
命令模式
-
命令与备忘录: 二者可以结合来实现撤销操作。在这种情况下,命令用于对目标对象执行各种不同的操作,备忘录用来保存一条命令执行前该对象的状态。
-
命令与策略:
- 二者看起来类似,它们都能通过某些行为来参数化对象。
- 可以使用命令模式将任何操作转换成对象,通过转换来延迟操作的执行、将操作放入队列、保存历史命令或发送远程服务命令。
- 策略模式通常用于描述完成某个事件的不同方式,能够在同一个上下文类中切换算法。
迭代器模式
-
迭代器与工厂方法: 二者可以一起使用,用来让子类集合返回不同类型的迭代器,并使得迭代器与集合相匹配。
-
迭代器与备忘录: 二者可以一起使用,用来获取当前迭代器的状态,在需要的时候可以进行回滚。
-
迭代器与访问者: 二者可以一起使用,用来遍历复杂的数据结构,并对其中的元素执行所需操作,即使这些元素所属的类完全不同。
中介者模式
- 中介者与观察者:
- 中介者的主要目标是消除一系列系统组件之间的相互依赖。观察者的目标是在对象之间建立动态的单向连接,使得部分对象可作为其他对象的附属发挥作用。
- 二者结合使用时,中介者对象担当发布者的角色,其他组件则作为订阅者,可以订阅中介者的事件或取消订阅。此时中介者模式和观察者模式看起来非常类似。
- 如何区分二者呢?
- 如果你将所有组件永久性的连接到同一中介者对象中,此时就是使用的中介者模式。
- 当程序中所有组件都变成了发布者,它们之间建立了动态的连接,这样程序就没有中心化的中介者对象,此时就是使用的观察者模式。
状态模式
- 状态与策略:
- 状态可以看成策略模式的扩展。
- 两者都基于组合机制: 它们都通过将部分工作委派给 “帮手” 对象来改变其在不同情景下的行为。
- 策略模式使得这些对象相互之间完全独立,它们不知道其他对象的存在。
- 但状态模式没有限制具体状态之间的依赖,且允许它们自行改变在不同情景下的状态。
策略模式
- 策略与模板方法:
- 机制不同:
- 模板方法模式基于继承机制: 它允许你通过扩展子类中的部分内容来改变部分算法。
- 策略模式基于组合机制: 你可以通过对相应行为提供不同的策略来改变对象的部分行为。
- 范围不同:
- 模板方法模式在类层次上运作,因此它是静态的。
- 策略模式在对象层次上运作,因此允许在运行时切换行为。
- 机制不同: