1. 程式人生 > >Java設計模式——命令模式

Java設計模式——命令模式

概述

命令模式是把“請求動作或操作”封裝成一個“命令物件”,“呼叫者” 通過該 “命令物件” 把 “命令” 傳送到 “接收者” 執行 “操作”。(看不懂沒關係,我的文字表達水平比較一般,看例子很容易明白了)

例子

舉一個來自《Head First設計模式》的例子:“在餐廳點餐”

場景:顧客到餐廳點餐,寫選單給服務員,服務員把選單給廚師,廚師按照選單要求做菜。

人物:顧客(發起者)、服務員(呼叫者)、廚師(接收者)。

分析:在大家日常點餐可以知道,顧客與廚師是被隔離的,顧客只管點餐不需要知道菜是如何炒的細節,廚師只管做菜執行命令,互不影響。這跟“命令模式”的目的很一致,把命令的“發起者”和“接收/執行者”獨立起來,實現解耦。

再舉一個更貼近生活的例子:

客戶(發起人):balabala提要求(命令)

需求哥(排程者):哦哦哦哦哦地記下一條又一條的需求(命令)

然後,需求哥把一條條的需求發給你(程式碼搬運工)

你(接收/執行者):這需求不可能實現,沒法做~~~

需求哥:這是客戶要求,可以不做,不過鍋你背,工資你扣

客戶提出要求後不需要理會內部如何實現,而你~~~~

凌晨2點,客戶在床上papapa,你在鍵盤上papapa

類圖

這裡寫圖片描述

程式碼

//命令介面
public interface Command {
    public void setReceiver(Receiver receiver);
    public
void execute(); }
//實現介面的具體命令
public class UiCommand implements Command {
    private Receiver receiver;

    @Override
    public void setReceiver(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.talk();
        receiver.execute();
    }
}
//接收者(碼農)
public class Receiver {

    public void talk() {
        System.out.println("討論需求...");
    }

    public void execute() {
        System.out.println("開始幹活....");
        this.thinking();
        this.doing();
        this.extraWork();
        this.end();
    }

    private void thinking() {
        System.out.println("思考解決方案.....");
    }

    private void doing() {
        System.out.println("開始寫程式碼......");
    }

    private void extraWork() {
        System.out.println("加班寫程式碼.........");
    }

    private void end() {
        System.out.println("");
        System.out.println("享年28....");
    }
}
//呼叫者(需求人員)
public class RequireInvoker {
    private Command command;

    public void setCommand(Command command){
        this.command = command;
    }

    public void execute() {
        command.execute();
    }
}
//客戶爸爸
public class Customer {
    public static void main(String[] args) {
        //內部明確好分工,哪個程式設計師負責UI,哪個負責資料優化
        //先建立個接收者物件
        Receiver receiver = new Receiver();
        //再建立個命令物件
        Command command = new UiCommand();
        //指定命令的接收者
        command.setReceiver(receiver);
        //建立個呼叫者物件
        RequireInvoker invoker = new RequireInvoker();

        //客戶把要求給需求人員
        invoker.setCommand(command);
        //開始幹活吧
        invoker.execute();
    }
}

輸出結果:

這裡寫圖片描述

命令模式特點:

1.和所有設計模式特點差不多,解耦。“命令者”與“接收者”隔離。新增命令不用改原始碼。

2.把“具體行為或操作”封裝成一個具體的物件,比如說客戶口述的需求也是命令。

3.這個設計模式可以輕易設計成,巨集命令(能批量執行命令的命令),Head First上面有講,其實很容易理解,口述一下吧,建立一個巨集命令(同樣實現Command介面),然後把其他命令add()進去,在它的execute()裡面遍歷並執行所有的命令。

4.可以記錄所有執行過的命令。在Invoker類里加上個ArrayList,每執行一次命令就add()一下或者可以直接寫入到硬盤裡,系統掛掉了也能按記錄重新執行。

第3、4點可以用於訊息佇列、日誌系統