Head First设计模式读书笔记-第十三章 Pattern 模式
模式
模式是在某情境下,针对某问题的某种解决方案
情境:应用某个模式的情况
问题:想在某情境下达到目标,也可以氏某情境下的约束
解决方案:一个通用的设计,用来解决约束,达到目标
装饰者:包装一个对象,以提供新的行为
状态:封装基于状态的行为,并使用委托在行为之间切换
迭代器:在对象的集合之中游走,而不暴露集合的实现
外观:简化一群类的接口
策略:封装可互换的行为,并使用委托来决定要使用哪一个
代理:包装对象,以控制对此对象的访问
工厂方法:由子类决定要创建的具体类是哪一个
适配器:封装对象,并提供不同的接口
观察者:让对象能够在状态改变时被通知
模板方法:由子类决定如何实现一个算法中的步骤
组合:客户用一致的方式处理对象集合和单个对象
单例:确保有且只有一个对象被创建
抽象工厂:允许客户创建对象的家族,而无需指定他们的具体类
命令:封装请求成为对象
模式分类
根据模式的目标分成三个不同类目:
创建型:
涉及对象实例化,这类模式都提供一个方法,将客户从所需要实例化的对象中解耦
Singleton、Builder、Prototype、Abstract Factory、Factory Method
行为型:
涉及到类和对象如何交互及分配职责
行为模式的目的时对象之间的沟通与互连
Mediator、Visitor、Template Method、Iterator、Command、Memento、Interpreter、Observer、Chain of Responsibility、State、Strategy
结构型:
把类或对象组合到更大的结构中
结构型模式用来描述类和对象如何组合以建立新的结构和新功能
Proxy、Façade、Decorator、Composite、Flyweight、Adapter
另一种分类方式:模式所处理的是类或对象
类模式描述类之间的关系如何通过继承定义。类模式的关系是在编译时建立的
对象模式描述对象之间的关系,而且主要利用组合定义。对象模式的关系通常在运行时建立,而且更加动态,更加弹性。
其他的模式:
架构模式
应用模式:建立系统架构的模式,许多多层的架构都属于这一类
领域特定模式:关注特定领域的问题
业务流程模式:描述业务、顾客和数据之间的交互
组织模式:描述人类组织的结构以及实践。
用户界面涉及模式:致力于解决涉及交互式软件时的问题
设计模式能够在某个特定的情境下,对一再出现的问题提供通用的解决方案
反模式:如何采用一个不好的方案解决一个问题
通过将反模式归档,能够帮助其他人在实现它们之前,分辨不好的解决方法
剩下的模式
桥接模式
使用桥接模式不只改变实现,也改变抽象
桥接模式通过将实现和抽象放在两个不同的类层次而使其可以独立改变
桥接的优点:
将实现予以解耦,让其和界面之间不再永久绑定
抽象和实现可以独立扩展,不会影响到对方
对于“具体的抽象类”所做的改变,不会影响到客户
桥接的缺点:
适合使用在需要跨越多个平台的图形和窗口系统上
当需要用不同的方式改变接口和实现时,桥接模式很好用
桥接模式的缺点是增加了复杂度
生成器
使用生成器模式(Builder Pattern)封装一个产品的构造过程,并允许按步骤构造
生成器的优点:
将一个复杂对象的创建过程封装起来
允许对象通过多个步骤来创建,并且可以改变过程
向客户隐藏产品内部表现
产品的实现可以被替换,因为客户只看到一个抽象的接口
生成器的用途和缺点:
经常被用来创建组合对象
与工厂模式相比,采用生成器模式创建对象的客户,需要具备更多的领域知识
责任链
当需要让一个以上的对象有机会能够处理某个请求的时候,使用责任链模式(Chain of Responsibility pattern)
通过责任链模式,可以为某个请求创建一个对象链。每个对象依序检查此请求,并对其进行处理,或者将它传给链中的一个对象
责任链的优点:
将请求的发送者和接受者解耦
可以简化对象,因为它不需要知道链的结构
通过改变链内的成员或调动它们的次序,允许动态地新增或者删除责任
责任链的用途和缺点:
经常被使用在窗口系统中,处理鼠标和键盘之类的事件
并不保证请求一定会被执行,如果没有任何对象处理它的话,它可能会落到链尾端之外
不容易观察运行时的特征,有碍于除错
蝇量模式
如想让某个类的一个实例能用来提供许多“虚拟实例“,使用蝇量模式(Flyweight Pattern)
蝇量的优点:
减少运行时对象实例的个数,节省内存
将许多“虚拟“对象的状态集中管理
蝇量的用途和缺点:
当一个类有许多的实例,而这些实例能被同一方法控制的时候,使用蝇量模式
蝇量的缺点在于,一旦使用蝇量,那么单个的逻辑实例将无法拥有独立而不同的行为
解释器
使用解释器模式(Interpreter Pattern)为语言创建解释器
解释器模式的优点:
将每一个语法规则表示成一个类,方便于实现语言
因为语法由多个类表示,所以可以轻易地改变或扩展此语言
通过在类结构中加入新的方法,可以在解释的同时增加新的行为
解释器的用途和缺点:
当需要实现一个简单的语言时,使用解释器
当有一个简单的语法,而且简单比效率更重要时,使用解释器
可以处理脚本语言和编程语言
当语法规则的数目太大时,这个模式可能会变得非常繁杂。这种情况下,使用解释器/编译器的产生器可能更合适
中介者
使用中介者模式(Mediator Pattern)来集中相关对象之间复杂的沟通和控制方式
中介者的优点:
通过将对象彼此解耦,可以增加对象的复用性
通过将控制逻辑集中,可以简化系统维护
可以让对象之间所传递的消息变得简单而且大福减少
中介者的用途和缺点:
中介者常常被用来协调相关的GUI组件
中介者模式的缺点是,如果设计不当,中介者对象本身会变得过于复杂
备忘录
当需要让对象返回之前的状态时,使用备忘录模式(MementoPattern)
备忘录模式有两个目标:
存储系统关键对象的重要状态
维护关键对象的封装
备忘录的优点:
将被存储的状态放在外面,不用和关键对象混在一起,这可以帮助维护内聚
保持关键对象的数据封装
提供了容易实现的恢复能力
备忘录的用途和缺点:
备忘录用于存储状态
使用备忘录的缺点:存储和恢复状态的过程可能相当耗时
在Java系统中,可以考虑使用序列化(serialization)机制存储系统的状态
原型
当创建给定类的实例的过程很昂贵或复杂时,使用原型模式(Prototype Pattern)
通过复制实例来创建实例
原型的优点:
向客户隐藏制造新实例的复杂性
提供让客户能够产生未知类型对象的选项
在某些环境下,复制对象比创建对象更有效
原型的用途和缺点:
在一个复杂的类层次中,当系统必须从其中的许多类型创建新对象时,可以考虑原型
使用原型模式的缺点:对象的复制有时相当复杂
访问者
当想要为一个对象的组合增加新的能力,且封装并不重要时,使用访问者模式(Visitor Pattern)
访问者的优点:
运行对组合结构加入新的操作,而无需改变结构本身
想要加入新的操作,相对容易
访问者所进行的操作,其代码是集中在一起的
访问者的用途和缺点
当采用访问者模式的时候,会打破组合类的封装
因为游走的功能涉及其中,所以对组合结构的改变就更加困难