命令模式是一種高內聚的模式,使用頻率其實也不算過高,本質是對命令進行封裝,將發出命令的責任和執行命令的責任分離開。markdown
命令模式將一個或一組命令封裝爲一個對象,從而可以將函數方法做爲參數進行傳輸,同時還可以解耦客戶端和服務端的直接耦合,適用場景有:作簡單的請求排隊,記錄請求日誌,以及支持可撤銷的操做。編輯器
將一個請求封裝成一個對象,從而讓你使用不一樣的請求把客戶端參數化,對請求排隊或者記錄請求日誌,能夠提供命令的撤銷和恢復功能。ide
//1.抽象命令類
public interface Command {
void excute();
}
//2.1 具體命令類
public class Command1 implements Command {
private final Receiver receiver;
public Command1(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void excute() {
receiver.operationA();
}
}
//2.2 具體命令類
public class Command2 implements Command {
private final Receiver receiver;
public Command2(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void excute() {
receiver.operationB();
}
}
//2.3 具體命令類
public class Command3 implements Command {
private final Receiver receiver;
public Command3(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void excute() {
receiver.operationC();
}
}
//3 抽象接收者
public interface Receiver {
void operationA();
void operationB();
void operationC();
}
//4 具體接收者
public class Receiver1 implements Receiver {
@Override
public void operationA() {
System.out.println("操做 A");
}
@Override
public void operationB() {
System.out.println("操做 B");
}
@Override
public void operationC() {
System.out.println("操做 C");
}
}
//5 調用者
public class Invoker {
private final List<Command> commands;
public Invoker() {
commands = new ArrayList<>();
}
public void setCommand(Command command) {
commands.add(command);
}
public void run() {
commands.forEach(Command::execute);
}
}
//6. 場景類
public class Demo {
public static void main(String[] args) {
Receiver receiver1 = new Receiver1();
Invoker invoker = new Invoker();
invoker.setCommand(new Command1(receiver1));
invoker.setCommand(new Command2(receiver1));
invoker.setCommand(new Command3(receiver1));
invoker.run();
}
}
//輸出結果
操做 A
操做 B
操做 C
複製代碼
類間解耦,調用者角色和接收者角色沒有依賴關係,調用者只能調用Command
的execute
函數
可擴展性,Command
的子類能夠很是容易地擴展this
命令模式能夠結合責任鏈模式,實現命令族解析任務,結合模板方法,還能夠減小Command
子類膨脹問題spa
若是有N
個命令,Command
的子類就有N
個,類膨脹問題嚴重日誌
不一樣的接收者可能須要實現重複的命令,例如Markdown
須要實現打開、關閉、保存的命令,而非Markdown
編輯器也須要實現打開、關閉、保存的命令code