《GOF设计模式》笔记之--Command命令模式介绍

《GOF设计模式》笔记之--Command命令模式介绍

官方描述
将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
 
我的描述
1、模式理解
我觉得命令模式可以从以下几点进行理解:
1)分离框架和应用逻辑
在GOF《设计模式》动机部分,描述了用户界面框架中按钮和菜单这样的对象,这些对象执行操作以对用户请求进行响应,但是由于这些对象属于工具箱的一部分,所以在实际的被用户使用之前,根本不能确定执行的操作内容,操作内容属于具体应用的一部分。为了在界面框架和基于该框架的应用之间协调的工作,并提供灵活的可扩展性,采用Command命令模式,该模式把操作内容从按钮和菜单项中分离出来,并通过定义一个抽象的Command类型来进行衔接,这样具体应用程序就可以通过实现具体的Command子类,来对应用程序中按钮和菜单项的操作任务进行灵活的定制。
在Struts框架中,框架通过Action类来封装请求操作,通过这种封装,使多变的请求逻辑和稳定的框架进行了分离,从而既实现了框架的完整性,又增强了框架使用的可扩展和可定制性。
在基于Struts的开发中,我们通过实现具体的Action子类来执行具体的请求操作,对于复杂的J2EE Web系统,我们仍然可以对系统进行分层处理,在业务层再创建具体的业务处理对象(比如Session Bean Facade或业务处理JavaBean Manager),子Action通过调用业务处理对象(对应Receiver)完成请求操作。
2)增强可扩展性和可切换性
即使不是在框架中,我们仍然可以采用Command命令模式,将请求从调用对象中分离出来,并进行包装,这样通过定义抽象的Command类型,及实现具体的不同子类,从而可以灵活的用具体Command对象对系统进行配置,当需要新的请求处理方式时,可以简单的再定义新的Command子类,并用其装配系统,从而实现很好的可扩展性;
同时因为各Command子类具有兼容的接口,所以系统可以在运行时根据需要对所使用的Command对象进行切换。
3)集中与请求密切相关的内容
有些时候,一些附加的操作很有必要,比如请求的撤销操作,排队以及日志记录操作等等,如果没有将Command分离出来,而是把请求操作放到象按钮或菜单对象内部,那么再增加这些附加的操作,必然会使得按钮/菜单这些对象变得极其的复杂,从而不便于实现和维护。
Command模式的采用,将请求从业务对象中分离出来,进行独立的封装,这样对于与请求密切相关的内容,就可以集中放到Command对象内部,从而简化业务对象的设计。
2、Command模式与其它模式的关系
1)和Adapter模式的关系
在GOF《设计模式》实现部分中,谈到Command的智能程度,一种极端是它只确定一个接收者和执行该请求的动作;另一种极端是它实现所有的功能,根本不需要额外的接收者对象。对于第一种极端,我觉得它起到了一种Adapter适配器的作用,它在客户端和实现者之间建立了一种协调的关系,而这和Adapter模式的核心区别就是意图不同,Adapter模式侧重于提供一种结构上的协调,Command模式则侧重于将请求从业务对象中分离。
2)和Composite模式的关系
当需要对Command对象进行组合,以构造宏命令时,组合的对象仍然是一种Command类型,当用户调用该组合Command对象的执行操作时,组合Command相应调用所含的各个Command成员执行操作。
3)和Memento模式的关系
当需要提供请求的撤销操作时,在请求执行之前需要把请求所操作的对象状态进行保存,以备撤销是使用,这是可以采用Memento备忘录模式进行对象内部状态地存储。
 
3、备注
1)Command模式的结构图
《GOF设计模式》笔记之--Command命令模式介绍
2)Command模式参与者描述
1、客户(Client)角色:创建了一个具体命令(ConcreteCommand)对象并确定其接收者。
2、命令(Command)角色:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色。
3、具体命令(ConcreteCommand)角色:定义一个接受者和行为之间的弱耦合;实现Execute()方法,负责调用接收考的相应操作。Execute()方法通常叫做执方法。
4、请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
5、接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
 
4、参考资料
GOF《设计模式——可复用面向对象软件的基捶