HeadFirst 設計模式學習筆記6 命令模式

2021-05-22 12:35:25 字數 1099 閱讀 1476

1.這一節我們的任務是建立乙個類似智慧型家居的萬能遙控器,控制各種家電。我們需要將「請求」封裝成物件(乙個命令物件通過在特定接收者上繫結一組動作來封裝請求),以便使用不同的請求、佇列、或者日誌來引數化其物件——這就是命令模式。

2.我們具體來看乙個例子:

首先我們要完成對命令的物件封裝:

只有乙個方法,所有的具體命令的物件都要實現這個介面,這就做到了封裝,比如對於燈這個物件,

我們可以通過上述介面封裝「開燈」這個命令,這個就是所謂的命令物件,它把動作和接收者包進物件之中,只暴露乙個execute方法:

而我們的遙控器對於上述封裝要一無所知,這樣才能做到解耦:

我們現在試著用一下這個遙控器,我們首先建立乙個遙控器,然後建立開燈這個命令並置於其中,最後按下按鍵,這樣,遙控器不知道是哪個物件(實際上是燈)進行了哪個動作(實際上是開燈這個動作)就可以完成請求的發出。如此一來,遙控器和燈之間的耦合性就非常低了:

很簡單的,我們想要在乙個遙控機中實現控制多個家電的能力就可以用乙個陣列來維護這樣的一組命令,可以看做提供了多個命令的插槽:

你可能會注意到乙個叫做nocommand的物件出現在初始化遙控器物件時。這個是個小技巧,我們並不想每次都檢查某個插槽是不是都繫結了命令,那麼我們就引入了這個東東,實現乙個不做事情的命令:

這樣初始化就讓每乙個插槽都有命令了,以後若不進一步指明命令的插槽,那麼就是預設這個nocommand物件。這就是乙個典型的「空物件」例子,當你不想返回乙個有意義的物件時,空物件就十分有用,此時空物件可以做成判斷null或者提示「未繫結」資訊的工作。

3.我們在命令模式中也可以設定類似undo的撤銷命令來撤銷發出的命令請求:

我們還是拿開電燈這個操作來說明,畢竟這足夠簡單:對於乙個開燈命令,其對應的撤銷命令自然是「關電燈」:

雖然這簡單之極,這還沒完,我們必須讓遙控器記住上次到底做了什麼操作,才可能去撤銷:

對於電燈,我們只有兩種狀態,但是要是多個狀態呢?我們舉乙個吊扇的例子,吊扇有多個轉速,高中低關,四個狀態:

那麼在實現風扇各個轉速命令時,就要去記錄在執行這個命令前風扇的轉速,其撤銷命令中則根據記錄的部分完成undo操作。

當然你也可以實現諸如多個命令批量執行和完成多個撤銷操作。

命令模式可以用於工作佇列和日誌操作等方面。

《Head first設計模式》學習筆記

開閉原則的意思是 對擴充套件開放,對修改關閉。在程式需要進行拓展的時候,不能去修改原有的 實現乙個熱插拔的效果。簡言之,是為了使程式的擴充套件性好,易於維護和公升級。想要達到這樣的效果,我們需要使用介面和抽象類,後面的具體設計中我們會提到這點。黎克特制代換原則是物件導向設計的基本原則之一。黎克特制代...

headfirst設計模式

花了一周多一點的時間看完了headfirst的設計模式。看完之後有一種恍然大悟的感覺,仔細想想有覺得自己好像什麼也看懂。簡單說下對這本書的一點感悟吧,headfirst的書比較通俗易懂,之前看了四人幫的設計模式,看一半就有一種痛不欲生的感覺,自己水平有限,看不懂,也就沒在勉強自己了。對於模式其實簡單...

HeadFirst設計模式學習筆記02

執行時擴充套件,遠比編譯時繼承威力大。熟悉了裝飾的技巧,能夠在不改變任何底層 的情況下,給你的物件賦予新的職責。星巴茲starbuzz以擴張速度快聞名,準備更新訂單系統,以適應他們的飲料 要求。原先類的設計 現在想購買咖啡時,可以要求在其中加入各種調料,如蒸奶 steamed milk 豆漿 soy...