在很多設計中,請求者不希望或者無法直接和被請求者打交道,那麼請求者可以將命令封裝成一個對象,請求者要發命令的時候,調用該對象中的方法,在這個方法裏呢,又會調用真正的被請求者的一個方法,這樣請求者的命令就順利傳達到被請求者一方了。
命令模式的類圖:
從類圖中看,簡單來說就是請求者將Command接口的聲明放在 自己的對象中,ConcreteCommand又實現了接口,再把接收者的對象聲明放在自己對象中,這樣請求者執行命令時,ConcreteCommand實際上通過接收者的對象執行了接收者類中的方法,這樣完成了命令的執行。
Q&A:
圖中爲什麼要用接口呢?
正是體現了面向抽象的原則吧,另外,如果增加若干個方法直接在接口中加入,實現該接口的類中就不會忘記添加了。
Command模式有如下效果:
a)將調用操作的對象和知道如何實現該操作的對象解耦。
b)Command是頭等對象。他們可以像其他對象一樣被操作和擴展。
c)你可將多個命令裝配成一個複合命令。
d)增加新的Command很容易,因爲這無需改變現有的類。
下面是java程序的實現,更清楚的說明一下
package dai;
public interface Command {
public void execute();
}
package dai;
public class Receive {
/**
* 執行偷襲命令
*/
public void doAttack() {
System.out.println("執行偷襲命令");
}
}
package dai;
public class ConcreateCommand implements Command{
Receive receive;
public ConcreateCommand(Receive receive) {
super();
this.receive = receive;
}
@Override
public void execute() {
// TODO Auto-generated method stub
this.receive.doAttack();
}
}
package dai;
public class Invoker {
Command command;
public void setCommand(Command command){
this.command = command;
}
public void startExecuteCommand(){
this.command.execute();
}
}
最後是測試的客戶端:
package dai;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Receive receive = new Receive();
Command command = new ConcreateCommand(receive);
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.startExecuteCommand();
}
}