行为模式是对不同对象之间划分责任和算法的抽象化。行为对象模式使用对象复合而不是继承。再来回顾一下各个行为模式的意图和结构。
1. 命令模式的基本介绍
意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
结构
命令模式的基本结构如下:
这里涉及到的参与者有如下几种:
- 命令(Command)角色
- 声明了一个给所有具体命令类的抽象接口。这是一个抽象角色,通常由一个Java接口或者抽象类实现。
- 具体命令(ConcreteCommand)角色
- 定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者相应的操作。execute()方法通常叫做执行方法。
- 请求者(Invoker)角色
- 负责调用命令对象的执行请求,相关的方法叫做行动方法。
- 接收者(Receiver)角色
- 负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
- 客户(Command)角色
- 创建一个具体命令(ConcreteCommand)对象并确定其接收者。
参与者如何协作?
1、Client创建一个ConcreteCommand对象并指定它的Receiver对象
2、某Invoker对象存储该ConcreteCommand
3、该Invoker通过调用Command对象的Execute操作来提交一个请求。若该命令是可撤销的,ConcreteCommand就在执行Execute操作之前存储当前状态以用于取消该命令。
ConcreteCommand对象对调用它的Receiver的一些操作以执行该请求
详见《命令模式浅析》
2. 责任链模式的基本介绍
意图
责任链的意图是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之前的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
结构
责任链模式的基本结构如下:
- Handler
- 定义一个处理请求的接口。
- ConcreteHandler
- 处理它所负责的请求
- 可访问它的后继者
详见《责任链模式浅析》
3. 解释器模式的基本介绍
意图
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
结构
解释器模式的基本结构如下:
这里涉及到的参与者有如下几种:
- AbstractExpression(抽象表达式)
- 声明一个所有的从具体表达式角色都需要实现的抽象接口。这个接口主要是一个interprete()方法 ,称作解释操作。
- TerminatalExpression(终结表达式)
- 实现了抽象表达式角色所要求的接口,主要是一个interprete()
- 文法中的每一个终结符都有一个具体终结表达式与之对应
- NonterminatalExpression(非终结表达式)
- 对文法中的每一条规则R=R1R2....Rn都需要一个具体的非终结符表达式类
- 对每一个R1R2....Rn中的符号都维护一个AbstractExpression类型的实例变量
- 为文法中的非终结符实现解释(Interprete)操作。解释(Interprete)一般要递归地调用表示R1到Rn的那些对象的操作。
- Context(上下文)
- 包含解释器之外的一些全局信息。
- Client(客户端)
- 构建(或被给定)表示该文法定义的语言中的一个特定的句子的抽象语法树。该抽象语法树由NonterminalExpression和TerminalExpression的实例装配而成
- 调用解释操作interprete()
参与者如何协作?
1、Client构建(或被给定)一个句子,它是NonterminalExpression和TerminalExpression的实例的一个抽象语法树,然后初始化上下文并调用解释操作。
2、每一个非终结符表达式节点定义相应子表达式的解释操作。而各终结符号表达式的解释操作构成了递归的基础。
3、每一个节点的解释操作用上下文来存储和访问解释器的状态。
详见《解释器模式浅析》
4. 迭代器模式的基本介绍
意图
提供一种方法顺序访问一个聚合对象中各个元素,而不是暴露该对象的内部表示。
结构
迭代器模式的基本结构如下:
这里涉及到的参与者有如下几种:
- Iterator(迭代器)
- 迭代器定义访问和遍历元素的接口
- ConcreteIterator(具体迭代器)
- 具体迭代器实现迭代器接口
- 对该聚合遍历时跟踪当前位置
- Aggregate(聚合)
- 聚合定义创建相应迭代器对象接口
- ConcreteAggregate(具体聚合)
- 具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例
详见《迭代器模式浅析》
5. 中介者模式的基本介绍
意图
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
结构
中介者模式的基本结构如下:
这里涉及到的参与者有如下几种:
- Mediator(中介者)
- 中介者定义一个接口用于各同事(Colleague)对象通信。
- ConcreteMediator(具体中介者)
- 具体中介者通过协调各同事对象实现协作行为。
- 了解并维护它的各个同事
- Colleague(同事类)
- 每一个同事类都知道它的中介者对象。
- 每一个同事对象在需与其他的同事通信的时候,与它的中介者通信。
参与者如何协作?
同事向一个中介者对象发送和接收请求。中介者在各同事间适当地转发请求以实现写作行为。
详见《中介者模式浅析》
6. 备忘录模式的基本介绍
意图
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
结构
备忘录模式的基本结构如下:
这里涉及到的参与者有如下几种:
- Memento(备忘录)
- 备忘录存储原发器对象的内部状态。原发器根据需要决备忘录存储原发器的哪些内部状态。
- Originator(原发器)
- 原发器创建一个备忘录,用于记录当前时刻它的内部状态
- 使用备忘录恢复内部状态。
- Caretaker(负责人)
- 负责保存好备忘录
- 不能对备忘录的内容进行操作或者检查。
详见《备忘录模式浅析》
7. 观察者模式的基本介绍
意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象都得到通知并被自动更新。
结构
观察者模式基本的结构如下图所示:
主要包括如下几个部分:
- Subject(目标)
- 目标知道它的观察者,可以有任意多个观察者观察同一个目标
- 提供注册和删除观察者对象的接口
- Observer(观察者)
- 为那些在目标发生改变时需获得通知的对象定义一个更新接口。
- ConcreteObserver(具体观察者)
- 实现Observer的更新接口以使自身状态与目标的状态保持一致。
JDK提供了java.util.Observer和java.util.Observable可以实现观察者模式。
详见《观察者模式浅析》
8. 状态模式的基本介绍
意图
允许一个对象在其内部状态改变的时候改变它的行为。对象看起来似乎修改了它的类。
结构
状态模式的基本结构如下:
这里涉及到的参与者有如下几种:
- Context(环境)
- 定义客户感兴趣的接口。
- 维护一个ConcreteState子类的实例,这个实例定义当前的状态。
- State(状态)
- 定义一个接口以封装与Context的特定状态相关的行为。
- ConcreteState(具体子类)
- 每个子类实现一个与Context的一个状态相关的行为。
参与者如何协作?
1、Context将与状态相关的请求委托给当前的ConreteState对象处理
2、Context可将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可访问Context。
3、Context是客户使用的主要接口。客户可用状态对象来配置一个Context,一旦一个Context配置完毕,它的客户不在需要直接与状态对象打交道。
4、Context或者ConcreteState子类都可以决定哪个状态是另外一个状态的后继者,以及是在何种条件下进行状态转换。
详见《状态模式解析》
9. 策略模式的基本介绍
意图
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。策略模式使得算法可独立于使用它的客户而变化。
结构
策略模式的基本结构如下:
- Strategy (策略)
- 定义所有支持的算法的公共接口,通常由一个接口或抽象类实现。
- ConcreteStrategy (具体策略)
- 以Strategy接口实现某具体算法。
- Context (上下文)
- 持有一个对Strategy对象的引用
详见《策略模式浅析》
10. 模板方法的基本介绍
意图
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。
结构
模板方法的基本结构如下:
这里涉及到两个角色:
- 抽象类(AbstarctClass)
- 定义一个或者多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤
- 定义并实现一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能有一些具体方法。
- 具体类(ConcreteClass)
- 实现父类定义的一个或者多个抽象方法,它们是一个顶级逻辑的组成步骤。
- 每个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级的实现各不相同。
模板方法中的方法可以分为两大类:
模板方法(template method)和基本方法(Primitive method)
- 模板方法
- 一个模板方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模板方法一般会在抽象类中定义,并由子类不加以修改地完全继承下来,所以在java中使用final来进行修饰。
- 一个抽象类可以有任意多个模板方法,而不限于一个。每个模板方法都可以调用任意多个具体方法。
- 基本方法
- 抽象方法:一个抽象方法由抽象类声明,由具体子类实现,方法使用abstract关键字修饰
- 具体方法:一个具体方法由抽象类声明并实现,而子类并不实现。一个具体方法没有abstract关键字
- 钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空的实现,作为方法的默认实现。
详见《模板方法模式浅析》
11. 访问者模式的基本介绍
意图
访问者模式是对象的行为模式,其表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
结构
访问者模式的基本结构如下:
这里涉及到的参与者有如下几种:
- Visitor(访问者)
- 声明一个或者多个访问操作
- ConcreteVistor(具体的访问者)
- 实现Visitor声明的所有接口,也就是访问者所声明的各个访问操作。
- Element(元素)
- 定义一个Accept操作,接受一个访问者对象作为一个参数。
- ConcreteElement(具体元素)
- 实现Accept操作,该操作以一个访问者为参数
- ObjectStructure(对象结构)
- 可以遍历结构中的所有元素
- 可以提供一个高层的接口以允许该访问它的元素
- 可以设计成一个复合对象或者一个集合,如一个列表(List)或者集合(Set)
详见《访问者模式浅析》
不知不觉,已经将中行为模式都写了一遍了,有兴趣的朋友可以一起研读、交流。