十四、责任链模式(Chain of Responsibility)
1、定义
使多个对象都有机会处理请求,避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有一个对象来处理它为止。
2、类图
Handler:定义职责的接口,通常在这里定义处理请求的方法,可以在这里实现后继链。
ConcreteHandler:实现职责的类,在这个类里面,实现对在它职责范围内请求的处理,如果不处理,就继续转发请求给后继者。
Client:职责链的客户端,向链上的具体处理者对象提交请求,让职责链负责处理。
3、调用顺序
4、示例代码
5、 何时选用职责链模式
1、如果有多个对象可以处理同一个请求,但是具体由哪个对象来处理该请求,是运行时刻动态确定的
2、如果你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求的话,可以使用职责链模式
3、如果想要动态指定处理一个请求的对象集合,可以使用职责链模式,职责链模式能动态的构建职责链
十五、策略模式(Strategy)
1、定义
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
2、类图
ConcreteStrategy:具体的策略实现,也就是具体的算法实现。
Context:上下文,负责和具体的策略类交互,通常上下文会持有一个真正的策略实现,上下文还可以让具体的策略类来获取上下文的数据,甚至让具体的策略类来回调上下文的方法。
3、调用顺序
4、示例代码
/**
* 策略,定义算法的接口
*/
public interface Strategy {
/**
* 某个算法的接口,可以有传入参数,也可以有返回值
*/
public void algorithmInterface();
}
复制代码
/**
* 实现具体的算法
*/
public class ConcreteStrategyA implements Strategy {
public void algorithmInterface() {
//具体的算法实现
}
}
复制代码
/**
* 实现具体的算法
*/
public class ConcreteStrategyB implements Strategy {
public void algorithmInterface() {
//具体的算法实现
}
}
复制代码
5、何时选用策略模式
1、出现有许多相关的类,仅仅是行为有差别的情况
2、出现同一个算法,有很多不同的实现的情况
3、需要封装算法中,与算法相关的数据的情况
十六、模板方法模式(Template Method)
1、定义
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
2、类图
ConcreteClass:具体实现类。用来实现算法骨架中的某些步骤,完成跟特定子类相关的功能。
3、示例代码
十七、命令模式(Command)
1、定义
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
2、类图
Command:定义命令的接口,声明执行的方法。
ConcreteCommand:命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
Receiver:接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
Invoker:要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
Client:创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。
3、调用顺序
4、示例代码
真实示例
5、何时选用命令模式
1、如果需要抽象出需要执行的动作,并参数化这些对象,可以选用命令模式,把这些需要执行的动作抽象成为命令,然后实现命令的参数化配置
2、如果需要在不同的时刻指定、排列和执行请求,可以选用命令模式,把这些请求封装成为命令对象,然后实现把请求队列化
3、如果需要支持取消操作,可以选用命令模式,通过管理命令对象,能很容易的实现命令的恢复和重做的功能
4、如果需要支持当系统崩溃时,能把对系统的操作功能重新执行一遍,可以选用命令模式,把这些操作功能的请求封装成命令对象,然后实现日志命令,就可以在系统恢复回来后,通过日志获取命令列表,从而重新执行一遍功能
5、在需要事务的系统中,可以选用命令模式,命令模式提供了对事务进行建模的方法,命令模式有一个别名就是Transaction。
十八、观察者模式(Observer)
1、定义
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
2、类图
Subject:目标对象,通常具有如下功能:
-
一个目标可以被多个观察者观察;
-
目标提供对观察者注册和退订的维护;
-
当目标的状态发生变化时,目标负责通知所有注册的、有效的观察者; Observer:定义观察者的接口,提供目标通知时对应的更新方法,这个更新方法进行相应的业务处理,可以在这个方法里面回调目标对象,以获取目标对象的数据。
ConcreteSubject:具体的目标实现对象,用来维护目标状态,当目标对象的状态发生改变时,通知所有注册有效的观察者,让观察者执行相应的处理。
ConcreteObserver:观察者的具体实现对象,用来接收目标的通知,并进行相应的后续处理,比如更新自身的状态以保持和目标的相应状态一致。
3、调用顺序
4、示例代码
十八、访问者模式(Visitor)
1、定义
表示一个作用于某个对象结构中的各元素的操作。它使你可以在不改变各元素的类 的前提下定义作用于这些元素的新操作。
2、类图
Visitor:访问者接口,为所有的访问者对象声明一个visit方法,用来代表为对象结构添加的功能,理论上可以代表任意的功能。
ConcreteVisitor:具体的访问者实现对象,实现要真正被添加到对象结构中的功能。
Element:抽象的元素对象,对象结构的顶层接口,定义接受访问的操作。
ConcreteElement:具体元素对象,对象结构中具体的对象,也是被访问的对象,通常会回调访问者的真实功能,同时开放自身的数据供访问者使用。
ObjectStructure:对象结构,通常包含多个被访问的对象,它可以遍历这多个被访问的对象,也可以让访问者访问它的元素。可以是一个复合或是一个集合,如一个列表或无序集合。
3、调用顺序
4、示例代码
5、何时选用访问者模式
1、如果想对一个对象结构,实施一些依赖于对象结构中的具体类的操作,可以使用访问者模式。
2、如果想对一个对象结构中的各个元素,进行很多不同的而且不相关的操作,为了避免这些操作使得类变得杂乱,可以使用访问者模式,把这些操作分散到不同的访问者对象中去,每个访问者对象实现同一类功能。
3、如果对象结构很少变动,但是需要经常给对象结构中的元素对象定义新的操作,可以使用访问者模式。
二十、状态模式(State)
1、定义
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
2、类图
3、调用顺序
4、示例代码
5、何时选用状态模式
1、如果一个对象的行为取决于它的状态,而且它必须在运行时刻根据状态来改变它的行为
2、如果一个操作中含有庞大的多分支语句,而且这些分支依赖于该对象的状态
二十一、解释器模式(Interpreter)
1、定义
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
2、类图
TerminalExpression:终结符解释器,用来实现语法规则中和终结符相关的操作,不再包含其它的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的叶子对象,可以有多种终结符解释器。
NonterminalExpression:非终结符解释器,用来实现语法规则中非终结符相关的操作,通常一个解释器对应一个语法规则,可以包含其它的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的组合对象,可以有多种非终结符解释器。
Context:上下文,通常包含各个解释器需要的数据,或是公共的功能。
Client:客户端,指的是使用解释器的客户端,通常在这里去把按照语言的语法做的表达式,转换成为使用解释器对象描述的抽象语法树,然后调用解释操作。
3、调用顺序
二十二、迭代器模式(Iterator)
1、定义
提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示。
2、类图
ConcreteIterator:具体的迭代器实现对象。实现对聚合对象的遍历,并跟踪遍历时的当前位置。
Aggregate:聚合对象。定义创建相应迭代器对象的接口。
ConcreteAggregate:具体聚合对象。实现创建相应的迭代器对象。
3、示例代码
二十三、中介者模式(Mediator)
1、定义
用一个中介对象来封装一系列的对象交互。中介者使得各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立的改变他们之间的交互。
2、类图
ConcreteMediator:具体中介者实现对象。它需要了解并维护各个同事对象,并负责具体的协调各同事对象的交互关系。
Colleague:同事类的定义,通常实现成为抽象类,主要负责约束同事对象的类型,并实现一些具体同事类之间的公共功能,比如:每个具体同事类都应该知道中介者对象,也就是具体同事类都会持有中介者对象,就可以定义到这个类里面。
ConcreteColleague:具体的同事类,实现自己的业务,在需要与其它同事通讯的时候,就与持有的中介者通信,中介者会负责与其它的同事交互。
3、调用顺序
4、示例代码
5、何时选用中介者模式
如果一组对象之间的通信方式比较复杂,导致相互依赖、结构混乱,可以采用中介者模式,把这些对象相互的交互管理起来,各个对象都只需要和中介者交互,从而使得各个对象松散耦合,结构也更清晰易懂。
如果一个对象引用很多的对象,并直接跟这些对象交互,导致难以复用该对象。可以采用中介者模式,把这个对象跟其它对象的交互封装到中介者对象里面,这个对象就只需要和中介者对象交互就可以了。
二十四、备忘录模式(Memento)
1、定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
2、类图
Originator:原发器。使用备忘录来保存某个时刻原发器自身的状态,也可以使用备忘录来恢复内部状态。
Caretaker:备忘录管理者,或者称为备忘录负责人。主要负责保存备忘录对象,但是不能对备忘录对象的内容进行操作或检查。