什么情况下用到命令模式
希望一列系的动作能够有计划的进行,可以进行保存,撤销等操作。将普通的任务改造成命令模式是很简单的。一般情况下,不要急于使用命令模式,真正需要的时候再去改造也是很容易的。
为什么后续的改造会很简单?原因在于,动作的执行者是对命令类是没有依赖的。举个例子,假如有正常的功能 类A,它很普通,对谁都没有依赖。这个时候,如果需要改造出一个命令类C,这个命令可以调用功能A,可以将类A以参数的方式传递给C,在C执行的时候,直接调用类A就好了。
类图
类图的关键有以下两点
1. 真正的功能类(也叫命令的接收者)对于命令类没有依赖
2. 有一个管家类用来组织这些命令
代码来解释
抽象的命令类(接口也可以)
public interface BaseCommand<T>{
//最基础的命令的抽象,只有两个功能,一个是指定接收者,一个是执行
public void execute();
//后面本来可以写一个基类的,但是发现这里使用泛型更好,这里没有对接收者做任何的约束,别人是属于正常功能的一部分
public void setReceiver(T receiver) ;
}
具体的命令类
public class CloseCommand implements BaseCommand<BaseFunction>{
private BaseFunction baseFunction;
@Override
public void execute() {
// TODO Auto-generated method stub
baseFunction.close();
}
@Override
public void setReceiver(BaseFunction baseFuncation) {
// TODO Auto-generated method stub
this.baseFunction = baseFuncation;
}
}
具体的功能类
public class Light implements BaseFunction{
@Override
public void open() {
// TODO Auto-generated method stub
Log.d("我是灯泡,执行打开操作");
}
@Override
public void close() {
// TODO Auto-generated method stub
Log.d("我是灯泡,执行关闭操作");
}
}
调用的部分最有意思。light身为一个普通的类,是可以单独构造,单独调用的。
命令模式只是做了以下两步:
第一步,简单的用一个命令包装一下普通类
第二步,进一步封装,用一个调用的管理者来管理
BaseCommand openCommand = new OpenCommand();
openCommand.setReceiver(new Light());
//放到一个调用者中一起调用
Invoker invoker = new Invoker();
invoker.addCommand(openCommand);
invoker.addCommand(closeCommand);
invoker.excuteCommand();
为了更好的查看,以代码的方式进行了记录.详情请查看DesignPattern中的 com.arron.pattern.command下的内容.戳我查看详情