模板方法模式
定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式涉及两个角色。
■ 抽象模板(Abstract Template)角色:该角色定义一个或多个抽象操作,以便让子类实现;这些抽象操作是基本操作,是一个顶级逻辑的组成步骤。还需要定义并实现一个或几个模板方法,这些模板方法一般是具体方法,即一个框架,实现对基本方法的调度,完成固定的逻辑。
■ 具体模板(Concrete Template)角色:该角色实现抽象模板中定义的一个或多个抽象方法,每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法的不同实现,从而使得顶级逻辑的实现各不相同。
模板方法比较简单,额外的是设计一些钩子,来实现子类的个性化。
示例类图:
命令模式
命令模式是指,使用者向接收者发送命令,使用者并不清楚命令如何执行,也不管是怎样的过程。
在实际生活中,音乐播放器就可以看成一个命令模式的设计。我们并不知道如何播放一首歌曲,只需要点击按钮命令即可。至于播放的是MP3还是OGG,如何解码音频,数据如何送达DSP,如何将声音转成模拟信号从扬声器输出等待,我们都不需要知道。
播放器
命令模式实现
1.定义全局变量标志,比如【Play】、【Pause】、【Next】等。
2.请求方只发送命令:【Play】、【Pause】、【Next】。
3.接收方解析命令,并调用对应的流程实现具体功能。
除了选择不同的命令之外,还可以选择不同的接收者。比如我们需要播放音频和视频,分别要使用音频播放器和视频播放器,但是对于上层的命令是一样的。既然我可以不管MP3还是WMA,我也可以不管这是MP3还是MP4,甚至是PPT。对于用户讲,我可以直接根据文件后缀来判断我应该启动和中关联程序。
对!电脑上双击文件就打开的功能就是这样做的。如果后缀名错了,一般无法自动打开,需要手动选择打开方式。
选择不同的命令解析者和接收者
命令模式的使用场景
只要你认为是命令的地方就可以采用命令模式,例如,在GUI开发中,一个按钮的点击是一个命令,可以采用命令模式;模拟DOS命令的时候,当然也要采用命令模式;触发-反馈机制的处理等。
扩展与撤销
我们可以在已有流程上扩展命令。比如播放音乐,开启空调,开启电灯,进入回家模式。或者相反进入出门模式,把所有的电器关闭。
此时,可以创建新的接收者,让新的解析器逐步处理。
撤销类似,记录之前的状态并还原。
当然,实际编程中,我们一般会省略设置和执行的分布,不需要先设置后执行,而是设置了就马上自动执行。
责任链模式
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
对于一个事件,创建一系列相关的处理链。链上的处理者,根据条件自行处理。场景很常见:
在这种情况下,我们可以创建灵活的责任链处理模式,比如插入、删除处理者,退回、撤销等模型。
责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做任何处理),作为请求者可以不用知道到底是需要谁来处理的,这是责任链模式的核心,同时责任链模式也可以作为一种补救模式来使用。
参考资料