大話設計模式筆記(二十)の命令模式

舉個栗子

路邊攤吃燒烤,老闆只有一人,又要記住點單,又要忙着收費,客戶作什麼都要排隊。。。ide

反例思路1

若是客戶多了,請求多,就容易混亂,他叫五串羊肉串,你叫三個烤雞翅,老闆哪裏忙得過來。代碼中的體現就是一句一句輸出,因此應該要有個服務員。。。優化

門面改造

Talk is cheap, show me the code

(屁話少說,放碼過來)

/**
 * 抽象命令
 * Created by callmeDevil on 2019/12/14.
 */
public abstract class Command {

    protected Barbecuer receiver;

    public Command(Barbecuer receiver){
        this.receiver = receiver;
    }

    // 執行命令
    public abstract void excuteCommand();

}
/**
 * 烤羊肉串命令
 * Created by callmeDevil on 2019/12/14.
 */
public class BakeMuttonCommand extends Command{

    public BakeMuttonCommand(Barbecuer receiver){
        super(receiver);
    }

    @Override
    public void excuteCommand() {
        receiver.bakeMutton();
    }

}
/**
 * 烤雞翅命令
 * Created by callmeDevil on 2019/12/14.
 */
public class BakeChickenWingCommand extends Command{

    public BakeChickenWingCommand(Barbecuer receiver){
        super(receiver);
    }

    @Override
    public void excuteCommand() {
        receiver.bakeChickenWing();
    }

}
/**
 * 烤肉串者
 * Created by callmeDevil on 2019/12/14.
 */
public class Barbecuer {

    public void bakeMutton(){
        System.out.println("烤羊肉串!");
    }

    public void bakeChickenWing(){
        System.out.println("烤雞翅!");
    }

}
/**
 * 服務員
 * Created by callmeDevil on 2019/12/14.
 */
public class Waiter {

    private Command command;

    // 無論什麼用戶想要什麼烤肉,反正都是命令,只管記錄訂單,而後通知烤肉串者便可
    public void setOrder(Command command){
        this.command = command;
    }

    public void notifying(){
        command.excuteCommand();
    }

}
public class Test {
    public static void main(String[] args) {
        // 開店前的準備
        Barbecuer boy = new Barbecuer();
        Command bakeMuttonCommand1 = new BakeMuttonCommand(boy);
        Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
        BakeChickenWingCommand bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
        Waiter girl = new Waiter();

        // 開門營業
        girl.setOrder(bakeMuttonCommand1);
        girl.notifying();
        girl.setOrder(bakeMuttonCommand2);
        girl.notifying();
        girl.setOrder(bakeChickenWingCommand1);
        girl.notifying();
    }
}

運行結果this

烤羊肉串!
烤羊肉串!
烤雞翅!

其實服務員那裏能夠完善,好比點單的時候不是一個一個點,而是點完以後一塊兒給單;並且還沒有烤肉時,訂單也能夠進行更改或取消,烤肉的人也是不少肉一塊兒烤,等等,此處就不優化了。設計

命令模式

定義

將一個請求封裝爲一個對象,從而使你可用不一樣的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操做。日誌

UML圖

總結

  • 它能較容易的設計一個命令隊列
  • 在須要的狀況下,能夠較容易的將命令記入日誌
  • 容許接收請求的一方決定是否要取消請求
  • 能夠容易的實現對請求的撤銷和重作
  • 因爲加進新的具體命令類不影響其餘的類,所以增長新的具體命令類很容易
  • 最關鍵的就是命令模式把請求一個操做的對象與知道怎麼執行一個操做的對象分割開(服務員和烤肉串者)。

是否碰到如撤銷/恢復功能等相似的狀況就必定要實現命令模式?

敏捷開發原則告訴咱們,不要爲代碼添加基於猜想的、實際不須要的功能。若是不清楚一個系統是否須要命令模式,通常就不要着急去實現它,事實上,在須要的時候經過重構實現這個模式並不困難,只要在真正須要如撤銷/恢復操做等功能時,把原來的代碼重構爲命令模式纔有意義。code

相關文章
相關標籤/搜索