作者:CppExplore 網(wǎng)址:
http://www.shnenglu.com/CppExplore/好久不更新了,拿以前的文章湊湊數(shù),從java那邊轉(zhuǎn)一篇過來。
最近發(fā)現(xiàn)一本<java與模式>,正好再溫故一下當(dāng)年的專業(yè)課內(nèi)容,下面是這幾天記的筆記.(并不是系統(tǒng)的講解書中的內(nèi)容)
一 綜述:
1、不要使用接口定義常量
2、自己少用標(biāo)志接口
3、不要繼承具體類
4、類層次的中間節(jié)點(diǎn)應(yīng)該是接口或者抽象類,葉子是具體類
5、子類應(yīng)當(dāng)擴(kuò)展父類的責(zé)任,而不是覆寫父類的責(zé)任
6、面向接口編程
7、不要濫用繼承,組合優(yōu)先于繼承
java中設(shè)計(jì)不當(dāng)?shù)念悾篶alendar:作為接口,含有與具體的歷法(羅馬歷法)相關(guān)的常量,不能擴(kuò)展到中國的陰歷歷法(不符合開閉原則)
properies類:濫用繼承,繼承至hashtable,應(yīng)當(dāng)使用聚合
8、笛比特法則:只與自己的直接朋友通信,不與陌生人通信(1)狹義笛比特法則:只與朋友通訊,通過自己的朋友傳遞間接的調(diào)用(2)結(jié)合依賴倒轉(zhuǎn)原則修改:不必通過朋友傳遞間接的調(diào)用,通過陌生人的抽象接口調(diào)用陌生人的行為(依舊不能與具體的陌生人發(fā)生通信)
9、盡量降低類中成員的訪問權(quán)限,不要設(shè)計(jì)退化類(類似c中struct)。
java中的point2D以及Dinmension2D類有這種設(shè)計(jì)缺陷(不過這種情況問題不大)
10、如果多個具體的產(chǎn)品類沒有共同的商業(yè)邏輯,就可以把它們抽象到一個接口中,如果有共同的商業(yè)邏輯,就把共同的部分抽象到抽象類中,共同的部分盡量向類繼承層次的上層移動,以達(dá)到復(fù)用的目的
二 工廠模式
1、簡單工廠模式:參與角色:工廠/抽象產(chǎn)品類/具體產(chǎn)品類
缺點(diǎn):添加新產(chǎn)品的時候,雖然產(chǎn)品相關(guān)代碼符合開閉原則,但對工廠類本身并不符合,需要修改其中的產(chǎn)生產(chǎn)品方法或者添加新的產(chǎn)生方法(工廠里實(shí)現(xiàn)的不同造成的修改不同)來支持新的產(chǎn)品類
退化方式:省略掉工廠角色,抽象產(chǎn)品類擔(dān)任具體產(chǎn)品類的工廠角色:提供靜態(tài)的getInstance方法,比如java類庫中的DateFormat類,(本人認(rèn)為這樣很不符合開閉原則,父類中出現(xiàn)與具體子類相關(guān)的代碼,不方便擴(kuò)展,添加新產(chǎn)品的時候,修改的時候缺點(diǎn)與原簡單工廠的工廠角色類似)
2、工廠方法模式:參與角色:抽象工廠類/具體工廠類/抽象產(chǎn)品類/具體產(chǎn)品類
消除了簡單工廠的缺點(diǎn)
3、抽象工廠模式:簡單工廠模式與工廠方法模式的結(jié)合
4、單例模式:餓漢和懶漢兩種,前者將本身對象作為靜態(tài)私有屬性事先生成,后者推遲到調(diào)用的時候,后者需要考慮多線程的時候,前面需要加線程安全關(guān)鍵字(注意),java中還是前者為優(yōu)。
不要濫用單例,只有系統(tǒng)要求只有一個類的實(shí)例的時候才調(diào)用
有的單例可能有狀態(tài)屬性,這就為多例模式提供了可能
含有私有屬性的類作成單例的時候尤其要注意:一是私有屬性的線程安全,確實(shí)需要的時候可以加線程安全關(guān)鍵字,比如系統(tǒng)中的log類,二是確認(rèn)這些屬性是不是可以所有線程共享的,類似普通類的static
三 各種具體模式(1)
1、建造模式:參與角色4個:指導(dǎo)者、抽象建造對象、具體建造對象、產(chǎn)品
一個復(fù)雜的產(chǎn)品有很多的零部件,就可以使用具體的建造對象來一一構(gòu)造
2、原始模式:深拷貝、淺拷貝
3、適配器模式:將adaptee類適配成目標(biāo)接口
4、合成模式:參與角色:composite接口、樹枝節(jié)點(diǎn)類、樹葉節(jié)點(diǎn)類
分成透明式和安全式兩種,各有優(yōu)缺點(diǎn)
(1)前者將管理子對象的方法放到接口中,這樣樹型結(jié)構(gòu)中的所有對象都是透明的,都可以統(tǒng)一調(diào)用,但是葉節(jié)點(diǎn)并沒有管理子對象的能力,因此透明但不安全
(2)后者將管理子對象的方法下放到樹枝節(jié)點(diǎn)類中,這樣安全但不透明
5、裝飾模式:繼承已有類的接口,提供和已有類相同的方法,并對已有類的功能提供擴(kuò)展(通過組合已有對象,調(diào)用已有對象方法的時候加入新的代碼)
(1)透明的裝飾模式(純粹的裝飾模式):裝飾類、被裝飾類繼承于同一接口,而且裝飾類只實(shí)現(xiàn)接口的方法,不提供額外方法的實(shí)現(xiàn),調(diào)用該類的時候使用接口聲明調(diào)用(實(shí)例化當(dāng)然還是自己的構(gòu)造函數(shù)),即該類的所有方法都是透明的
(2)半透明的裝飾模式(退化的裝飾模式):裝飾類、被裝飾類繼承于同一接口,裝飾類不僅實(shí)現(xiàn)接口的方法,還提供額外方法的實(shí)現(xiàn),這樣要調(diào)用它獨(dú)特的方法的時候就必須使用它本身來調(diào)用,退化到一半裝飾模式、一半適配器模式。
四 各種具體模式(2)
1、代理模式:參與角色:代理與真實(shí)實(shí)體共同的抽象角色、代理角色、真實(shí)實(shí)體角色
遠(yuǎn)程代理:封裝對與遠(yuǎn)程對象復(fù)雜的調(diào)用通訊過程,象調(diào)用本地對象一樣
虛擬代理:真實(shí)實(shí)體加載時間過長的,使用虛擬代理提供友好的顯示方式,一邊加載實(shí)際的對象
安全代理:調(diào)用真實(shí)的對象之前插入權(quán)限驗(yàn)證模塊
智能引用代理:調(diào)用真實(shí)的對象之后調(diào)用統(tǒng)計(jì)等相關(guān)操作模塊
2、享元模式:參與對象:建造工廠、抽象享元、具體享元
分析對象的內(nèi)蘊(yùn)與外蘊(yùn)狀態(tài),即不變的私有屬性與變化的私有屬性。建造工廠使用備忘錄模式存儲已經(jīng)建造的對象,建造對象的時候,以參數(shù)的形式傳遞享元對象的內(nèi)蘊(yùn)屬性。實(shí)際調(diào)用中,使用傳遞外部參數(shù)的方法使用外蘊(yùn)變量。
復(fù)合的享元對象組成的對象,不可以整體使用享元模式,但可以單個的享元對象屬性使用該模式
優(yōu)點(diǎn):降低內(nèi)存中的對象 缺點(diǎn):設(shè)計(jì)復(fù)雜性
3、門面模式:結(jié)構(gòu)模式。為包含有很多對象的子系統(tǒng)提供統(tǒng)一的操作接口類,所有對該子系統(tǒng)的調(diào)用都通過這個類,降低子系統(tǒng)之間調(diào)用的復(fù)雜度,也符合笛比特法則(一個對象的朋友盡量少,只與朋友說話)
4、橋梁模式:參與角色:抽象化角色、抽象化的具體角色、實(shí)現(xiàn)化角色、實(shí)現(xiàn)化的具體角色兩個有繼承等級的對象群,一個對象群對另一個對象群有調(diào)用關(guān)系的時候使用
目的:使抽象化與實(shí)現(xiàn)化解藕
五 各種具體模式(3)
1、策略:常用于算法族,將算法從依賴的環(huán)境中抽象出來形成
2、狀態(tài):和策略非常接近,使用于有明顯狀態(tài)變化的時候
3、命令:命令的發(fā)起與執(zhí)行解藕,命令類可以獨(dú)立演化,有助于做redo undo操作以及記錄所執(zhí)行的命令
4、解釋:用于文法的解析
5、迭代子:java中有現(xiàn)成的實(shí)現(xiàn),iterator
6、觀察者:常見,類似與模型視圖的關(guān)系,java中提供了oberver類和observable接口
7、調(diào)停者:處理混亂的類交互,抽象出中間類,將類間的交互都通過這個類完成
8、模版:將擁有同一父類的多個具體子類的共同操作提取出來形成抽象模版類
原則:具體的私有屬性應(yīng)該放到具體類中,抽象類中調(diào)用屬性通過屬性方法而不是直接調(diào)用屬性
將私有屬性放到具體的類中,才能方便對父類進(jìn)行多個實(shí)現(xiàn)。
將行為看作劃分類的標(biāo)準(zhǔn),以前我都是將數(shù)據(jù)模型看作劃分類的思想,以后應(yīng)該重新審視行為在類中的重要作用,特別是在的繼承等級中。