第六部分 ? ? ?行 ?為 ?擴 ?展
第15章 ? ?訪 問 者
訪問者模式:表示一個作用于某對象結(jié)構(gòu)中的各元素的操作沉馆。它讓我們可以在不改變各元素的類的前提下定義作用于這些元素的新操作。
何時使用訪問者模式
- ?一個復(fù)雜的對象結(jié)構(gòu)包含很多其他對象,它們有不同的接口(比如組合體)朝刊,但是想對這些對象實施一些依賴于其具體類型的操作。
- ?需要對一個組合結(jié)構(gòu)中的對象進行很多不相關(guān)的操作,但是不想讓這些操作“污染”這些對象的類陪捷。可以將相關(guān)的操作集中起來诺擅,定義在一個訪問者類中市袖,并在需要在訪問者中定義的操作時使用它。
- ?定義復(fù)雜結(jié)構(gòu)的類很少作修改烁涌,但是經(jīng)常需要向其添加新的操作苍碟。
說明: 訪問者模式有個需要注意的缺點,那就是撮执,訪問者與目標類耦合在一起微峰。因此,如果訪問者需要支持新的類(比如向Mark家族增加新的節(jié)點類型)抒钱,訪問者的父類和子類都需要修改蜓肆,才能反映新的功能。不過谋币,要是不經(jīng)常往目標類家族中添加新類仗扬,也沒什么大問題。
由于將來對訪問者的修改不可預(yù)見蕾额,為每個訪問者準備一個“萬能”的訪問方法厉颤,來支持未來的目標類,是個好注意凡简。要是經(jīng)常需要增加新節(jié)點逼友,就應(yīng)該下定決心精肃,修改訪問者的接口,以支持新的節(jié)點類型帜乞。
訪問者的其他用途
請注意司抱,如果把這些操作放在Mark接口,那么就需要同時修改每個節(jié)點類黎烈。因此习柠,一旦對組合結(jié)構(gòu)實現(xiàn)了訪問者模式,通常就再也不需要修改組合體類的接口了照棋。
總結(jié): 訪問者模式是擴展組合結(jié)構(gòu)功能的一種強有力的方式资溃。如果組合結(jié)構(gòu)具有精心設(shè)計的基本操作,而且結(jié)構(gòu)將來也不會變更烈炭,就可以使用訪問者模式溶锭,用各種不同用途的訪問者,以同樣的方式訪問這個組合結(jié)構(gòu)符隙。訪問者模式用盡可能少的修改趴捅,可以把組合體結(jié)構(gòu)與其他訪問者類中的相關(guān)算法分離。
在下一章霹疫,將討論另一種模式拱绑,它通過從外部進行“裝飾”,同樣可以擴展對象的行為丽蝎。
第16章 ? ? ?裝 ? ?飾
裝飾模式: 動態(tài)地給一個對象添加一些額外的職責(zé)猎拨。就擴展功能來說,裝飾模式相比生成子類更為靈活屠阻。
何時使用裝飾模式
- ?想要在不影響其他對象的情況下迟几,以動態(tài)、透明的方式給單個對象添加職責(zé)栏笆;
- ?想要擴展一個類的行為类腮,卻做不到。類定義可能被隱藏蛉加,無法進行子類化蚜枢;或者,對類的每個行為的擴展针饥,為支持每種功能組合厂抽,將產(chǎn)生大量的子類。
- ?對類的職責(zé)的擴展是可選的丁眼。
說明:濾鏡可以用不同順序進行連接筷凤。
通過范疇實現(xiàn)裝飾
在使用范疇的方式中,只需要向UIImage類添加濾鏡,構(gòu)成范疇藐守,它們雖然不是單獨的UIImage類挪丢,卻能夠像單獨的UIImage類那樣使用。這就是OC中范疇的好處卢厂。我們要加兩個濾鏡乾蓬,一個對圖像用二維變換,另一個向圖像添加陰影效果慎恒。
第17章 ? ?責(zé) ? 任 ? 鏈
責(zé)任鏈模式:使多個對象都有機會處理請求任内,從而避免請求的發(fā)送者和接受者之間發(fā)生耦合。此模式將這些對象連接成一條鏈融柬,并沿著這條鏈傳遞請求死嗦,直到有一個對象處理它為止。
何時使用責(zé)任鏈模式:
- ?有多個對象可以處理請求粒氧,而處理程序只有在運行時才能確定越除;
- ?向一組對象發(fā)出請求,而不想顯示指定處理請求的特定處理程序靠欢。
總結(jié):
本章的例子中廊敌,我們把RPG游戲中人物的各種防御機制實現(xiàn)為責(zé)任鏈模式铜跑。每種防御機制只能應(yīng)付一種特定的攻擊门怪。一個攻擊處理程序鏈決定了人物可以防御何種攻擊。在游戲過程中锅纺,任何攻擊處理程序都能在任何時間被添加或刪除掷空,而不會影響人物的其他行為。對于此類設(shè)計囤锉,責(zé)任鏈模式是很自然的選擇坦弟。否則,攻擊處理程序的復(fù)雜組合會讓人物的代碼非常龐大官地,讓處理程序的變更非常困難酿傍。
已經(jīng)討論過的這幾個模式,都是在擴展對象的行為的同時驱入,對對象進行最少的修改甚至不作修改赤炒。接下來將討論如何通過封裝和擴展對象的算法來改變對象的行為。