1. 程式人生 > >走進設計模式的世界6:老婆讓你乾的事趕緊的-命令模式

走進設計模式的世界6:老婆讓你乾的事趕緊的-命令模式

命令模式:

將請求封裝成物件,這可以讓你使用不同的請求、佇列,或者日誌請求來引數化其他物件。命令模式也可以支援撤銷操作。

解釋:隨著科技的發展,變化的速度和擴充套件的速度也逐漸增強。單一的耦合的設計往往不符合時代的趨勢。就拿智慧家電的例子來說一個遙控器的幾個按鈕分別控制著不同的家用電器。如果沒有一個好的設計模式的話,程式碼的可複用性就非常差。類的種類繁多,每個家電的開關的邏輯又不一樣。如果我們不引用命令模式無論是擴充套件還是二次開發都會產生很大的工作量。所謂命令模式,就是讓發起者和執行者之間解耦,發起者不用關心執行者是如何執行的只是讓他執行就可以了。

命令模式樣例演示:老婆讓你乾的事你趕緊的。

/**
    萬惡的雙11就要來了
    老婆的購物車東西多的讓你頭皮發麻
    遙想當年的app,只有一個淘寶讓你老婆購買
    真的美好
**/

// 老婆控制器
public WifeControl{
    // 淘寶的購買類
    private BuyTaoBao buyTaoBao;
    // 構造器
    public WifeControl(BuyTaoBao buyTaoBao){
        this.buyTaoBao = buyTaoBao;
    }

    // 雙11的資訊
    public doubleEleven(){
        // 選擇商品
        buyTaoBao.choose();
        // 下訂單
        buyTaoBao.order();
        // 用支付寶支付
        buyTaoBao.payByZhiFuBao();
    }
}

// 淘寶購買的類
public class BuyTaoBao{
    
    // 選擇商品
    public void choose(){
        ...
    }
    // 下訂單
    public void order(){
        ...
    }
    // 用支付寶支付
    public void payByZhiFuBao{
        ...
    }
}

// 測試類
public class Test{
    public static void mian(String[]args){
        // 獲取淘寶的實體類
        BuyTaoBao taobao = new BuyTaoBao();
        // 獲取wife控制器
        WifeControl wife = new WifeControl(taobao);
        // 清空淘寶購物車
        wife.doubleEleven();
    }
}

上面的例子詮釋瞭如果只清空淘寶購物車的功能,現在的購物app越來越多。唯品會。。京東。。淘寶。。

如果媳婦都讓你清空呢?你總不能給WifeControl 加各種引數吧。

那麼就引入瞭如下設計模式 命令模式

/**
    先看一個簡化版的吧。
    讓我們一個個去清空媳婦的購物車。    
**/

/**
    首先建立一個介面
    讓所有的購物app的流程都實現統一的介面
**/

public interface DoubleElevenBuy{
    // 規定統一的方法雙11
    public void doubleEleven();
}

/**
    然後讓所有的購物app類都去實現這個介面
**/
// 淘寶
public class TaoBaoApp implements DoubleElevenBuy{
    // 雙11購買的方法
    public void doubleEleven(){
        // 選擇商品
        this.choose();
        // 下訂單
        this.order();
        // 用支付寶支付
        this.payByZhiFuBao();
    }
}

// 京東
public class JingDongApp implements DoubleElevenBuy{
    // 雙11購買的方法
    public void doubleEleven(){
        // 選擇商品
        this.choose();
        // 下訂單
        this.order();
        // 用微信支付
        this.payByWeiXin();
    }
}

// 唯品會
public class WeiPinHuiApp implements DoubleElevenBuy{
     // 雙11購買的方法
    public void doubleEleven(){
        // 選擇商品
        this.choose();
        // 下訂單
        this.order();
        // 確認海外直購資訊(怎麼感覺我在給唯品會做廣告)
        this.buyOrNot();
        // 用銀行卡支付
        this.payByBank();
    }
}

/**
    下面就是老婆控制器的程式碼了
    注意觀察於上一代程式碼有何不同
**/
public class WifeControl{
    // 命令物件
    private DoubleElevenBuy doubleElevenBuy;
    // 構造方法
    public WifeControl(DoubleElevenBuy doubleElevenBuy){
           this.doubleElevenBuy = doubleElevenBuy;
    }
    private doubleEleven(){
        // 清空購物車
        doubleElevenBuy.doubleEleven();
    }
}

public class Test{
    public static void main(String[]args){
        // 淘寶
        DoubleElevenBuy  taobao = new TaoBaoApp();
        // 京東
        DoubleElevenBuy  jingdong = new JingDongApp();
        // 唯品會
        DoubleElevenBuy  weipinhui = new WeiPinHui();
        // 先命令我清空淘寶
        WifeControl wife = new WifeControl(taobao);
        // 我照做了
        wife.doubleEleven();
        // 京東
        wife = new WifeControl(jingdong);
        // 我照做了
        wife.doubleEleven();
        // 唯品會
        wife = new WifeControl(weipinhui);
        // 我照做了
        wife.doubleEleven();
    }
}

以上設計讓老婆控制器不在關心我是如何從各個app給她清空購物車的了,完成了命令者與被命令者的解耦,只要知道每個app都有個清空購物車的功能就可以了。既然每個app都有清空購物車功能當然也有退費功能了。。所以自己想怎麼擴充套件。

如果老婆想只跟我說一次就把所有她手機裡的購物app清空購物車呢???我們做如下修改。

/**

    懶得不行了的老婆控制類
**/
public class WifeControl{
    DoubleElevenBuy[] doubleElevenBuys;
    public WifeControl(DoubleElevenBuy[] doubleElevenBuys){
        this.doubleElevenBuys = doubleElevenBuys;
    }
    
    public void doubleElevenBuy(){
        for(DoubleElevenBuy doubleElevenBuy:doubleElevenBuys){
            doubleElevenBuy.doubleElevenBuy();
        }
    }
}

public class Test{
    public static void main(String[]args){
         DoubleElevenBuy[] doubleElevenBuys = new   DoubleElevenBuy[4];
         doubleElevenBuys.add(new TaoBaoApp());
         doubleElevenBuys.add(new JingDongApp());
         doubleElevenBuys.add(new WeiPinHuiApp());
         doubleElevenBuys.doubleElevenBuy();
    }
}

總結:設計的時候要考慮減少耦合,儘量做到鬆耦合不要有太多的OO型別設計。