手打不容易啊……
1撤蟆、 內(nèi)容來自《Design Patterns Explained》一書。
2即寒、 2报辱、附有Python代碼,個(gè)人覺得立帖,更清晰易懂眼溶,但是需要注意,Python代碼與“實(shí)現(xiàn)”的文字描述不一致晓勇,與C++或者Java風(fēng)格的模式演示代碼也不一致堂飞。代碼來自https://github.com/faif/python-patterns
3、 文中的Python代碼都是圖片绑咱,jianshu無法粘貼圖片绰筛,需要看到圖片請(qǐng)下載pdf格式附件或者自行到github上下載。
一描融、模板方法
模板方法(Template Method)通常用于定義一個(gè)操作中算法的骨架铝噩,而將一些步驟延遲到子類中,不改變算法的結(jié)構(gòu)就可以重新定義它的步驟窿克。
其關(guān)鍵特征:
1骏庸、 意圖:定義一個(gè)操作中算法的骨架,將一些步驟推遲到子類中實(shí)現(xiàn)年叮【弑唬可以不改變算法的結(jié)構(gòu)而重新定義該算法的步驟。
2只损、 問題:要完成在某一細(xì)節(jié)層次一致的一個(gè)過程或一系列步驟一姿,但其個(gè)別步驟在更詳細(xì)的層次上的實(shí)現(xiàn)可能不同。
3跃惫、 解決方案:允許定義可變的子步驟叮叹,同時(shí)保持基本過程一致。
4辈挂、 參與者與協(xié)作者:Template Method模式由一個(gè)抽象類組成衬横,這個(gè)抽象類定義了需要覆蓋的基本TemplateMethod方法,每個(gè)從這個(gè)抽象類派生的具體類將為此模板實(shí)現(xiàn)新方法终蒂。
5蜂林、 效果:模板提供了一個(gè)很好的代碼復(fù)用平臺(tái)遥诉,它還有助于確保所需步驟的實(shí)現(xiàn)。它將每個(gè)concrete類的覆蓋步驟綁定起來噪叙,因此只有在這些變化總是并且只能一起發(fā)生時(shí)矮锈,才應(yīng)該使用TemplateMethod模式。
6睁蕾、 實(shí)現(xiàn):創(chuàng)建一個(gè)抽象類苞笨,用抽象方法實(shí)現(xiàn)一個(gè)過程,這些抽象方法必須在子類中實(shí)現(xiàn)子眶,以執(zhí)行過程的整個(gè)步驟瀑凝。這些步驟是獨(dú)立變化的,那么每個(gè)步驟都可以考慮使用Strategy模式來實(shí)現(xiàn)臭杰。
7粤咪、 Python代碼:
二、策略模式
策略模式(Strategy Pattern)能把一系列“可互換的”算法封裝起來渴杆,并根據(jù)用戶的需求來選擇其中一種寥枝。
其關(guān)鍵特征:
1、 意圖:可以根據(jù)所處上下文磁奖,使用不同的業(yè)務(wù)規(guī)則或算法
2囊拜、 問題:對(duì)所需算法的選擇,取決于發(fā)出請(qǐng)求的客戶或者要處理的數(shù)據(jù)比搭。如果只有一些不會(huì)變化的算法冠跷,就不需要此模式。
3敢辩、 解決方案:將對(duì)算法的選擇和算法的實(shí)現(xiàn)相分離蔽莱。允許根據(jù)上下文進(jìn)行選擇弟疆。
4戚长、 參與者與協(xié)作者:
a、 Strategy指定了如何使用不同的算法
b怠苔、 各ConcreteStrategy實(shí)現(xiàn)了這些不同的算法
c同廉、 Context通過類型為Strategy的引用使用具體的ContextStrategy。Strategy與Context相互作用以實(shí)現(xiàn)所選擇的算法柑司,有些時(shí)候迫肖,Strategy必須查詢Context,Context將來自Client的請(qǐng)求轉(zhuǎn)發(fā)給Strategy攒驰。
5蟆湖、 效果:
a、 Strategy模式定義了一系列的算法
b玻粪、 可以不使用if語句或者switch語句
c隅津、 相異的算法擁有相同的接口诬垂,必須以相同的方式調(diào)用所有的算法。
d伦仍、 各ContextStrategy與Context之間的相互作用可能需要在Context中加入獲取狀態(tài)的方法
6结窘、 實(shí)現(xiàn):讓使用算法的類(Context)包含一個(gè)抽象類(Strategy),該抽象類有一個(gè)抽象方法指定如何調(diào)用算法充蓝。每個(gè)派生類按需要實(shí)現(xiàn)具體的算法隧枫。
7、 python代碼:
三谓苟、觀察者模式
觀察者模式(Observer Pattern)常用于處理對(duì)象間一對(duì)多的依賴關(guān)系官脓,當(dāng)某對(duì)象改變狀態(tài)時(shí),所有相關(guān)對(duì)象都會(huì)得到通知并自動(dòng)更新涝焙。
其關(guān)鍵特征:
1确买、 意圖:在對(duì)象之間定義一種一對(duì)多的依賴關(guān)系,這樣當(dāng)一個(gè)對(duì)象狀態(tài)改變時(shí)纱皆,所有依賴者都將得到通知并自動(dòng)更新湾趾。
2、 問題:當(dāng)某個(gè)事件發(fā)生時(shí)派草,需要向一系列變化著的對(duì)象發(fā)出通知搀缠。
3、 解決方案:Observer將監(jiān)視某個(gè)事件的責(zé)任委托給中心對(duì)象:Subject近迁。
4艺普、 參與者與協(xié)作者:Subject知道自己的Observer,因?yàn)镺bserver要向它注冊(cè)鉴竭。Subject必須在所監(jiān)視的事件發(fā)生時(shí)通知Observer歧譬。Observer負(fù)責(zé)向Subject注冊(cè)并在獲得通知時(shí),從Subject處獲取信息搏存。
5瑰步、 效果:如果某些Observer只對(duì)事件的一個(gè)子集感興趣,那么Subject可能會(huì)告知它不想要知道的事件璧眠。如果Subject通知了Observer缩焦,Observer還需要更多的信息,可能需要另外的通信责静。
6袁滥、 實(shí)現(xiàn):
a、 讓某個(gè)事件發(fā)生時(shí)需要知道的對(duì)象(Observer)將自己注冊(cè)到另一個(gè)監(jiān)視事件發(fā)生或自己觸發(fā)事件的對(duì)象(Subject)上灾螃。
b题翻、 事件發(fā)生時(shí),Subject告訴Observer事件已經(jīng)發(fā)生
c腰鬼、 為了對(duì)所有的Observer類型的對(duì)象實(shí)現(xiàn)Observer的接口嵌赠,有需要需要使用Adaptec模式靴拱。
7、 Python代碼:
四猾普、裝飾模式
裝飾模式(Decorator Pattern)用于動(dòng)態(tài)的給一個(gè)對(duì)象添加一些額外的職責(zé)袜炕,就增加功能來說,Decorator Pattern比生成子類更為靈活初家。
其關(guān)鍵特征:
1偎窘、 意圖:動(dòng)態(tài)的給一個(gè)對(duì)象添加職責(zé)。
2溜在、 問題:要使用的對(duì)象將執(zhí)行所需的基本功能陌知。但是,某些時(shí)刻可能需要為這個(gè)對(duì)象添加某些功能掖肋,這些附加功能可能發(fā)生在對(duì)象的基礎(chǔ)功能之前或之后仆葡。這是個(gè)常用的模式,比如說志笼,Python天然就支持沿盅。
3、 解決方案:可以無需創(chuàng)建子類纫溃,而擴(kuò)展一個(gè)對(duì)象的功能腰涧。
4、 參與者與協(xié)作者:ConcreteComponent讓Decorator對(duì)象為自己添加功能紊浩。有時(shí)候用ConcreteComponent的派生類提供核心功能窖铡,在這種情況下,ConcreteComponent類就是抽象的坊谁。Component類定義了所有這些類所使用的接口费彼。
5、 效果:所添加的功能放在小對(duì)象中口芍,好處是可以在ConcreteComponent對(duì)象的功能之前或者之后動(dòng)態(tài)添加功能箍铲。注意,雖然裝飾對(duì)象可以在被裝飾的對(duì)象之前或只有添加功能阶界,但是對(duì)象鏈總是終于ConcreteComponent對(duì)象虹钮。
6、 實(shí)現(xiàn):創(chuàng)建一個(gè)抽象類來表示原類和要添加到這個(gè)類的新功能膘融。在裝飾類中,將對(duì)新功能的調(diào)用放在對(duì)緊隨其后對(duì)象的調(diào)用之前或之后祭玉,以獲得正確的順序氧映。
7、 Python代碼:
五脱货、橋模式
橋模式(Bridge Pattern)用于將抽象(比如接口岛都,比如算法等)與實(shí)現(xiàn)方式相分離律姨,解耦后的抽象與實(shí)現(xiàn)方式可以獨(dú)立的變化。
其關(guān)鍵特征:
1臼疫、 意圖:將一組實(shí)現(xiàn)與另一組使用它們的對(duì)象分離择份。
2、 問題:一個(gè)抽象類的派生類必須使用多個(gè)實(shí)現(xiàn)烫堤,但不能出現(xiàn)類數(shù)量爆炸性的增長荣赶。
3、 解決方案:為所有實(shí)現(xiàn)定義一個(gè)接口鸽斟,供抽象類的所有派生類使用拔创。
4、 參與者與協(xié)作者:Abstraction為要實(shí)現(xiàn)的對(duì)象定義接口富蓄,Implementor為具體的實(shí)現(xiàn)類定義接口剩燥。Abstraction煩人派生類使用Implementor的派生類,卻無需知道自己具體使用了哪一個(gè)ConcreteImplementor立倍。
5灭红、 效果:實(shí)現(xiàn)與使用實(shí)現(xiàn)的對(duì)象解耦,提供了可擴(kuò)展性口注,客戶對(duì)象無需操心實(shí)現(xiàn)問題比伏。
6、 實(shí)現(xiàn):
a疆导、 將實(shí)現(xiàn)封裝在一個(gè)抽象類中
b赁项、 在要實(shí)現(xiàn)的抽象的基類中包含一個(gè)實(shí)現(xiàn)的句柄,
7澈段、 Python代碼