1. 程式人生 > >不一樣的命令模式(設計模式十五)

不一樣的命令模式(設計模式十五)

### 前言 什麼是命令模式呢?其實是這樣一個東西。 “行為請求者”與“行為實現者”通常呈現一種“緊耦合” 先介紹一下什麼是行為請求者和行為實現者沒有分開: ``` class Person() { public void eat() { //吃飯 } public void sleep() { //碎覺 } } class ClientA() { public void do() { person.eat(); } } ``` 這個是行為請求者和行為實現者沒有分開。 他們通過之間呼叫的方式,是一個緊耦合的關係。但是有些情況下,緊耦合並不適用。 現在又一個一個客戶: ``` class ClientB() { public void do() { person.sleep(); } } ``` 比如說,現在clientA和clientB 非常多,並且是一個併發多執行緒的過程,但是又不立即執行,比如說訂單系統,要保持高響應。 要達到這種目的就需要一個佇列(當然也可以兩個佇列,但是如果person行為非常多,那麼佇列數量多的話難以維護),也就是說要把person.eat()和person.sleep()封裝成一個具備公共介面或者公共父類物件。這就是命令模式的核心思想,把一個行為封裝成一個物件。 把概念貼一下: ``` 命令模式(Command Pattern)是一種資料驅動的設計模式,它屬於行為型模式。請求以命令的形式包裹在物件中,並傳給呼叫物件。呼叫物件尋找可以處理該命令的合適的物件,並把該命令傳給相應的物件,該物件執行命令。 ``` ### 正文 那麼可以這樣寫,下面為手寫,不一定完全正確。 ``` public abstract class Command { public abstract void excute(); } ``` ``` public class EatCommand:Command { Peason peason; public EatCommand(Peason peason) { this.Person=Person } public void excute() { peason.eat(); } } ``` ``` public class SleepCommand:Command { Peason peason; public SleepCommand(Peason peason) { this.Person=Person } public void excute() { peason.sleep(); } } ``` ``` public class Manager { private static queue q=new queue(); public Manager() { } public void add(Command command) { q.add(command); } public void excute() { if(q.Count!=0) { //不用擔心這樣寫覺得command 會多餘哈,編譯器會幫我們優化,這樣寫更清晰 var command=q.Dequeue() as Command; command.excute(); } } } ``` 這裡只寫clientA: ``` class ClientA() { public void do() { //不要關心person怎麼來的,可以new 一個或者工廠例項化,等等 EatCommand Eatcomment=new EatCommand(person); //manager 單例,在另外一個執行緒中消費 manager.add(Eatcomment); } } ``` 這樣寫就是將一個行為變成了一個物件,而行為請求者和行為執行者,耦合性降低,這樣靈活性就上升了。 比如說,需要clientA 需要撤銷功能。 ``` public void do() { EatCommand Eatcomment=new EatCommand(person); if(...) { manager.add(Eatcomment); } if(...) { manager.remove(Eatcomment); } manager.excute(); } ``` 我這裡沒有實現remove,如果是這種的話,那麼就不是一個佇列而是一個集合或者別的。 這樣可以自由控制行為,而且可以延遲執行,延遲執行的優點可以參考linq。 因為行為變成了物件,誰是執行者這個問題就弱化了(就是說當person傳給了command,那麼關注點和person就沒有關係了),更多的關係到功能實現上了。 缺點: 使用命令模式可能會導致某些系統有過多的具體命令類。因為針對每一個命令都需要設計一個具體命令類,因此某些系統可能需要大量具體命令類,這將影響命令模式的