目录
命令模式
为什么使用命令模式
命令模式应用实例
命令模式
命令模式:在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)
从上面对于命令模式的定义也反映出了为什么要使用命令模式,通过将一系列的操作封装成一个命令对象,方便执行,同时也能够很好的让我们进行一些操作回滚,用来记录是否执行过该操作等问题。
为什么使用命令模式
当我们有一系列任务要进行处理,也就是很多方法,而且这些任务之间没有明显的先后顺序,而我们只有一个线程用来执行任务,比如某个物品的装配任务,不同的人采用了不同的装配顺序,假设不同装配顺序都可产生该产品,但是只有一个装配机器进行装配任务,因此我们不可能将每个装配步骤写在装配机器程序中,因为每个人的装配步骤是不同的,所以每个用来执行装配任务的机器必须能够进行动态的调整,所以这个时候命令模式的作用发挥出来了,我们可以这样架构该系统。代码如下:
/定义一个命令接口
public interface Command{
public void execute();
public void undo();
}
//其中的一个命令继承自这个接口
public class addPatCommand implements Command{
public void execute(){
doSomething...
}
public void undo(){
undo...
}
}
//执行者,用来执行命令
public class Executer{
//命令队列
ArrayList<Command>commandList = new ArrayList<Command>();
//记录当前已经执行的命令
int executed = 0;
//执行命令
public void execute(){
if(commandList.size()==0)
System.out.println("Please add a command");
else{
for(int i=executed; i<commandList.size(); i++){
commandList.get(i).execute();
}
executed = commandList.size();
}
}
//添加命令
public void addCommand(Command mCommand){
commandList.add(mCommand);
}
//执行撤销命令,回滚到执行前
public void undo(){
if(executed==0)
System.out.println("Do Nothing");
else{
for(int i=executed; i>=0; i--){
commandList.get(i).undo();
}
}
}
}
通过上面的代码,我们可能发现这有些像是之前的策略模式,对不同的行为单独进行封装,然后通过add方法将依赖实例注入,然后通过一个list持有依赖集群,然后再通过对依赖队列的遍历来执行方法,策略模式可能唯一不同的是在在内部通过委托的方式来执行方法,再就是策略模式中每个委托对象所要被调用的方法不同,而且每个注入的实例也将会被用到不同的方法之中,而命令模式则是将其置于一个方法之中。
命令模式应用实例
数据库中的事务,可以通过这种方式来实现回滚,日常安排,线程池,工作队列等,通过着我们可以很好的实现被操作对象和操作者之间的解耦,同时还可以实现撤销操作。
Android中的Thread通过构造函数接纳实现了Runnable接口的类,这个运用的就是命令模式,当然我们平常更多会是通过匿名内部类的形式来将依赖实例注入。
下篇更代理模式,侧重下其和委托形式的区别和实际应用。