命令模式是一种设计模式,它尝试以物件来代表实际行动。命令物件可以把行动(action) 及其参数封装起来。
在许多设计中,经常设计一个对象请求另一个对象执行某一个操作。如果请求者无法或者不希望直接和被请求者打交道,即请求对象无法或者不希望含有被请求者的引用,那么可以使用命令模式。命令模式里称提出请求的对象为请求者,被请求者的对象为接收者。在命令模式中,当一个对象请求另一个对象调用其方法时,不和被请求者直接打交道,而是把这种“请求”封装到一个“命令”对象中,封装的手段将“请求”封装到“命令”对象的一个方法中。命令模式的核心就是使用命令对象来封装方法调用。
核心结构
1、接收者:接收者是一个类的实例,该实例负责执行与请求相关的操作。
2、命令接口:命令式一个接口,规定了用来封装“请求”的若干个方法,比如execute()、undo()等方法。
3、具体命令:具体命令式实现了命令接口的类的实例,包含命令接口的方法。并且包含接受者的引用,指明那个对象去执行该命令。
4、请求者:请求者是包含命令接口变量类的实例,该接口变量可以存放任何具体命令的引用。请求者负责调用具体命令,让具体命令执行那些封装了的请求方法。
结构图
使用命令模式还有一个好处,就是可以撤销所执行的操作。也就是请求者发送一个请求,接收者执行后,还可以撤销该操作。以下使用一个简单的例子说明怎样在具体的命令中实现undo()方法.
java代码示例
接受者
//命令接收者
public class MakeDir {
//创建目录
public void createDir(String name){
File dir = new File(name);
dir.mkdir();
}
//删除目录
public void deleteDir(String name){
File dir = new File(name);
dir.delete();
}
}
命令接口
public interface Command {
void execute(String name);
void undo();
}
具体命令
public class ConcreteCommand implements Command {
ArrayList dirNameList;
MakeDir makeDir;
public ConcreteCommand(MakeDir makeDir) {
dirNameList = new ArrayList();
this.makeDir = makeDir;
}
public void execute(String name) {
makeDir.createDir(name);
dirNameList.add(name);
}
public void undo() {
if(dirNameList.size()>0){
makeDir.deleteDir(dirNameList.get(dirNameList.size()-1));
dirNameList.remove(dirNameList.size()-1);
}else{
System.out.println(“没有需要撤销的操作!”);
}
}
}
请求者
public class RequestMakeDir {
Command command;
public void setCommand(Command command) {
this.command = command;
}
public void startExecuteCommand(String name){
command.execute(name);
}
public void undoCommand(){
command.undo();
}
}
测试类
public class Application {
public static void main(String[] args) {
MakeDir makeDir = new MakeDir(); //创建接收者
Command command = new ConcreteCommand(makeDir);//创建具体命令并且指定接收者
RequestMakeDir request = new RequestMakeDir(); //创建请求者
request.setCommand(command); //设置命令
request.startExecuteCommand(“haha”); //创建目录
request.startExecuteCommand(“hahaa”);
request.undoCommand(); //撤销
request.undoCommand();
}
}
参考:
http://liuling123.com/2013/04/design-pattern-command.html
http://www.cnblogs.com/qianxudetianxia/archive/2011/08/13/2135478.html