一、概述
命令模式可以將請求發送者和接收者完全解耦,發送者與接收者之間沒有直接引用關係,發送請求的對象只需要知道如何發送請求,而不必知道如何完成請求。核心在於引入了命令類,通過命令類來降低發送者和接收者的耦合度,請求發送者只需指定一個命令對象,再通過命令對象來調用請求接收者的處理方法,命令模式是一種對象行爲型模式。
二、使用場景
1>、系統要求請求發送者和接收者的解耦,使得調用者和接收者不直接交互;
2>、類似消息 請求/命令 隊列處理;[命令裝載在集合或隊列中,通過遍歷集合,達到命令的批量處理]
3>、當執行一個命令而觸發多個具體命令的執行,從而實行對命令的批量處理,這種命令被稱爲組合命令或宏命令;
三、UML類圖
四、參與者
1>、Command(抽象命令類):抽象命令類一般是一個抽象類或接口,在其中聲明瞭用於執行請求的execute()等方法,通過這些方法可以調用請求接收者的相關操作。
2>、ConcreteCommand(具體命令類):具體命令類是抽象命令類的子類,實現了在抽象命令類中聲明的方法,它對應具體的命令接收者對象,將接收者對象的動作綁定其中。在實現execute()方法時,將調用接收者對象的相關操作(operation)。
3>、Invoker(命令發起者/消息請求者):與抽象命令類存在關聯關係,在命令發起時 將一個具體命令對象注入其中 再調用具體命令對象的執行方法(execute) 從而間接實現調用請求接收者的相關操作。
4>、Receiver(命令/消息 接收者):接收者執行與請求相關的操作,它具體實現對請求的業務處理(operation方法執行)。
五、用例學習
1、命令接收者A:ReceiverA.java
/**
* 命令接收者A
* @author [email protected]
*
*/
public class ReceiverA {
public void operation(){
System.out.println("我是命令接收者A,我已接收到命令,正在執行相應的業務操作方法");
}
}
2、命令接收者B:ReceiverB.java
/**
* 命令接收者B
* @author [email protected]
*
*/
public class ReceiverB {
public void operation(){
System.out.println("我是命令接收者B,我已接收到命令,正在執行相應的業務操作方法");
}
}
3、抽象命令類:Command.java
/**
* 命令抽象類
* @author [email protected]
*
*/
public abstract class Command {
public abstract void execute();
}
4、具體命令類A:ConcreteCommandA.java
/**
* 具體命令類A<br/>
* 與命令接收者ReceiverA 關聯
* @author [email protected]
*
*/
public class ConcreteCommandA extends Command {
private ReceiverA receiver;
public ConcreteCommandA(){
receiver = new ReceiverA();
}
@Override
public void execute() {
// 調用具體命令接收者的執行方法
receiver.operation();
}
}
5、具體命令類B:ConcreteCommandB.java
/**
* 具體命令類B<br/>
* 與命令接收者ReceiverB 關聯
* @author [email protected]
*
*/
public class ConcreteCommandB extends Command {
private ReceiverB receiver;
public ConcreteCommandB(){
receiver = new ReceiverB();
}
@Override
public void execute() {
// 調用具體命令接收者的執行方法
receiver.operation();
}
}
6、命令發送者/消息請求者:Invoker.java
/**
* 命令/消息發送者
* @author [email protected]
*
*/
public class Invoker {
// 維護一個抽象命令類的引用
private Command command;
/**
* 對具體命令對象的引用
* @param command
*/
public void setCommand(Command command){
this.command = command;
}
/**
* 發送命令<br/>
* 調用具體命令執行類,間接的將消息/命令傳遞給了命令接收者執行
*/
public void runCommand(){
command.execute();
}
}
7、客戶端測試類:Client.java
public class Client {
public static void main(String[] args) {
Command command = null;
/*
* 如果要使命令發送給 命令接收者B(ReceiverB)處理
* 則只要實例化與ReceiverB 相關的命令類ConcreteCommandB即可
* 代碼修改如下:
* command = new ConcreteCommandB();
*
* 以下是實例化命令類ConcreteCommandA 及將命令消息發送給與之關聯的ReceiverA處理
*/
command = new ConcreteCommandA();
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.runCommand();
}
}
六、其他