《Design Patterns》Command.積跬步系列

Command:命令模式

先代碼

package h.l.demo.command;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 用來聲明執行操作的接口
 */
abstract class Command {
	protected CommandReceiver commandReceiver;
	protected String commandContent;

	// 設置命令執行者
	public Command(CommandReceiver commandReceiver) {
		this.commandReceiver = commandReceiver;
	}

	// 設置命令內容
	public void setCommandContent(String commandContent) {
		this.commandContent = commandContent;
	}

	// 獲取命令內容
	public String getCommandContent() {
		return this.commandContent;
	}

	abstract public void Execute();
}

/**
 * 具體命令類
 */
class ConcreteCommand extends Command {

	public ConcreteCommand(CommandReceiver commandReceiver) {
		super(commandReceiver);
	}

	@Override
	public void Execute() {
		commandReceiver.Action();
	}
}

/**
 * 具體命令類2
 */
class ConcreteCommand2 extends Command {

	public ConcreteCommand2(CommandReceiver commandReceiver) {
		super(commandReceiver);
	}

	@Override
	public void Execute() {
		commandReceiver.Action2();
	}
}

/**
 * Invoker類,要求該命令執行這個請求,相當於命令發起人和命令接收人中間傳遞消息的那個人,承前啓後,前接收命令,後下發命令道執行者那。
 */
class Invoker {
	private List<Command> commands = new ArrayList<>();

	public void addCommand(Command command) {
		System.out.println("【添加命令】:" + "\t" + command.getCommandContent()
				+ "\t" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
		commands.add(command);
	}

	public void execute() {
		System.out.println("【執行命令】:");
		for (Command command : commands) {
			command.Execute();
		}
	}
}

/**
 * 命令接收者:裏面有一系列執行的動作
 */
class CommandReceiver {
	public void Action() {
		System.out.println("【執行命令】" + "\t" + "買好可樂,給你");
	}

	public void Action2() {
		System.out.println("【執行命令】" + "\t" + "買好薯片,給你");
	}
}

測試類:

package h.l.demo.command;

/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年2月14日
 * @Description: 測試
 */
public class TestMainEnter {

	public static void main(String[] args) {
		// 命令執行人
        CommandReceiver commandReceiver = new CommandReceiver();
        // 命令
        Command command = new ConcreteCommand(commandReceiver);
        command.setCommandContent("幫我買一個可樂,謝謝");
        // 命令2
        Command command2 = new ConcreteCommand2(commandReceiver);
        command2.setCommandContent("幫我買一包薯片,謝謝");
        // 命令中間人
        Invoker invoker = new Invoker();
        invoker.addCommand(command);
        invoker.addCommand(command2);
        // 執行命令
        invoker.execute();
	}

}

測試結果:
在這裏插入圖片描述

後分析

  • 個人建議:寫代碼是件幸福的事,So,do it

命令模式,定義:將一個請求封裝爲一個對象,從而使你可用不同的請求對客戶進行參數化,對請求排隊或記錄請求日誌,以及支持可撤銷的操作。命令模式的邏輯,就是將客戶的請求封裝爲對象,這個對象我們在這裏稱之爲命令,這些命令的屬性中對應綁定了一個命令的執行者類。整個操作通過中間人也就是Invoker類進行操作,客戶在Invoker這裏下發請求,Invoker可以對請求進行過濾等操作,將結果通過命令實例中自帶的命令執行者進行命令的操作。這就是命令模式的一個邏輯。
命令模式的作用:第一,它能較容易的設計一個命令隊列;第二,在需要的情況下可以較容易地將命令計入日誌;第三,允許接收請求的一方決定是否接收請求(上述代碼的Invoker類就是做這樣的事);第四,可以容易地實現對請求的撤銷和重做(Invoker類);第五,由於加進新的具體命令不影響其他的類,因此增加新的具體命令類很容易。最關鍵的優點就是命令模式把請求一個操作的對象與知道怎麼執行一個操作的對象分隔開。

其他例子:參考自《大話設計模式》烤肉串引來的思考。客戶通過服務員點餐,服務員下單到烤肉師傅。這一個過程可以使用命令模式展示。


注:以上文章僅是個人總結,若有不當之處,望不吝賜教

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章