现在的位置: 首页 > 综合 > 正文

GOF 设计模式之 Command

2013年09月21日 ⁄ 综合 ⁄ 共 2704字 ⁄ 字号 评论关闭

GOF Command设计模式 将一个请求封装成一个对象,从而使你可用不同的请求进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。” 耦合与变化 “耦合是软件不能抵御变化灾难的根本性原因,不仅实体对象与实体对象之间存在耦合关系,实体对象与行为操作之间也存在耦合关系。” 首先我们看看行为的请求者与行为实现者间正常的关系: 动机在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”,我们日常写代码也是这么写的,一般来说没有太大问题。但在某些场合—比如需要对行为进行“记录”、“撤销”、“重做”、“事务”等处理,这种无法抵御变化的紧后河是不合适的。如何实现这两者之间的解耦呢? GOF设计模式之Command模式是这样做的:“将一个请求封装成一个对象,从而使你可用不同的请求进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。”,我们把行为请求者记为A,实现者为B,明显A和B之间存在着直接依赖,而这种直接依赖在A或B一方发生变化时是存在不稳定因素的,因此Command模式是想想办法把A与B之间的直接依赖关系转化为间接依赖,间接实现A与B之间的关系,即在A与B之间加入一个中间,A去依赖C,B也去依赖C,而其依赖的C则是一个抽象层。Command模式是对行为(B)进行抽象 从而实现了A与B之间的间接依赖关系,实现了其送耦合关系。接下来的一个例子是李建忠老师视频里的,我觉得它可以很好的阐述Command模式。 import java.util.Stack; //////////////////////////////////////////////////////////////// // // // 关键:依赖关系转化 // // 本来是A与B存在依赖关系的(紧耦合),现在在A与B之间加入C,A与B都去依赖C // // 而C则是一个抽象 // // // /////////////////////////////////////////////////////////////// /* * COMMAND设计模式--抽象体-----------------------------------相当于C */ public interface Command { public abstract void Show(); public abstract void Undo(); public abstract void Redo(); } // 已经存在的,实现细节,低层实现,单单是以个实体,不扮演行为实现的角色 //-------------------------------------------------------相当于B class Document { public void ShowText() { // ... } } // 已经存在的,实现细节,低层实现,单单是以个实体,不扮演行为实现的角色 //-------------------------------------------------------相当于B class Graphics { public void ShowGrahpic() { // ... } } // 具体化的命令对象--从抽象意义来讲,DocumentCommand表示一个行为 class DocumentCommand implements Command { Document document; public DocumentCommand(Document doc) { this.document = doc; } public void Show() { document.ShowText(); } public void Undo() { // ... } public void Redo() { // ... } } // 具体化的命令对象--从抽象意义来讲,GraphicsCommand表示一个行为 class GraphicsCommand implements Command { Graphics graph; public GraphicsCommand(Graphics graph) { this.graph = graph; } public void Show() { graph.ShowGrahpic(); } public void Undo() { // ... } public void Redo() { // ... } } // 应用程序主干--高层抽象----依赖于共有抽象,不依赖任何具体实现----能够对行为进行记录,实现Undo、Redo等操作 //---------------------------------------------------------相当于A class Application { Stack stack; Stack undoList; public void show() { while (stack.iterator().hasNext()) { stack.iterator().next().Show(); } } public void Undo() { if (!stack.isEmpty()) { Command command = stack.pop(); command.Undo(); undoList.add(command); } } public void Redo() { if(!stack.isEmpty()){ Command command = undoList.pop(); command.Redo(); } } } Command UML 图 其中Client即上述说的行为请求者A,即上例中的程序主体类Application,这里的ConcreteCommand就相当于上例中的DocumentComand和GraphicesCommand,而Receiver则相当于Document和Graphices,即行为实现者B。具体的方法Action可以是带参或无参,与Command间没直接关系,只需Command与ConcreteCommand的接口Excute保持一致就行,state保存一定状态信息。而最高层的抽象层则我们所说的中间抽象层C。 Command模式几个要点: 1. 根本目的在于将“行为请求者”和“行为实现者”解耦,在面向对象语言中,常见的实现手段是“将行为抽象为对象”。 2. 实现Command接口的具体命令对象ConcreteCommand有时候根据需要可能会保存一些额外的状态信息。 3. 通过使用Composit模式,可以将多个“命令”封装为一个“复合命令”对象MacroCommand。 参考资料: Design Patterns:Elements of Reusable Object-Oriented Software C# 设计模式纵横谈(李建忠)

抱歉!评论已关闭.