昨天看了下命令模式,有了点心得。
先看一个典故:《后汉书·吕布传》:“诸将谓布曰:‘将军常欲杀刘备,今可假手于术。’”。
命令模式把一个请求或者操作封装到一个对象中。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。命令模式允许请求的一方和发送的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否执行,何时被执行以及是怎么被执行的。系统支持命令的撤消。
说白了,这种模式叫“假手于人”,借别人的手,来完成自己要做的事。
本来自己可以直接做这件事,硬是在中间插上个第三者,由第三者来统一管理这些事情,好比公司总经理本来可以直接叫单位低层下属做事情的,但是现在就在二者之间插入部门经理,总经理要办事情,只要叫部门经理去就可以了,总经理只要知道是哪个人做什么事就可以了,没必要知道事情是什么时候、怎么做的。
命令模式可以降低系统的耦合度,增强功能模块的复用性,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
上面的话用公司的例子来说,就是如果有副总经理要叫低层下属做事,也可以直接找部门总管,这就是复用性,要增加部门的话,直接增加就可以,不会影响到别的部门的办公。
下面我写个例子说明一下:
//下属
class Underling {
public void action(String actionName)
{
System.out.println("I'm "+actionName+" now.");
}
}
//抽象命令类
abstract class Command {
protected Underling underling;
protected String commandName;
public Command(Underling underling)
{
this.underling=underling;
}
abstract public void execute();
}
//命令--打印文件
class PrintDocument extends Command {
public PrintDocument(Underling underling) {
super(underling);
commandName="PrintDocument";
}
public void execute() {
underling.action(commandName);
}
}
//命令--取文件
class FetchDocument extends Command {
public FetchDocument(Underling underling) {
super(underling);
commandName="FetchDocument";
}
public void execute() {
underling.action(commandName);
}
}
//部门经理
public class DepartmentlManage {
private Command command;
public DepartmentlManage(Command command)
{
this.command=command;
}
public void execCommand()
{
command.execute();
}
}
//总经理
public class GeneralManager {
public static void main(String[] args) {
Underling underling=new Underling();
Command printDocument=new PrintDocument(underling);
DepartmentlManage dm=new DepartmentlManage(printDocument);
dm.execCommand();
System.out.println("------------------");
Command fetchDocument=new FetchDocument(underling);
DepartmentlManage dm2=new DepartmentlManage(fetchDocument);
dm2.execCommand();
}
}
运行结果如下:
I'm PrintDocument now.
------------------
I'm FetchDocument now.
在上面例子中,总经理说叫下属underling去打印文件(PrintDocument),部门经理dm接到命令,执行,最后下属打印了文件。dm创建后,可以在任何时间执行命令。
最后说说用command模式实现undo/redo功能。
要实现undo功能,每个具体命令中要包含撤消命令的实现,命令管理类(相当于部门经理)中要能储存所有已经执行了的命令。要记住undo/redo到哪个地方的话,既可以用2个List,分别储存已经执行了2种不同操作的命令,也可以用一个指示变量,记住最后那个命令(就是指针嘛~~),二种方法要怎么用就看自己了。
就到这里了。