1、外观
(1)定义:提供一个统一的接口,用来访问子系统中的一群接口,从而让子系统容易使用。
(2)核心:为程序库、 框架或其他复杂类提供一个简单的接口。
(3)场景:
- 如果你需要一个指向复杂子系统的直接接口,且该接口的功能有限,则可以使用外观模式。
- 如果需要将子系统组织为多层结构,可以使用外观。
(4)优点: - 可以让自己的代码独立于复杂子系统
- 降低了大型软件系统中的编译依赖性
(5)缺点:外观可能成为与程序中所有类都耦合的上帝对象
2、适配器
(1)定义:将一类接口转换为需要的另一类接口
(2)场景:由于接口不兼容而不能一起工作的那些类需要在一起工作
(3)实现方式:
- 类的适配器模式(采用继承实现):相比对象适配器更换适配器的实现过程比较简单
- 对象适配器(采用对象组合方式实现):相比类的适配器更加解耦,能组合更多的适配对象
(4)优点: - 通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑
- 复用了现存的类,解决了现存类和复用环境要求不一致的问题
- 将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码,对象适配器还能能组合更多的适配对象
(5)缺点: - 引入开发复杂度
- 对于对象适配器来说,更换适配器的实现过程比较复杂
3、桥接
(1)定义:将抽象部分与实现部分分离,使它们都可以独立的变化
(2)场景:
- 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。
- 设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。
- 一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。
- 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
(3)实现要点: - 对象间的组合关系解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
- Bridge模式有时候类似于多继承方案,但是多继承方案往往违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
- Bridge模式的应用一般在“两个非常强的变化维度(类似迪达尔积)”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。
(4)优点:多个对象独立变化,自由组合,减少了重复代码
(5)缺点:构建复杂
4、组合
(1)定义:又叫部分整体模式,将对象组合成树形结构来表示“整体/部分”层次关系,允许用户以相同的方式处理单独对象和组合对象。
(2)场景:
- 想表示对象的部分-整体层次结构(树形结构)。
- 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
(3)实现方式: - 透明组合模式:把所有的方法都添加到Component中,这样客户端就不需要知道哪些事叶子节点和树枝节点
- 安全组合模式:是只规定系统各个层次的最基础的一致行为,而把组合本身的方法放到自身当中
(3)实现要点:树枝和叶子实现统一接口,树枝内部组合该接口。
(4)优点:高层模块调用简单。一棵树形机构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,高层模块不必关心自己处理的是单个对象还是整个组合结构
(5)缺点: - 透明组合模式:使用透明组合模式时,违反了设计模式的七大原则之一单一职责原则,即最少知道原则,然后叶子节点也会继承一些他不需要的的方法(管理其他操作的方法),这还违反了设计模式的原则之接口隔离原则
- 安全组合模式:使用安全组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒转原则
5、装饰
(1)定义:装饰模式是一种用于代替继承的技术,无需通过继承增加子类就能够扩展对象的新功能。使用对象的组合关系(区分于“组合设计模式”)代替继承关系,避免类型体系的快速膨胀。简单地说,装饰模式用于动态增加一个对象的新功能,或为功能增强。
(2)场景:
- 如果你希望在无需修改代码的情况下即可使用对象, 且希望在运行时为对象新增额外的行为。
- 希望在几个独立维度上扩展一个类。
- 需要在运行时切换不同实现方法。
(3)实现要点:类应该对扩展开放,对修改关闭: 也就是添加新功能时不需要修改代码。饮料可以动态添加新的配料,而不需要去修改饮料的代码
(4)优点: - 扩展对象功能,比继承灵活,不会导致类个数急剧增加。
- 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象。
- 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类。
(5)缺点: - 产生很多小对象。大量小对象占据内存,一定程度上影响性能。
- 装饰模式易于出错,调试排查比较麻烦。
6、享元
(1)定义:利用共享的方式来支持大量细粒度的对象,这些对象一部分内部状态是相同的。
(2)场景:享元模式由于其共享的特性,可以在任何“池”中操作, 比如:线程池、数据库连接池、JVM中的常量池。
(3)实现要点:区分哪些是共享对象
(4)优点: 极大减少内存中对象的数量,相同或相似对象内存中只存一份,极大的节约资源,提高系统性能。
(5)缺点:
- 模式较复杂,使程序逻辑复杂化。
- 为了节省内存,共享了内部状态,分离出外部状态,而读取外部状态使运行时间变长(外部状态仍然需要不断创建对象)。用时间换取了空间。
7、代理
(1)定义:
(2)场景:
(3)实现要点:
(4)优点:
(5)缺点