創(chuàng)建型設(shè)計(jì)模式
主要解決對(duì)象的創(chuàng)建問(wèn)題,封裝復(fù)雜的創(chuàng)建過(guò)程捺信,解耦對(duì)象的創(chuàng)建代碼合使用代碼岳瞭。
單例模式
單例模式用來(lái)創(chuàng)建全局唯一的對(duì)象。一個(gè)類(lèi)只允許創(chuàng)建一個(gè)對(duì)象候齿,這個(gè)類(lèi)就是一個(gè)單例類(lèi)熙暴。單例有幾種經(jīng)典實(shí)現(xiàn)方式,分別為:餓漢式慌盯、懶漢式周霉、雙重檢測(cè)、靜態(tài)內(nèi)部類(lèi)亚皂、枚舉俱箱。
工廠模式
工廠模式包含簡(jiǎn)單工廠、工廠方法灭必、抽象工廠這三種細(xì)分模式狞谱。其中,前兩者比較常用禁漓、后一種并不常用跟衅。
工廠模式用來(lái)創(chuàng)建不同但是相關(guān)類(lèi)型的對(duì)象(繼承同一父類(lèi)或者接口的一組子類(lèi)),由給定參數(shù)來(lái)決定創(chuàng)建哪種類(lèi)型的對(duì)象播歼。
實(shí)際上伶跷,如果創(chuàng)建對(duì)象邏輯不復(fù)雜,直接new就可以了秘狞,不需要使用工廠模式叭莫。當(dāng)創(chuàng)建邏輯比較復(fù)雜時(shí),考慮使用工廠模式烁试,封裝對(duì)象的創(chuàng)建過(guò)程雇初,將對(duì)象創(chuàng)建與使用相分離。
當(dāng)對(duì)象創(chuàng)建邏輯比較簡(jiǎn)單時(shí)廓潜,推薦使用簡(jiǎn)單工廠模式抵皱,將多個(gè)對(duì)象創(chuàng)建邏輯放到一個(gè)類(lèi)中善榛。
當(dāng)對(duì)象創(chuàng)建邏輯比較復(fù)雜時(shí),推薦使用工廠方法模式呻畸,避免設(shè)計(jì)一個(gè)過(guò)于龐大的工廠類(lèi)移盆,將創(chuàng)建邏輯拆分得更細(xì),每個(gè)對(duì)象的創(chuàng)建邏輯獨(dú)立到各自的工廠類(lèi)中伤为。
工廠模式的作用有下面4個(gè):
1.封裝變化咒循。將創(chuàng)建邏輯的變更對(duì)調(diào)用者透明。
2.代碼復(fù)用绞愚。創(chuàng)建代碼抽離到獨(dú)立的工廠類(lèi)后可以復(fù)用叙甸。
3.隔離復(fù)雜性。封裝創(chuàng)建位衩,調(diào)用者無(wú)需了解如何創(chuàng)建裆蒸。
4.控制復(fù)雜度。將創(chuàng)建代碼抽離糖驴,讓原本函數(shù)或類(lèi)職責(zé)更加單一僚祷。
建造者模式
建造者模式用來(lái)創(chuàng)建復(fù)雜對(duì)象,可以通過(guò)設(shè)置不同的可選參數(shù)贮缕,定制化地創(chuàng)建不同的對(duì)象辙谜。
如果有下面情況,可以考慮使用建造者模式:
1.如果類(lèi)的屬性之間有一定的依賴(lài)關(guān)系或者約束條件感昼;
2.如果希望創(chuàng)建不可變對(duì)象装哆,也就是說(shuō),對(duì)象創(chuàng)建好之后定嗓,不能再修改內(nèi)部的屬性值蜕琴,這樣就不能在類(lèi)中暴露set方法。
原型模式
如果對(duì)象的創(chuàng)建成本比較大蜕乡,而同一個(gè)類(lèi)的不同對(duì)象之間差別不大(大部分字段都相同)奸绷。這種情況下,我們可以利用已有對(duì)象(原型)進(jìn)行拷貝的方法层玲,來(lái)創(chuàng)建新對(duì)象号醉,以達(dá)到節(jié)省創(chuàng)建時(shí)間的目的。
這種基于原型來(lái)創(chuàng)建對(duì)象的方式就叫做原型模式辛块。
原型模式有兩種實(shí)現(xiàn)方法:深拷貝和淺拷貝畔派。
淺拷貝只會(huì)復(fù)制類(lèi)中的基本數(shù)據(jù)類(lèi)型數(shù)據(jù)和引用對(duì)象的內(nèi)存地址;
深拷貝得到的是一份完全獨(dú)立的對(duì)象润绵。所以更加耗時(shí)线椰,耗內(nèi)存空間;
如果要拷貝的對(duì)象時(shí)不可變對(duì)象尘盼,淺拷貝共享不可變對(duì)象是沒(méi)問(wèn)題的憨愉。但是對(duì)于可變對(duì)象來(lái)說(shuō)烦绳,淺拷貝得到的對(duì)象和原始對(duì)象會(huì)共享部分?jǐn)?shù)據(jù),這有可能出現(xiàn)數(shù)據(jù)被修改的風(fēng)險(xiǎn)配紫。
所以径密,一般比較推薦使用深拷貝。不要為了一點(diǎn)性能提升使用淺拷貝躺孝。
結(jié)構(gòu)型設(shè)計(jì)模式
結(jié)構(gòu)型模式主要總結(jié)了一些類(lèi)或?qū)ο蠼M合在一起的經(jīng)典結(jié)構(gòu)享扔,這些經(jīng)典結(jié)構(gòu)可以解決特定應(yīng)用場(chǎng)景的問(wèn)題馒过。
代理模式
代理模式在不改變?cè)碱?lèi)接口的條件下坝茎,為原始類(lèi)定義一個(gè)代理類(lèi),主要目的是控制訪問(wèn)暴拄,而非加強(qiáng)功能于个,這是他和裝飾器模式最大的不同氛魁。
一般情況下,我們讓代理類(lèi)和原始類(lèi)實(shí)現(xiàn)同樣的接口厅篓。但是呆盖,如果原始類(lèi)沒(méi)有定義接口,我們可以讓代理類(lèi)繼承原始類(lèi)的方法來(lái)實(shí)現(xiàn)代理模式贷笛。
靜態(tài)代理需要針對(duì)每個(gè)類(lèi)都創(chuàng)建一個(gè)代理類(lèi),增加了維護(hù)和開(kāi)發(fā)成本宙项。
我們可以使用動(dòng)態(tài)代理:不事先為每個(gè)原始類(lèi)編寫(xiě)代理類(lèi)乏苦,而是在運(yùn)行的時(shí)候動(dòng)態(tài)地創(chuàng)建原始類(lèi)對(duì)應(yīng)的代理類(lèi),然后在系統(tǒng)中用代理類(lèi)替換掉原始類(lèi)尤筐。
代理模式常用于開(kāi)發(fā)一些非功能性需求汇荐,比如監(jiān)控、統(tǒng)計(jì)盆繁、鑒權(quán)掀淘、限流、事務(wù)油昂、冪等革娄、日志。
我們可以將這些附加功能與業(yè)務(wù)功能解耦冕碟,放到代理類(lèi)統(tǒng)一處理拦惋。
裝飾器模式
裝飾器模式主要解決繼承關(guān)系過(guò)于復(fù)雜的問(wèn)題,通過(guò)組合來(lái)替代繼承安寺,給原始類(lèi)添加增強(qiáng)功能厕妖。這也是判斷是否該用裝飾器模式的一個(gè)重要依據(jù)。除此之外挑庶,裝飾器模式還有一個(gè)特點(diǎn)言秸,就是可以對(duì)原始類(lèi)嵌套使用多個(gè)裝飾器软能。為了滿(mǎn)足這樣的需求,在設(shè)計(jì)的時(shí)候举畸,裝飾器類(lèi)需要跟原始類(lèi)繼承相同的抽象類(lèi)或者接口查排。
適配器模式
代理模式、裝飾器模式提供的都是和原始類(lèi)相同的接口俱恶,而適配器提供跟原始類(lèi)不同的接口雹嗦。適配器模式是用來(lái)做適配的,它將不兼容的接口轉(zhuǎn)換為可兼容的接口合是,讓原本由于接口不兼容而不能一起工作的類(lèi)可以一起工作了罪。
適配器模式有兩種實(shí)現(xiàn)方式:類(lèi)適配器和對(duì)象適配器。其中聪全,類(lèi)適配器使用繼承關(guān)系來(lái)實(shí)現(xiàn)泊藕,對(duì)象適配器使用組合關(guān)系來(lái)實(shí)現(xiàn)。
適配器模式是一種事后補(bǔ)救策略难礼,用來(lái)補(bǔ)救設(shè)計(jì)上的缺陷娃圆。
門(mén)面模式
門(mén)面模式通過(guò)封裝細(xì)粒度的接口,提供組合各個(gè)細(xì)粒度接口的高層次接口蛾茉,來(lái)提高接口的易用性讼呢,或者解決性能、分布式事務(wù)等問(wèn)題谦炬。
組合模式
組合模式用來(lái)處理樹(shù)形結(jié)構(gòu)數(shù)據(jù)悦屏。
組合模式,將一組對(duì)象組織成樹(shù)形結(jié)構(gòu)键思,將單個(gè)對(duì)象和組合對(duì)象都看作樹(shù)中的節(jié)點(diǎn)础爬,以統(tǒng)一處理邏輯,并且他利用樹(shù)形結(jié)構(gòu)的特點(diǎn)吼鳞,遞歸地處理每個(gè)子樹(shù)看蚜,依次簡(jiǎn)化代碼實(shí)現(xiàn)。
享元模式
享元赔桌,顧名思義就是被共享的單元供炎。
享元模式的意圖是復(fù)用對(duì)象,節(jié)省內(nèi)存纬乍,前提是享元模式是不可變對(duì)象碱茁。
當(dāng)一個(gè)系統(tǒng)中存在大量重復(fù)對(duì)象,我們可以利用享元模式仿贬,將對(duì)象在內(nèi)存中只保留一份實(shí)例纽竣,共多處代碼引用,這樣可以減少內(nèi)存中對(duì)象的數(shù)量,節(jié)省內(nèi)存蜓氨。
對(duì)于相似對(duì)象聋袋,我們也可以將這些對(duì)象中相同的部分(字段),提取出來(lái)設(shè)計(jì)成享元穴吹,讓這些大量相似對(duì)象引用這些享元幽勒。
行為型設(shè)計(jì)模式
行為型設(shè)計(jì)模式主要解決的是“類(lèi)或?qū)ο笾g的交互”問(wèn)題。
觀察者模式
觀察者模式將觀察者和被觀察著解耦港令。
不同應(yīng)用場(chǎng)景下啥容,觀察者模式有著不同的實(shí)現(xiàn)方式:
- 有同步阻塞、以及異步非阻塞方式顷霹;
- 有進(jìn)程內(nèi)方式咪惠,也有跨進(jìn)程方式;
同步阻塞主要是為了代碼解耦淋淀;異步非阻塞除了能解耦代碼外遥昧,還能提高代碼的執(zhí)行效率;
進(jìn)程間的觀察者模式解耦更加徹底朵纷,一般基于消息隊(duì)列實(shí)現(xiàn)炭臭。
模板模式
模板方法模式在一個(gè)方法中定義一個(gè)算法骨架,并將某些步驟推遲到子類(lèi)中實(shí)現(xiàn)袍辞。模板方法模式可以讓子類(lèi)在不改變算法整體接口的情況下鞋仍,重新定義算法中的某些步驟。
模板模式有兩大作用:服用和擴(kuò)展搅吁。其中服用指的是凿试,所有的子類(lèi)可以復(fù)用父類(lèi)中提供的模板方法的代碼。擴(kuò)展指的是似芝,框架通過(guò)模板模式提供功能擴(kuò)展點(diǎn),讓框架用戶(hù)可以在不修改框架源碼的情況下板甘,基于擴(kuò)展點(diǎn)定制化框架的功能党瓮。
策略模式
策略模式定義一組算法類(lèi),將每個(gè)算法分別封裝起來(lái)盐类,讓他們可以互相替換寞奸。策略模式可以使算法的變化獨(dú)立于使用他們的客戶(hù)端。策略模式用來(lái)解耦策略的定義在跳、創(chuàng)建枪萄、使用。
策略類(lèi)的定義包含一個(gè)策略接口和一組實(shí)現(xiàn)這個(gè)接口的策略類(lèi)猫妙。策略的創(chuàng)建由工廠類(lèi)來(lái)完成瓷翻,封裝創(chuàng)建細(xì)節(jié)。策略模式包含一組策略可選,客戶(hù)端代碼選擇使用哪個(gè)策略齐帚,有兩種確定方法:編譯時(shí)靜態(tài)確定和運(yùn)行時(shí)動(dòng)態(tài)確定妒牙。其中,后者是策略模式最典型的應(yīng)用場(chǎng)景对妄。
運(yùn)用策略模式最常見(jiàn)的場(chǎng)景是來(lái)避免冗長(zhǎng)的if-else或switch分支判斷湘今。
職責(zé)鏈模式
在職責(zé)鏈模式中,多個(gè)處理器依次處理同一個(gè)請(qǐng)求剪菱。請(qǐng)求先經(jīng)過(guò)A處理器處理摩瞎,然后傳遞給B處理器,B處理器完成后再傳遞給C處理器孝常,以此類(lèi)推旗们,形成一個(gè)鏈條。鏈條上的每個(gè)處理其各自承擔(dān)其處理職責(zé)茫因。
職責(zé)鏈模式常用在框架開(kāi)發(fā)中蚪拦,用來(lái)實(shí)現(xiàn)過(guò)濾器、攔截器功能冻押,讓框架使用者在不需要修改框架源碼的情況下驰贷,添加新的過(guò)濾、攔截功能洛巢。
迭代器模式
迭代器模式也叫做游標(biāo)模式括袒,它用來(lái)遍歷集合對(duì)象。迭代器模式的主要作用是解耦容器代碼和遍歷代碼稿茉。
在通過(guò)迭代器遍歷集合元素時(shí)锹锰,增刪集合中的元素,可能會(huì)導(dǎo)致某個(gè)元素被重復(fù)遍歷或遍歷不到漓库。解決這個(gè)問(wèn)題有兩種辦法:
1.遍歷的時(shí)候不允許增刪元素恃慧;
2.增刪元素之后讓遍歷報(bào)錯(cuò)。Java語(yǔ)言就是采用這種解決方案渺蒿,fail-fast痢士。
狀態(tài)模式
狀態(tài)模式一般用來(lái)實(shí)現(xiàn)狀態(tài)機(jī),而狀態(tài)機(jī)常用在游戲茂装、工作流引擎等系統(tǒng)開(kāi)發(fā)中怠蹂。
狀態(tài)機(jī)又叫有限狀態(tài)機(jī),它由3個(gè)部分組成:狀態(tài)少态、時(shí)間城侧、動(dòng)作。其中彼妻,事件也被稱(chēng)為轉(zhuǎn)移條件嫌佑。事件觸發(fā)狀態(tài)的轉(zhuǎn)移及動(dòng)作的執(zhí)行豆茫。這里,動(dòng)作不是必須的歧强,可以只轉(zhuǎn)移狀態(tài)澜薄。
狀態(tài)機(jī)有三種實(shí)現(xiàn)方式:
1.分支邏輯法。if-else或switch實(shí)現(xiàn)摊册,直譯每個(gè)狀態(tài)轉(zhuǎn)移肤京。適用于比較簡(jiǎn)單的狀態(tài)機(jī)。
2.查表法茅特。對(duì)于狀態(tài)很多忘分、且轉(zhuǎn)移比較復(fù)雜的狀態(tài)機(jī),通過(guò)二維數(shù)組來(lái)表示狀態(tài)轉(zhuǎn)移圖白修,能極大的提高代碼可讀性以及可維護(hù)性妒峦。
3.利用狀態(tài)模式。對(duì)于狀態(tài)不多兵睛、轉(zhuǎn)移也比較簡(jiǎn)單肯骇,但事件觸發(fā)執(zhí)行的動(dòng)作包含的業(yè)務(wù)邏輯比較復(fù)雜的狀態(tài)機(jī),首選這種方式祖很。
訪問(wèn)者模式
訪問(wèn)者模式允許一個(gè)或多個(gè)操作應(yīng)用到一組對(duì)象上笛丙,設(shè)計(jì)意圖是解耦操作和對(duì)象本身,保持類(lèi)職責(zé)單一假颇、滿(mǎn)足開(kāi)閉原則以及應(yīng)對(duì)代碼的復(fù)雜性胚鸯。
備忘錄模式
備忘錄模式也叫做快照模式,具體來(lái)說(shuō)就是在不違背封裝原則的前提下笨鸡,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài)姜钳,并在該對(duì)象之外保存這個(gè)狀態(tài),以便之后恢復(fù)對(duì)象為先前的狀態(tài)形耗。
這個(gè)模式的定義表達(dá)了兩部分內(nèi)容:一部分是哥桥,存儲(chǔ)副本以便后期恢復(fù);另一部分是激涤,要在不違背封裝原則的前提下泰讽,進(jìn)行對(duì)象的備份和恢復(fù)。
命令模式
命令模式用到最核心的實(shí)現(xiàn)手段昔期,就是將函數(shù)封裝成對(duì)象。
在大部分編程語(yǔ)言中佛玄,函數(shù)式?jīng)]辦法作為參數(shù)傳遞給其他函數(shù)的硼一,也沒(méi)法賦值給變量。借助命令模式梦抢,我們將函數(shù)封裝成對(duì)象般贼,這樣就可以實(shí)現(xiàn)把函數(shù)像對(duì)象一樣使用。
命令模式的主要作用和應(yīng)用場(chǎng)景,使用來(lái)控制命令的執(zhí)行哼蛆,比如蕊梧,異步、延遲腮介、排隊(duì)執(zhí)行命令肥矢、撤銷(xiāo)重做命令、存儲(chǔ)命令叠洗、給命令記錄日志等甘改。
解釋器模式
解釋器模式為某個(gè)語(yǔ)言定義它的語(yǔ)法表示,并定義一個(gè)解釋器用來(lái)處理這個(gè)語(yǔ)法灭抑。
解釋器模式的核心實(shí)現(xiàn)思想是十艾,將語(yǔ)法解析的工作拆分到各個(gè)小類(lèi)中,以此來(lái)避免大而全的解析類(lèi)腾节。一般的做法是忘嫉,將語(yǔ)法規(guī)則拆分一些小的獨(dú)立單元,然后對(duì)每個(gè)單元進(jìn)行解析案腺,最終合并為對(duì)整個(gè)語(yǔ)法規(guī)則的解析庆冕。
中介模式
中介模式的設(shè)計(jì)思想跟中間層很像,通過(guò)引入中介這個(gè)中間層救湖,將一組對(duì)象之間的交互關(guān)系(或者說(shuō)依賴(lài)關(guān)系)從多對(duì)多的網(wǎng)狀關(guān)系轉(zhuǎn)換為一對(duì)多的星狀關(guān)系愧杯。原來(lái)一個(gè)對(duì)象需要跟N個(gè)對(duì)象交互,現(xiàn)在只需要跟一個(gè)中介對(duì)象交互鞋既,從而最小化對(duì)象之間的交互關(guān)系力九,降低代碼復(fù)雜度。