首先,我們得清楚為何要解耦?
耦合的壞處就是,牽一髮而動全身,比如,當我更改了類A或其子類的時候,類B也要進行修改。這裡,解除耦合,就意味著,即使你Receiver怎麼改,新增了多少,刪除了多少。我Invoker都不需要做什麼改動。
有人會說,這不是很好辦嗎,我定義一個介面,每個Receiver都實現這個介面,然後我Invoker針對這個介面程式設計不就好了?
這樣有兩個問題,一方面,我可能需要根據Receivier的方法或特性進行多種操作,一個介面實現是不能夠滿足需求的。
另一方面,如果有些Receiver已經存在,如果要讓它實現一個介面,那不是就要修改原來的程式碼嗎,這是要儘量避免的。
注意:Receiver可以是任何一個類。我們的目的就是要無修改地利用現有類。讓Invoker根據需要,利用現有類的部分功能。
命令模式如何實現解耦?
Invoker同樣是針對介面程式設計,不過這個介面並不是由Receiver實現,而是由命令物件實現。Invoker只管呼叫命令物件的execute方法即可,它根本不知道execute方法裡發生了什麼。命令物件就是Invoker和Receiver之間溝通的橋樑。利用命令物件,我們可以根據需要使Invoker呼叫某個類的某個方法等。
有人就奇怪了,要操作一個Receiver的某個方法,直接呼叫不就好了,為什麼還要封裝一下,專門給Invoker呼叫,這麼麻煩?
很多學習命令模式的,剛接觸的案例都是那幾個。直接呼叫,和讓Invoker呼叫,輸出也沒什麼差別。所以,很多人沒有意識到,命令給誰做的差別。但是,設想一下,如果這個命令是交給一個執行緒呢?這就不一樣了吧。
如果不是直接呼叫,而是給其他類呼叫,那麼這個呼叫類就必須知道該如何操作這個被呼叫的類(Receiver),而命令物件,就告訴了它,"別怕,你只要執行我的execute方法就好了,其他細節我來處理。"