命令模式将“请求”封装成对象以便使用不同的请求、队列或者日志来参数化其它对象。将不同命令接口的匿名实现类作为参数传入某个方法,这个只需要方法只需要调用该对象参数的某个方法即可,并不需要关心这个被调用方法的真正实现,所以这是避免某个对象的具体实现会发生变化造成需要修改该对象所对应的类。命令模式相当于将命令从类当中分离出来。
1.适用性与优缺点
1.适用性:
a.抽象出待执行的动作以参数化某对象
b.在不同的时刻指定排列和执行请求
c.支持撤销操作
d.支持修改日志
2.优点:
a.降低系统耦合度:将命令者和接收者通过具体命令类解耦。
b.利用命令接口,便于操作和扩展
c.组合命令,可以将多个命令装配成一个组合命令。
3.缺点:
导致系统有过多的具体命令类。
2.示例讲解
本文通过讲述一个对数组进行操作的示例来加深印象。众所周知,对于一个数组的具体操作有很多个。如果客户端每次对数组进行一次操作都需要改写一个命令,则会十分繁琐。因此,命令模式选择将具体操作从中分离出来,通过一个命令类来控制数组与具体操作,如果需要不同操作,只需要对命令类进行修改即可。
1.首先定义一个命令管理类,具体操作未知,action类负责管理对象和具体命令之间的调用,参数是target数组,和Command对象,从action函数中可以看出,Command类对象cmd调用了自己的操作函数并将target数组作为参数。这里采用了将具体操作与被操作对象的分离,并且是用命令对象去对tagert数组具体操作什么。这种命令作为主体的特点就是命令模式的特点。
package command.manager;
import command.command.Command;
public class CommandManager {
public void action(int[] target,Command cmd)
{
cmd.process(target);
}
}
2.建立一个Command接口,里面有个process方法,是用于实现对数组的具体操作。
package command.command;
public interface Command
{
// 接口里定义的process()方法用于封装“处理行为”
void process(int[] target);
}
3.接下来实现两个具体操作类,分别对数组元素进行累加和累乘的操作
package command.command.impl;
import command.command.Command;
public class SumCommand implements Command {
@Override
public void process(int[] target) {
// TODO Auto-generated method stub
int ans=0;
for(int tmp:target)
{
ans+=tmp;
}
System.out.println(ans);
}
}
package command.command.impl;
import command.command.Command;
public class MultiCommand implements Command {
@Override
public void process(int[] target) {
// TODO Auto-generated method stub
int ans=1;
for(int tmp:target)
{
ans*=tmp;
}
System.out.println(ans);
}
}
4.然后是对示例进行测试:package command.test;
import command.manager.*;
import command.command.*;
import command.command.impl.*;
public class CommandTest
{
public static void main(String[] args)
{
CommandManager cm = new CommandManager();
int[] target = {3, -4, 6, 4};
Command cmd=new SumCommand();
Command cmd2=new MultiCommand();
// 第一次处理数组,具体处理行为取决于Command对象
cm.action(target , cmd);
cm.action(target, cmd2);
}
}
运行程序,结果如下:9
-288
由上面可知,命令模式中,将具体操作类分离出来,作为主体,主动地对待操作对象进行操作,从而实现对对象的具体操作。上面例子的对象指的是数组,当然这里的对象还可以指类实例化的对象。所以,命令模式是将对象与对对象的具体操作分离的一种模式。