昨天看了下命令模式,有了點心得。
先看一個典故:《後漢書·呂布傳》:“諸將謂布曰:‘將軍常欲殺劉備,今可假手於術。’”。
命令模式把一個請求或者操作封裝到一個對象中。命令模式把發出命令的責任和執行命令的責任分割開,委派給不同的對象。命令模式允許請求的一方和發送的一方獨立開來,使得請求的一方不必知道接收請求的一方的介面,更不必知道請求是怎麼被接收,以及操作是否執行,何時被執行以及是怎麼被執行的。系統支援命令的撤消。
說白了,這種模式叫“假手於人”,借別人的手,來完成自己要做的事。
本來自己可以直接做這件事,硬是在中間插上個第三者,由第三者來統一管理這些事情,好比公司總經理本來可以直接叫單位低層下屬做事情的,但是現在就在二者之間插入部門經理,總經理要辦事情,只要叫部門經理去就可以了,總經理只要知道是哪個人做什麼事就可以了,沒必要知道事情是什麼時候、怎麼做的。
命令模式可以降低系統的耦合度,增強功能模組的複用性,由於加進新的具體命令類不影響其他的類,因此增加新的具體命令類很容易。
上面的話用公司的例子來說,就是如果有副總經理要叫低層下屬做事,也可以直接找部門總管,這就是複用性,要增加部門的話,直接增加就可以,不會影響到別的部門的辦公。
下面我寫個例子說明一下:
//下屬
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種不同操作的命令,也可以用一個指示變數,記住最後那個命令(就是指標嘛~~),二種方法要怎麼用就看自己了。
就到這裡了。