行为型模式:命令模式(Command Pattern)
Command Pattern(命令模式)
一:概述
在软件实现过程中,“行为的请求者”和“行为的实现者”通常是紧耦合的。命令模式的目的就是把中间的命令封装成一个对象,实现"行为请求者",和“行为实现者”之间的松耦合。
首先它是行为模式(behavioral design pattern)。命令模式也叫(Transaction Pattern)事务模式,Action 模式。
命令模式是对命令的封装,用户程序使用的时候,请求方(Invoker)只与命令(Command)进行交互,让命令(Command)同接收命令的对象(Receiver)交互。降低了请求(Invoker)方与接收方(Command)的耦合度。
命令模式使“行为请求者”和“行为实现者”独立开来,使得“行为请求者”不必知道“行为实现者”使用的接口。更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
二:模式结构
命令模式设计到了5个角色:
Client(客户):创建具体命令(ConcreteCommand)对象和命令的接收者(Receiver);
Command(命令):声明一个给具体命令实现的接口或者抽象类。
ConcreteCommand(具体命令):义一个接受者和行为之间的弱耦合;实现Execute()方法,负责调用接收考的相应操作。Execute()方法通常叫做执方法。
Invoker(行为请求者):调用命令对象执行请求。
Receiver(行为实现者):具体实施一个请求。
三:命令模式的优点
具体的命令可以被不同的请求者角色重用
容易构造命令队列(多个命令装配程一个复合命令)
增加新的命令很容易,因为无须改变现有的类
记录相关的命令日志
增加命令状态,实现命令的撤销(undo)和重做(redo)
允许接收请求的一方决定是否可做
四:命令模式的缺点
因为针对每一个命令都要设计一个具体的命令类,会导致系统内有过多的命令类。
五:适用场合
1, Transactional behavior(事务行为)
a) 使用命令模式,可以简单的实现以下事务行为,当一个事务失败,回退到之前的状态,可以使用命令保存这种状态,简单的处理回退操作。
2, Swing中,工具条上按钮执行的命令,可以用command来封装这些命令(All implementations of javax.swing.Action)
3, (Thread pools)线程池之中,Runnable就相当于一个命令接口(Command),实现它相当于一个具体命令(ConcreteCommand)。线程池类相当于调用者(Invoker)(All implementations of java.lang.Runnable)
4, Macro Record(宏记录)
a) 可以通过command简单的封装用户的一个操作,系统就可以通过队列来保存一些类的用户操作。通过执行队列的操作,可以执行返回操作。
5, Network
a) 通过网络可以发送命令到其他机器上运行
6, Struts中的Action ,已登陆为例,Action就相当于一个命令接口,实现LoginAction的类为具体命令,当jsp页面发送一login个请求,执行LoginAction(具体命令)中的 execute()方法,最以后调用相关的业务逻辑中的接收角色
六:UML图
命令模式随处可见,就比如用人关电视这件事,电视黑屏。这其中有几个对象可以抽取出来,
人--Client
遥控器--Invoker
电视机---Receiver
电视屏幕关掉这个动作----ConcreteCommand
这其中遥控器(Invoker)和电视机(Receiver)并没有什么交集。他们就是松耦合的关系。
只是遥控器(Invoker)按了一个关机按钮(相当于发出了一个关机的命令(Command)),至于电视关没有关掉,都和遥控器没关系,因为遥控器只是一个发送命令的。
七:案例源码
行为实现者:
public class TV { public void turnOff(){ System.out.println("TV Close"); } public void turnOn(){ System.out.println("TV trun On"); } }
命令接口:
public interface ICommand { void execute(); void redo(); void undo(); }
命令实现:
public class TVCommand implements ICommand { private TV receiver; public TVCommand(TV receiver){ this.receiver=receiver; } @Override public void execute() { this.receiver.turnOn(); } @Override public void redo() { execute(); } @Override public void undo() { this.receiver.turnOff(); } }
行为请求者:
import java.util.ArrayList; import java.util.List; public class Invoker { private List<ICommand> command=new ArrayList<ICommand>(); public Invoker(){ } public void storeAndExecute(ICommand cmd){ if(!command.contains(cmd)){ this.command.add(cmd); } cmd.execute(); } }
Client:
public class Client { public static void main(String[] args) throws Exception { Invoker invoker =new Invoker(); ICommand command=new TVCommand(new TV()); invoker.storeAndExecute(command); } }
八:总结
1,命令模式解决了“行为请求者”与“行为实现者”之间紧密耦合的问题,
2,日志记录,命令撤销,批处理,事务支持都是它带来的好处。,
综合网上资料和书籍资料加上个人理解所得。请指正。随时更新

浙公网安备 33010602011771号