本文說(shuō)明:本文章只簡(jiǎn)單敘述設(shè)計(jì)模式本今,而且僅僅從理論上簡(jiǎn)單敘述闻蛀,僅此而已!2谋搿观挎!
本文摘自網(wǎng)絡(luò),純粹復(fù)制粘貼段化,不喜可以出門右轉(zhuǎn)嘁捷!謝謝!O匝雄嚣!
重要的事情說(shuō)三遍:僅僅從理論上簡(jiǎn)單敘述,僅僅從理論上簡(jiǎn)單敘述喘蟆,僅僅從理論上簡(jiǎn)單敘述缓升!
設(shè)計(jì)原則:
1.單一職責(zé)原則
不要存在多于一個(gè)導(dǎo)致類變更的原因。通俗的說(shuō)蕴轨,即一個(gè)類只負(fù)責(zé)一項(xiàng)職責(zé)港谊。
類T負(fù)責(zé)兩個(gè)不同的職責(zé):職責(zé)P1,職責(zé)P2尺棋。當(dāng)由于職責(zé)P1需求發(fā)生改變而需要修改類T時(shí)封锉,有可能會(huì)導(dǎo)致原本運(yùn)行正常的職責(zé)P2功能發(fā)生故障绵跷。
解決方案:遵循單一職責(zé)原則。分別建立兩個(gè)類T1成福、T2碾局,使T1完成職責(zé)P1功能,T2完成職責(zé)P2功能奴艾。這樣净当,當(dāng)修改類T1時(shí),不會(huì)使職責(zé)P2發(fā)生故障風(fēng)險(xiǎn)蕴潦;同理像啼,當(dāng)修改T2時(shí),也不會(huì)使職責(zé)P1發(fā)生故障風(fēng)險(xiǎn)潭苞。
2.里氏替換原則
如果對(duì)每一個(gè)類型為 T1的對(duì)象 o1忽冻,都有類型為 T2 的對(duì)象o2,使得以 T1定義的所有程序 P 在所有的對(duì)象 o1 都代換成 o2 時(shí)此疹,程序 P 的行為沒(méi)有發(fā)生變化僧诚,那么類型 T2 是類型 T1 的子類型。
所有引用基類的地方必須能透明地使用其子類的對(duì)象蝗碎。問(wèn)題由來(lái):有一功能P1湖笨,由類A完成。現(xiàn)需要將功能P1進(jìn)行擴(kuò)展蹦骑,擴(kuò)展后的功能為P慈省,其中P由原有功能P1與新功能P2組成。新功能P由類A的子類B來(lái)完成眠菇,則子類B在完成新功能P2的同時(shí)边败,有可能會(huì)導(dǎo)致原有功能P1發(fā)生故障。
解決方案:當(dāng)使用繼承時(shí)琼锋,遵循里氏替換原則放闺。類B繼承類A時(shí),除添加新的方法完成新增功能P2外缕坎,盡量不要重寫父類A的方法怖侦,也盡量不要重載父類A的方法。
3.依賴倒置原則
高層模塊不應(yīng)該依賴低層模塊谜叹,二者都應(yīng)該依賴其抽象匾寝;抽象不應(yīng)該依賴細(xì)節(jié);細(xì)節(jié)應(yīng)該依賴抽象荷腊。
類A直接依賴類B艳悔,假如要將類A改為依賴類C,則必須通過(guò)修改類A的代碼來(lái)達(dá)成女仰。這種場(chǎng)景下猜年,類A一般是高層模塊抡锈,負(fù)責(zé)復(fù)雜的業(yè)務(wù)邏輯;類B和類C是低層模塊乔外,負(fù)責(zé)基本的原子操作床三;假如修改類A,會(huì)給程序帶來(lái)不必要的風(fēng)險(xiǎn)杨幼。
解決方案:將類A修改為依賴接口I撇簿,類B和類C各自實(shí)現(xiàn)接口I,類A通過(guò)接口I間接與類B或者類C發(fā)生聯(lián)系差购,則會(huì)大大降低修改類A的幾率四瘫。
4.接口隔離原則
客戶端不應(yīng)該依賴它不需要的接口;一個(gè)類對(duì)另一個(gè)類的依賴應(yīng)該建立在最小的接口上欲逃。問(wèn)題由來(lái):類A通過(guò)接口I依賴類B找蜜,類C通過(guò)接口I依賴類D,如果接口I對(duì)于類A和類B來(lái)說(shuō)不是最小接口稳析,則類B和類D必須去實(shí)現(xiàn)他們不需要的方法锹杈。
解決方案:將臃腫的接口I拆分為獨(dú)立的幾個(gè)接口,類A和類C分別與他們需要的接口建立依賴關(guān)系迈着。也就是采用接口隔離原則。
5.迪米特法則
一個(gè)對(duì)象應(yīng)該對(duì)其他對(duì)象保持最少的了解邪码。
類與類之間的關(guān)系越密切裕菠,耦合度越大,當(dāng)一個(gè)類發(fā)生改變時(shí)闭专,對(duì)另一個(gè)類的影響也越大奴潘。
解決方案:盡量降低類與類之間的耦合。
6.開(kāi)閉原則
一個(gè)軟件實(shí)體如類影钉、模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開(kāi)放画髓,對(duì)修改關(guān)閉。
在軟件的生命周期內(nèi)平委,因?yàn)樽兓蜗骸⑸?jí)和維護(hù)等原因需要對(duì)軟件原有代碼進(jìn)行修改時(shí),可能會(huì)給舊代碼中引入錯(cuò)誤廉赔,也可能會(huì)使我們不得不對(duì)整個(gè)功能進(jìn)行重構(gòu)肉微,并且需要原有代碼經(jīng)過(guò)重新測(cè)試。
解決方案:當(dāng)軟件需要變化時(shí)蜡塌,盡量通過(guò)擴(kuò)展軟件實(shí)體的行為來(lái)實(shí)現(xiàn)變化碉纳,而不是通過(guò)修改已有的代碼來(lái)實(shí)現(xiàn)變化。
具體的設(shè)計(jì)模式:
1.單例模式:
確保一個(gè)類只有一個(gè)實(shí)例馏艾,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例劳曹。單例模式注意事項(xiàng):
只能使用單例類提供的方法得到單例對(duì)象奴愉,不要使用反射,否則將會(huì)實(shí)例化一個(gè)新對(duì)象铁孵。不要做斷開(kāi)單例類對(duì)象與類中靜態(tài)引用的危險(xiǎn)操作锭硼。多線程使用單例使用共享資源時(shí),注意線程安全問(wèn)題库菲。
2.工廠方法模式:
定義一個(gè)用于創(chuàng)建對(duì)象的接口账忘,讓子類決定實(shí)例化哪一個(gè)類,工廠方法使一個(gè)類的實(shí)例化延遲到其子類熙宇。在工廠方法模式中鳖擒,核心的工廠類不再負(fù)責(zé)所有的對(duì)象的創(chuàng)建,而是將具體創(chuàng)建的工作交給子類去做烫止。這個(gè)核心類則搖身一變蒋荚,成為了一個(gè)抽象工廠角色,僅負(fù)責(zé)給出具體工廠子類必須實(shí)現(xiàn)的接口馆蠕,而不接觸哪一個(gè)類應(yīng)當(dāng)被實(shí)例化這種細(xì)節(jié)期升。
3.抽象工廠模式
為創(chuàng)建一組相關(guān)或相互依賴的對(duì)象提供一個(gè)接口,而且無(wú)需指定他們的具體類互躬。在以下情況下播赁,適用于工廠方法模式:
(1) 當(dāng)一個(gè)類不知道它所必須創(chuàng)建的對(duì)象的類的時(shí)候。
(2) 當(dāng)一個(gè)類希望由它的子類來(lái)指定它所創(chuàng)建的對(duì)象的時(shí)候吼渡。
(3) 當(dāng)類將創(chuàng)建對(duì)象的職責(zé)委托給多個(gè)幫助子類中的某一個(gè)容为,并且你希望將哪一個(gè)幫助子類是代理者這一信息局部化的時(shí)候。
4.模版方法模式
定義一個(gè)操作中算法的框架寺酪,而將一些步驟延遲到子類中坎背,使得子類可以不改變算法的結(jié)構(gòu)即可重定義該算法中的某些特定步驟。子類可以置換掉父類的可變部分寄雀,但是子類卻不可以改變模板方法所代表的頂級(jí)邏輯得滤。
每當(dāng)定義一個(gè)新的子類時(shí),不要按照控制流程的思路去想盒犹,而應(yīng)當(dāng)按照“責(zé)任”的思路去想懂更。換言之,應(yīng)當(dāng)考慮哪些操作是必須置換掉的急膀,哪些操作是可以置換掉的膜蛔,以及哪些操作是不可以置換掉的。使用模板模式可以使這些責(zé)任變得清晰脖阵。
建造者模式將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離皂股,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。與抽象工廠的區(qū)別:在建造者模式里命黔,有個(gè)指導(dǎo)者呜呐,由指導(dǎo)者來(lái)管理建造者就斤,用戶是與指導(dǎo)者聯(lián)系的,指導(dǎo)者聯(lián)系建造者最后得到產(chǎn)品蘑辑。即建造模式可以強(qiáng)制實(shí)行一種分步驟進(jìn)行的建造過(guò)程洋机。
5.建造模式
是將復(fù)雜的內(nèi)部創(chuàng)建封裝在內(nèi)部,對(duì)于外部調(diào)用的人來(lái)說(shuō)洋魂,只需要傳入建造者和建造工具绷旗,對(duì)于內(nèi)部是如何建造成成品的,調(diào)用者無(wú)需關(guān)心副砍。
在Java的應(yīng)用中JavaMail使用到了該模式衔肢。
6.代理模式
為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。所謂代理豁翎,就是一個(gè)人或者機(jī)構(gòu)代表另一個(gè)人或者機(jī)構(gòu)采取行動(dòng)角骤。在一些情況下,一個(gè)客戶不想或者不能夠直接引用一個(gè)對(duì)象心剥,而代理對(duì)象可以在客戶端和目標(biāo)對(duì)象之間起到中介的作用邦尊。
7.原型模式
用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并通過(guò)拷貝這些原型創(chuàng)建新的對(duì)象优烧。
原型模式要求對(duì)象實(shí)現(xiàn)一個(gè)可以“克隆”自身的接口蝉揍,這樣就可以通過(guò)復(fù)制一個(gè)實(shí)例對(duì)象本身來(lái)創(chuàng)建一個(gè)新的實(shí)例。這樣一來(lái)畦娄,通過(guò)原型實(shí)例創(chuàng)建新的對(duì)象疑苫,就不再需要關(guān)心這個(gè)實(shí)例本身的類型,只要實(shí)現(xiàn)了克隆自身的方法纷责,就可以通過(guò)這個(gè)方法來(lái)獲取新的對(duì)象,而無(wú)須再去通過(guò)new來(lái)創(chuàng)建撼短。在Java語(yǔ)言里深度克隆一個(gè)對(duì)象再膳,常常可以先使對(duì)象實(shí)現(xiàn)Serializable接口曲横,然后把對(duì)象(實(shí)際上只是對(duì)象的拷貝)寫到一個(gè)流里(序列化)喂柒,再?gòu)牧骼镒x回來(lái)(反序列化),便可以重建對(duì)象禾嫉。
原型模式的優(yōu)點(diǎn)
原型模式允許在運(yùn)行時(shí)動(dòng)態(tài)改變具體的實(shí)現(xiàn)類型灾杰。原型模式可以在運(yùn)行期間,由客戶來(lái)注冊(cè)符合原型接口的實(shí)現(xiàn)類型熙参,也可以動(dòng)態(tài)地改變具體的實(shí)現(xiàn)類型艳吠,看起來(lái)接口沒(méi)有任何變化,但其實(shí)運(yùn)行的已經(jīng)是另外一個(gè)類實(shí)例了孽椰。因?yàn)榭寺∫粋€(gè)原型就類似于實(shí)例化一個(gè)類昭娩。
原型模式的缺點(diǎn)
原型模式最主要的缺點(diǎn)是每一個(gè)類都必須配備一個(gè)克隆方法凛篙。配備克隆方法需要對(duì)類的功能進(jìn)行通盤考慮,這對(duì)于全新的類來(lái)說(shuō)不是很難栏渺,而對(duì)于已經(jīng)有的類不一定很容易呛梆,特別是當(dāng)一個(gè)類引用不支持序列化的間接對(duì)象,或者引用含有循環(huán)結(jié)構(gòu)的時(shí)候磕诊。
8.中介者模式
用一個(gè)中介者對(duì)象封裝一系列的對(duì)象交互填物,中介者使各對(duì)象不需要顯示地相互作用,從而使耦合松散霎终,而且可以獨(dú)立地改變它們之間的交互滞磺。
中介者模式的優(yōu)點(diǎn)
適當(dāng)?shù)厥褂弥薪檎吣J娇梢员苊馔骂愔g的過(guò)度耦合,使得各同事類之間可以相對(duì)獨(dú)立地使用神僵。
使用中介者模式可以將對(duì)象間一對(duì)多的關(guān)聯(lián)轉(zhuǎn)變?yōu)橐粚?duì)一的關(guān)聯(lián)雁刷,使對(duì)象間的關(guān)系易于理解和維護(hù)。
使用中介者模式可以將對(duì)象的行為和協(xié)作進(jìn)行抽象保礼,能夠比較靈活的處理對(duì)象間的相互作用沛励。適用場(chǎng)景
在面向?qū)ο缶幊讨校粋€(gè)類必然會(huì)與其他的類發(fā)生依賴關(guān)系炮障,完全獨(dú)立的類是沒(méi)有意義的目派。一個(gè)類同時(shí)依賴多個(gè)類的情況也相當(dāng)普遍,既然存在這樣的情況胁赢,說(shuō)明企蹭,一對(duì)多的依賴關(guān)系有它的合理性,適當(dāng)?shù)氖褂弥薪檎吣J娇梢允乖玖鑱y的對(duì)象關(guān)系清晰智末,但是如果濫用谅摄,則可能會(huì)帶來(lái)反的效果。一般來(lái)說(shuō)系馆,只有對(duì)于那種同事類之間是網(wǎng)狀結(jié)構(gòu)的關(guān)系送漠,才會(huì)考慮使用中介者模式∮赡ⅲ可以將網(wǎng)狀結(jié)構(gòu)變?yōu)樾菭罱Y(jié)構(gòu)闽寡,使同事類之間的關(guān)系變的清晰一些。
中介者模式是一種比較常用的模式尼酿,也是一種比較容易被濫用的模式爷狈。對(duì)于大多數(shù)的情況,同事類之間的關(guān)系不會(huì)復(fù)雜到混亂不堪的網(wǎng)狀結(jié)構(gòu)裳擎,因此涎永,大多數(shù)情況下,將對(duì)象間的依賴關(guān)系封裝的同事類內(nèi)部就可以的,沒(méi)有必要非引入中介者模式土辩。濫用中介者模式支救,只會(huì)讓事情變的更復(fù)雜。
9.命令模式
意圖:將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象拷淘,從而可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化各墨;對(duì)請(qǐng)求排隊(duì)或記錄日志,以及支持可撤銷的操作
動(dòng)機(jī):將”發(fā)出請(qǐng)求的對(duì)象”和”接收與執(zhí)行這些請(qǐng)求的對(duì)象”分隔開(kāi)來(lái)启涯。常見(jiàn)應(yīng)用:
1贬堵、工作隊(duì)列,線程池结洼,日程安排
2黎做、日志請(qǐng)求(系統(tǒng)恢復(fù))
要點(diǎn):
1、命令模式將發(fā)出請(qǐng)求的對(duì)象和執(zhí)行請(qǐng)求的對(duì)象解耦
2松忍、在被解耦的兩者之間是通過(guò)命令對(duì)象進(jìn)行溝通的蒸殿。命令對(duì)象封裝了接收者和一個(gè)或一組動(dòng)作
3、調(diào)用者通過(guò)調(diào)用命令對(duì)象的execute()發(fā)出請(qǐng)求鸣峭,這會(huì)使得接收者的動(dòng)作被調(diào)用
4宏所、調(diào)用者可以接受命令當(dāng)作參數(shù),甚至在運(yùn)行時(shí)動(dòng)態(tài)的進(jìn)行
5摊溶、命令可以支持撤銷爬骤,做法是實(shí)現(xiàn)一個(gè)undo()方法來(lái)回到execute()被執(zhí)行前的狀態(tài)
6、宏命令是命令的一種簡(jiǎn)單的延伸莫换,允許調(diào)用多個(gè)命令霞玄。宏方法也可以支持撤銷
7、實(shí)際操作時(shí)拉岁,很常見(jiàn)使用"聰明"命令對(duì)象坷剧,也就是直接實(shí)現(xiàn)了請(qǐng)求,而不是將工作委托給接受者(弊端喊暖?)
8惫企、命令也可以用來(lái)實(shí)現(xiàn)日志和事物系統(tǒng)
10.責(zé)任鏈模式
使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系哄啄。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求风范,直到有對(duì)象處理它為止咨跌。一個(gè)純的責(zé)任鏈模式要求一個(gè)具體的處理者對(duì)象只能在兩個(gè)行為中選擇一個(gè):一是承擔(dān)責(zé)任,而是把責(zé)任推給下家硼婿。不允許出現(xiàn)某一個(gè)具體處理者對(duì)象在承擔(dān)了一部分責(zé)任后又 把責(zé)任向下傳的情況锌半。
在一個(gè)純的責(zé)任鏈模式里面,一個(gè)請(qǐng)求必須被某一個(gè)處理者對(duì)象所接收寇漫;在一個(gè)不純的責(zé)任鏈模式里面刊殉,一個(gè)請(qǐng)求可以最終不被任何接收端對(duì)象所接收殉摔。
純的責(zé)任鏈模式的實(shí)際例子很難找到,一般看到的例子均是不純的責(zé)任鏈模式的實(shí)現(xiàn)记焊。有些人認(rèn)為不純的責(zé)任鏈根本不是責(zé)任鏈模式逸月,這也許是有道理的。但是在實(shí)際的系統(tǒng)里遍膜,純的責(zé)任鏈很難找到碗硬。如果堅(jiān)持責(zé)任鏈不純便不是責(zé)任鏈模式,那么責(zé)任鏈模式便不會(huì)有太大意義了瓢颅。
11.裝飾模式
又名包裝(Wrapper)模式恩尾,裝飾模式以對(duì)客戶端透明的方式擴(kuò)展對(duì)象的功能,是繼承關(guān)系的一個(gè)替代方案挽懦。裝飾模式與類繼承的區(qū)別:
1) ? ?裝飾模式是一種動(dòng)態(tài)行為翰意,對(duì)已經(jīng)存在類進(jìn)行隨意組合,而類的繼承是一種靜態(tài)的行為信柿,一個(gè)類定義成什么樣的冀偶,該類的對(duì)象便具有什么樣的功能,無(wú)法動(dòng)態(tài)的改變角塑。
2) ? ?裝飾模式擴(kuò)展的是對(duì)象的功能蔫磨,不需要增加類的數(shù)量,而類繼承擴(kuò)展是類的功能圃伶,在繼承的關(guān)系中堤如,如果我們想增加一個(gè)對(duì)象的功能,我們只能通過(guò)繼承關(guān)系窒朋,在子類中增加兩個(gè)方法搀罢。
3) ? ?裝飾與繼承比較圖:
4) ? ?裝飾模式是在不改變?cè)愇募褪褂美^承的情況下,動(dòng)態(tài)的擴(kuò)展一個(gè)對(duì)象的功能侥猩,它是通過(guò)創(chuàng)建一個(gè)包裝對(duì)象榔至,也就是裝飾來(lái)包裹真是的對(duì)象。
5. ? ?裝飾模式把對(duì)客戶端的調(diào)用委派給被裝飾的類欺劳,裝飾模式的關(guān)鍵在于這種擴(kuò)展完全透明的唧取。
12.策略模式
定義一組算法,將每個(gè)算法都封裝起來(lái)划提,并且使他們之間可以互換枫弟。
策略模式的好處在于你可以動(dòng)態(tài)的改變對(duì)象的行為。策略模式屬于對(duì)象行為型模式鹏往,主要針對(duì)一組算法淡诗,將每一個(gè)算法封裝到具有共同接口的獨(dú)立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響
到客戶端的情況下發(fā)生變化韩容。通常款违,策略模式適用于當(dāng)一個(gè)應(yīng)用程序需要實(shí)現(xiàn)一種特定的服務(wù)或者功能,而且該程序有多種實(shí)現(xiàn)方式時(shí)使用群凶。
13.適配器模式
基于現(xiàn)有類所提供的服務(wù)插爹,向客戶提供接口,以滿足客戶的期望座掘。
適配器模式的用意是要改變?cè)吹慕涌诘萃铮员阌谀繕?biāo)接口相容。缺省適配的用意稍有不同溢陪,它是為了方便建立一個(gè)不平庸的適配器類而提供的一種平庸實(shí)現(xiàn)萍虽。適配器模式的優(yōu)點(diǎn)
更好的復(fù)用性
系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要形真。那么通過(guò)適配器模式就可以讓這些功能得到更好的復(fù)用杉编。
更好的擴(kuò)展性
在實(shí)現(xiàn)適配器功能的時(shí)候,可以調(diào)用自己開(kāi)發(fā)的功能咆霜,從而自然地?cái)U(kuò)展系統(tǒng)的功能邓馒。
適配器模式的缺點(diǎn)
過(guò)多的使用適配器,會(huì)讓系統(tǒng)非常零亂蛾坯,不易整體進(jìn)行把握光酣。比如,明明看到調(diào)用的是A接口脉课,其實(shí)內(nèi)部被適配成了B接口的實(shí)現(xiàn)救军,一個(gè)系統(tǒng)如果太多出現(xiàn)這種情況,無(wú)異于一場(chǎng)災(zāi)難倘零。因此如果不是很有必要唱遭,可以不使用適配器,而是直接對(duì)系統(tǒng)進(jìn)行重構(gòu)呈驶。
14.迭代器模式
提供一種方法訪問(wèn)一個(gè)容器對(duì)象中各個(gè)元素拷泽,而又不暴露該對(duì)象的內(nèi)部細(xì)節(jié)。在jdk中,與迭代器相關(guān)的接口有兩個(gè):Iterator 與 Iterable
Iterator:迭代器袖瞻,Iterator及其子類通常是迭代器本身的結(jié)構(gòu)與方法司致;
Iterable:可迭代的,那些想用到迭代器功能的其它類聋迎,如AbstractList HashMap等脂矫,需要實(shí)現(xiàn)該接口。
15.組合模式
將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示‘部分-整體’的層次結(jié)構(gòu)砌庄。組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性羹唠。
對(duì)象通過(guò)實(shí)現(xiàn)(繼承)統(tǒng)一的接口(抽象類),調(diào)用者對(duì)單一對(duì)象和組合對(duì)象的操作具有一致性娄昆。通過(guò)實(shí)現(xiàn)組合模式佩微,調(diào)用者對(duì)組合對(duì)象的操作與對(duì)單一對(duì)象的操作具有一致性。調(diào)用者不用關(guān)心這是組合對(duì)象還是文件萌焰,也不用關(guān)心組合對(duì)象內(nèi)部的具體結(jié)構(gòu)哺眯,就可以調(diào)用相關(guān)方法,實(shí)現(xiàn)功能扒俯。
16.觀察者模式
定義對(duì)象間一種一對(duì)多的依賴關(guān)系奶卓,使得當(dāng)每一個(gè)對(duì)象改變狀態(tài),則所有依賴于它的對(duì)象都會(huì)得到通知并自動(dòng)更新撼玄。
觀察者模式定義了一種一對(duì)多的依賴關(guān)系夺姑,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)上發(fā)生變化時(shí)掌猛,會(huì)通知所有觀察者對(duì)象盏浙,使它們能夠自動(dòng)更新自己。在JAVA語(yǔ)言的java.util庫(kù)里面荔茬,提供了一個(gè)Observable類以及一個(gè)Observer接口废膘,構(gòu)成JAVA語(yǔ)言對(duì)觀察者模式的支持。
17.門面模式
外部與一個(gè)子系統(tǒng)的通信必須通過(guò)一個(gè)統(tǒng)一的門面對(duì)象進(jìn)行慕蔚。門面模式的優(yōu)點(diǎn):
● 松散耦合
門面模式松散了客戶端與子系統(tǒng)的耦合關(guān)系丐黄,讓子系統(tǒng)內(nèi)部的模塊能更容易擴(kuò)展和維護(hù)。
● 簡(jiǎn)單易用
門面模式讓子系統(tǒng)更加易用孔飒,客戶端不再需要了解子系統(tǒng)內(nèi)部的實(shí)現(xiàn)灌闺,也不需要跟眾多子系統(tǒng)內(nèi)部的模塊進(jìn)行交互,只需要跟門面類交互就可以了十偶。
● 更好的劃分訪問(wèn)層次
通過(guò)合理使用Facade菩鲜,可以幫助我們更好地劃分訪問(wèn)的層次。有些方法是對(duì)系統(tǒng)外的惦积,有些方法是系統(tǒng)內(nèi)部使用的接校。把需要暴露給外部的功能集中到門面中,這樣既方便客戶端使用狮崩,也很好地隱藏了內(nèi)部的細(xì)節(jié)蛛勉。
18.備忘錄模式
在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài)睦柴,并在該對(duì)象之外保存這個(gè)狀態(tài)诽凌。這樣就可以將該對(duì)象恢復(fù)到原先保存的狀態(tài)。備忘錄對(duì)象是一個(gè)用來(lái)存儲(chǔ)另外一個(gè)對(duì)象內(nèi)部狀態(tài)的快照的對(duì)象坦敌。備忘錄模式的用意是在不破壞封裝的條件下侣诵,將一個(gè)對(duì)象的狀態(tài)捕捉(Capture)住痢法,并外部化,存儲(chǔ)起來(lái)杜顺,從而可以在將來(lái)合適的時(shí)候把這個(gè)對(duì)象還原到存儲(chǔ)起來(lái)的狀態(tài)财搁。備忘錄模式常常與命令模式和迭代子模式一同使用。
19.訪問(wèn)者模式
封裝某些作用于某種數(shù)據(jù)結(jié)構(gòu)中各元素的操作躬络,它可以在不改變數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作尖奔。
訪問(wèn)者模式是對(duì)象的行為模式。訪問(wèn)者模式的目的是封裝一些施加于某種數(shù)據(jù)結(jié)構(gòu)元素之上的操作穷当。一旦這些操作需要修改的話提茁,接受這個(gè)操作的數(shù)據(jù)結(jié)構(gòu)則可以保持不變。
訪問(wèn)者模式的優(yōu)點(diǎn)
a好的擴(kuò)展性.能夠在不修改對(duì)象結(jié)構(gòu)中的元素的情況下馁菜,為對(duì)象結(jié)構(gòu)中的元素添加新的功能茴扁。
b好的復(fù)用性.可以通過(guò)訪問(wèn)者來(lái)定義整個(gè)對(duì)象結(jié)構(gòu)通用的功能,從而提高復(fù)用程度汪疮。
c分離無(wú)關(guān)行為.可以通過(guò)訪問(wèn)者來(lái)分離無(wú)關(guān)的行為丹弱,把相關(guān)的行為封裝在一起,構(gòu)成一個(gè)訪問(wèn)者铲咨,這樣每一個(gè)訪問(wèn)者的功能都比較單一躲胳。
訪問(wèn)者模式的缺點(diǎn)
a對(duì)象結(jié)構(gòu)變化很困難.不適用于對(duì)象結(jié)構(gòu)中的類經(jīng)常變化的情況,因?yàn)閷?duì)象結(jié)構(gòu)發(fā)生了改變纤勒,訪問(wèn)者的接口和訪問(wèn)者的實(shí)現(xiàn)都要發(fā)生相應(yīng)的改變坯苹,代價(jià)太高。
b破壞封裝.訪問(wèn)者模式通常需要對(duì)象結(jié)構(gòu)開(kāi)放內(nèi)部數(shù)據(jù)給訪問(wèn)者和ObjectStructrue摇天,這破壞了對(duì)象的封裝性粹湃。
20.狀態(tài)模式.
當(dāng)一個(gè)對(duì)象的內(nèi)在狀態(tài)改變時(shí)允許改變其行為,這個(gè)對(duì)象看起來(lái)像是改變了其類泉坐。
狀態(tài)模式.允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變的時(shí)候改變其行為为鳄。這個(gè)對(duì)象看上去就像是改變了它的類一樣。
21.解釋器模式
給定一種語(yǔ)言腕让,定義他的文法的一種表示孤钦,并定義一個(gè)解釋器,該解釋器使用該表示來(lái)解釋語(yǔ)言中句子纯丸。
22.享元模式.
復(fù)用我們內(nèi)存中已存在的對(duì)象偏形,降低系統(tǒng)創(chuàng)建對(duì)象實(shí)例的性能消耗。
Flyweight在拳擊比賽中指最輕量級(jí)觉鼻,即“蠅量級(jí)”或“雨量級(jí)”俊扭,這里選擇使用“享元模式”的意譯,是因?yàn)檫@樣更能反映模式的用意坠陈。享元模式是對(duì)象的結(jié)構(gòu)模式萨惑。享元模式以共享的方式高效地支持大量的細(xì)粒度對(duì)象捐康。享元模式采用一個(gè)共享來(lái)避免大量擁有相同內(nèi)容對(duì)象的開(kāi)銷。這種開(kāi)銷最常見(jiàn)庸蔼、最直觀的就是內(nèi)存的損耗吹由。享元對(duì)象能做到共享的關(guān)鍵是區(qū)分內(nèi)蘊(yùn)狀態(tài)(Internal State)和外蘊(yùn)狀態(tài)(External State)。
23.橋梁模式
將抽象和實(shí)現(xiàn)解耦朱嘴,使得兩者可以獨(dú)立地變化。
橋梁模式的用意是“將抽象化(Abstraction)與實(shí)現(xiàn)化(Implementation)脫耦粗合,使得二者可以獨(dú)立地變化”萍嬉。橋梁模式在Java應(yīng)用中的一個(gè)非常典型的例子就是JDBC驅(qū)動(dòng)器。JDBC為所有的關(guān)系型數(shù)據(jù)庫(kù)提供一個(gè)通用的界面隙疚。一個(gè)應(yīng)用系統(tǒng)動(dòng)態(tài)地選擇一個(gè)合適的驅(qū)動(dòng)器壤追,然后通過(guò)驅(qū)動(dòng)器向數(shù)據(jù)庫(kù)引擎發(fā)出指令。這個(gè)過(guò)程就是將抽象角色的行為委派給實(shí)現(xiàn)角色的過(guò)程供屉。