公號:碼農充電站pro
主頁:https://codeshellme.github.iohtml
本篇來介紹命令模式(Command Design Pattern),它將「請求」封裝成對象,從而將「請求」的建立者與「請求」的執行者解耦。java
相信你們都在網上買過東西,咱們以淘寶爲例來介紹命令模式。git
咱們假設這樣一個簡單的場景:github
在這個過程當中,淘寶網並不關心每家商店的具體狀況,它只知道每家商店都能完成它所派發的訂單。算法
那麼,咱們怎樣爲這個場景建模呢?shell
從上面購物流程中,咱們能看出來,鏈接顧客,淘寶網與商店的中間橋樑是訂單:架構
首先,咱們須要定義一個 Order
接口:測試
interface Order { void execute(); }
Order
接口中只有一個 execute
方法,須要派生類來實現。this
而後定義一個華爲商店:線程
abstract class Shops { protected String shopName; protected abstract String sell(); } class HuaWeiShop extends Shops { public HuaWeiShop() { this.shopName = "HUAWEI"; } public String sell() { return "HuaWei Phone"; } }
上面代碼中,Shops
是一個抽象類,表示商店,商店能夠銷售商品。HuaWeiShop
類繼承了 Shops
接口,實現了 sell
方法。
而後定義一個 GoodsOrder
類,它繼承了 Order
接口,並實現了 execute
方法:
class GoodsOrder implements Order { private Shops shop; public GoodsOrder(Shops shop) { this.shop = shop; } public void execute() { String goods = shop.sell(); System.out.println(goods); } }
而後定義 Client
類,用於生成訂單:
class Client { public Order createOrder() { Shops phone = new HuaWeiShop(); Order phoneOrder = new GoodsOrder(phone); return phoneOrder; } }
下面定義淘寶網,它能夠接收訂單和處理訂單:
class Taobao { private Order order; public void receiveOrder(Order order) { this.order = order; } // 處理訂單 public void handleOrder() { order.execute(); } }
最後來測試代碼:
Client c = new Client(); Order order = c.createOrder(); // 顧客生成訂單 Taobao t = new Taobao(); t.receiveOrder(order); // 淘寶接收訂單 t.handleOrder(); // 淘寶處理訂單
輸出以下:
HuaWei Phone
輸出表示顧客成功買到了手機。
咱們畫出上面代碼的類圖,以下:
我將完整的命令模式代碼放在了這裏,供你們參考。
實際上,上面代碼的實現方式就是命令模式。
命令模式將請求(命令)封裝爲一個對象,這樣能夠將不一樣請求注入到其餘對象,而且可以支持請求(命令)的排隊執行、記錄日誌、撤銷等功能。
命令模式中包含如下幾個組件(並把組件類比到上面的購物場景中):
命令模式的類圖以下(與上面購物代碼的類圖一致):
上圖的 Command 接口中有一個 undo
方法,它是 execute
方法的反操做,用於實現撤銷功能。
命令模式經過將請求封裝成對象,將請求的建立者,請求的調用者和請求的執行者,這三者之間完全解耦:
請求服務是一種由客戶端發出請求,而後由服務端去處理的一種程序架構,不一樣的客戶端之間互不干擾。
咱們上面模擬的購物程序能夠說使用的就是這種架構,以下:
好比 Redis Server 處理 Client 命令的方式使用的就是這種架構。
請求被封裝成對象後,可將其放在請求隊列中,而後由工做線程將其取出,再執行。
這種架構也至關於一個生產者-消費者架構。
請求被封裝成對象後,也能夠將其記錄在日誌中。若是服務意外崩潰,服務重啓後就可使用請求日誌,將服務恢復到崩潰以前的狀態。
好比 Redis 的 AOF 持久化使用的就是這種方式。
命令模式將請求封裝成對象,有兩個優勢:
命令模式的這些優勢,使得咱們能夠實現請求的排隊執行、記錄日誌等功能。
(本節完。)
推薦閱讀:
歡迎關注做者公衆號,獲取更多技術乾貨。