2020重新出發(fā),JAVA高級(jí)主儡,23種設(shè)計(jì)模式

Java的23種設(shè)計(jì)模式全面解析

設(shè)計(jì)模式(Design Pattern)是前輩們對(duì)代碼開發(fā)經(jīng)驗(yàn)的總結(jié)奖唯,是解決特定問題的一系列套路。它不是語法規(guī)定糜值,而是一套用來提高代碼可復(fù)用性丰捷、可維護(hù)性、可讀性寂汇、穩(wěn)健性以及安全性的解決方案病往。

1995 年,GoF(Gang of Four骄瓣,四人組/四人幫)合作出版了《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書停巷,共收錄了 23 種設(shè)計(jì)模式,從此樹立了軟件設(shè)計(jì)模式領(lǐng)域的里程碑榕栏,人稱「GoF設(shè)計(jì)模式」畔勤。

這 23 種設(shè)計(jì)模式的本質(zhì)是面向?qū)ο笤O(shè)計(jì)原則的實(shí)際運(yùn)用,是對(duì)類的封裝性扒磁、繼承性和多態(tài)性庆揪,以及類的關(guān)聯(lián)關(guān)系和組合關(guān)系的充分理解。

當(dāng)然渗磅,軟件設(shè)計(jì)模式只是一個(gè)引導(dǎo)嚷硫,在實(shí)際的軟件開發(fā)中,必須根據(jù)具體的需求來選擇:

  • 對(duì)于簡單的程序始鱼,可能寫一個(gè)簡單的算法要比引入某種設(shè)計(jì)模式更加容易仔掸;
  • 但是對(duì)于大型項(xiàng)目開發(fā)或者框架設(shè)計(jì),用設(shè)計(jì)模式來組織代碼顯然更好医清。

軟件設(shè)計(jì)模式的產(chǎn)生背景

“設(shè)計(jì)模式”這個(gè)術(shù)語最初并不是出現(xiàn)在軟件設(shè)計(jì)中起暮,而是被用于建筑領(lǐng)域的設(shè)計(jì)中。

1977 年,美國著名建筑大師负懦、加利福尼亞大學(xué)伯克利分校環(huán)境結(jié)構(gòu)中心主任克里斯托夫·亞歷山大(Christopher Alexander)在他的著作《建筑模式語言:城鎮(zhèn)筒捺、建筑、構(gòu)造(A Pattern Language: Towns Building Construction)中描述了一些常見的建筑設(shè)計(jì)問題纸厉,并提出了 253 種關(guān)于對(duì)城鎮(zhèn)系吭、鄰里、住宅颗品、花園和房間等進(jìn)行設(shè)計(jì)的基本模式肯尺。

1979 年他的另一部經(jīng)典著作《建筑的永恒之道》(The Timeless Way of Building)進(jìn)一步強(qiáng)化了設(shè)計(jì)模式的思想,為后來的建筑設(shè)計(jì)指明了方向躯枢。

1987 年则吟,肯特·貝克(Kent Beck)和沃德·坎寧安(Ward Cunningham)首先將克里斯托夫·亞歷山大的模式思想應(yīng)用在 Smalltalk 中的圖形用戶接口的生成中,但沒有引起軟件界的關(guān)注锄蹂。

直到 1990 年氓仲,軟件工程界才開始研討設(shè)計(jì)模式的話題,后來召開了多次關(guān)于設(shè)計(jì)模式的研討會(huì)得糜。

1995 年敬扛,艾瑞克·伽馬(ErichGamma)、理査德·海爾姆(Richard Helm)朝抖、拉爾夫·約翰森(Ralph Johnson)舔哪、約翰·威利斯迪斯(John Vlissides)等 4 位作者合作出版了《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》(Design Patterns: Elements of Reusable Object-Oriented Software)一書,在本教程中收錄了 23 個(gè)設(shè)計(jì)模式槽棍,這是設(shè)計(jì)模式領(lǐng)域里程碑的事件,導(dǎo)致了軟件設(shè)計(jì)模式的突破抬驴。這 4 位作者在軟件開發(fā)領(lǐng)域里也以他們的“四人組”(Gang of Four炼七,GoF)匿名著稱。

直到今天布持,狹義的設(shè)計(jì)模式還是本教程中所介紹的 23 種經(jīng)典設(shè)計(jì)模式豌拙。

軟件設(shè)計(jì)模式的概念

軟件設(shè)計(jì)模式(Software Design Pattern),又稱設(shè)計(jì)模式题暖,是一套被反復(fù)使用按傅、多數(shù)人知曉的、經(jīng)過分類編目的胧卤、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。它描述了在軟件設(shè)計(jì)過程中的一些不斷重復(fù)發(fā)生的問題枝誊,以及該問題的解決方案况芒。也就是說,它是解決特定問題的一系列套路叶撒,是前輩們的代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)绝骚,具有一定的普遍性耐版,可以反復(fù)使用。其目的是為了提高代碼的可重用性压汪、代碼的可讀性和代碼的可靠性粪牲。

學(xué)習(xí)設(shè)計(jì)模式的意義

設(shè)計(jì)模式的本質(zhì)是面向?qū)ο笤O(shè)計(jì)原則的實(shí)際運(yùn)用,是對(duì)類的封裝性止剖、繼承性和多態(tài)性以及類的關(guān)聯(lián)關(guān)系和組合關(guān)系的充分理解腺阳。正確使用設(shè)計(jì)模式具有以下優(yōu)點(diǎn)。

  • 可以提高程序員的思維能力滴须、編程能力和設(shè)計(jì)能力舌狗。
  • 使程序設(shè)計(jì)更加標(biāo)準(zhǔn)化、代碼編制更加工程化扔水,使軟件開發(fā)效率大大提高痛侍,從而縮短軟件的開發(fā)周期。
  • 使設(shè)計(jì)的代碼可重用性高魔市、可讀性強(qiáng)主届、可靠性高、靈活性好待德、可維護(hù)性強(qiáng)君丁。

當(dāng)然,軟件設(shè)計(jì)模式只是一個(gè)引導(dǎo)将宪。在具體的軟件幵發(fā)中绘闷,必須根據(jù)設(shè)計(jì)的應(yīng)用系統(tǒng)的特點(diǎn)和要求來恰當(dāng)選擇。對(duì)于簡單的程序開發(fā)较坛,苛能寫一個(gè)簡單的算法要比引入某種設(shè)計(jì)模式更加容易印蔗。但對(duì)大項(xiàng)目的開發(fā)或者框架設(shè)計(jì),用設(shè)計(jì)模式來組織代碼顯然更好丑勤。

軟件設(shè)計(jì)模式的基本要素

軟件設(shè)計(jì)模式使人們可以更加簡單方便地復(fù)用成功的設(shè)計(jì)和體系結(jié)構(gòu)华嘹,它通常包含以下幾個(gè)基本要素:模式名稱、別名法竞、動(dòng)機(jī)耙厚、問題、解決方案、效果、結(jié)構(gòu)岭粤、模式角色逗宁、合作關(guān)系、實(shí)現(xiàn)方法、適用性舵匾、已知應(yīng)用飒炎、例程诡曙、模式擴(kuò)展和相關(guān)模式等臀叙,其中最關(guān)鍵的元素包括以下 4 個(gè)主要部分。

  1. 模式名稱:每一個(gè)模式都有自己的名字价卤,通常用一兩個(gè)詞來描述劝萤,可以根據(jù)模式的問題、特點(diǎn)慎璧、解決方案床嫌、功能和效果來命名。模式名稱(PatternName)有助于我們理解和記憶該模式胸私,也方便我們來討論自己的設(shè)計(jì)厌处。
  2. 問題:問題(Problem)描述了該模式的應(yīng)用環(huán)境,即何時(shí)使用該模式岁疼。它解釋了設(shè)計(jì)問題和問題存在的前因后果阔涉,以及必須滿足的一系列先決條件。
  3. 解決方案:模式問題的解決方案(Solution)包括設(shè)計(jì)的組成成分捷绒、它們之間的相互關(guān)系及各自的職責(zé)和協(xié)作方式瑰排。因?yàn)槟J骄拖褚粋€(gè)模板,可應(yīng)用于多種不同場合暖侨,所以解決方案并不描述一個(gè)特定而具體的設(shè)計(jì)或?qū)崿F(xiàn)椭住,而是提供設(shè)計(jì)問題的抽象描述和怎樣用一個(gè)具有一般意義的元素組合(類或?qū)ο蟮?組合)來解決這個(gè)問題。
  4. 效果:描述了模式的應(yīng)用效果以及使用該模式應(yīng)該權(quán)衡的問題字逗,即模式的優(yōu)缺點(diǎn)京郑。主要是對(duì)時(shí)間和空間的衡量,以及該模式對(duì)系統(tǒng)的靈活性葫掉、擴(kuò)充性傻挂、可移植性的影響,也考慮其實(shí)現(xiàn)問題挖息。顯式地列出這些效果(Consequence)對(duì)理解和評(píng)價(jià)這些模式有很大的幫助。

23 種設(shè)計(jì)模式的分類和功能

設(shè)計(jì)模式有兩種分類方法兽肤,即根據(jù)模式的目的來分和根據(jù)模式的作用的范圍來分套腹。

根據(jù)目的來分

根據(jù)模式是用來完成什么工作來劃分,這種方式可分為創(chuàng)建型模式资铡、結(jié)構(gòu)型模式和行為型模式 3 種电禀。

  1. 創(chuàng)建型模式:用于描述“怎樣創(chuàng)建對(duì)象”,主要特點(diǎn)是“將對(duì)象的創(chuàng)建與使用分離”笤休。這樣可以降低系統(tǒng)的耦合度尖飞,使用者不需要關(guān)注對(duì)象的創(chuàng)建細(xì)節(jié),對(duì)象的創(chuàng)建由相關(guān)的工廠來完成。就像我們?nèi)ド虉鲑徺I商品時(shí)政基,不需要知道商品是怎么生產(chǎn)出來一樣贞铣,因?yàn)樗鼈冇蓪iT的廠商生產(chǎn)。
    • 提供了單例沮明、原型辕坝、工廠方法、抽象工廠荐健、建造者等 5 種創(chuàng)建型模式酱畅。
  2. 結(jié)構(gòu)型模式:用于描述如何將類或?qū)ο蟀茨撤N布局組成更大的結(jié)構(gòu),它分為類結(jié)構(gòu)型模式和對(duì)象結(jié)構(gòu)型模式江场,前者采用繼承機(jī)制來組織接口和類纺酸,后者釆用組合或聚合來組合對(duì)象。由于組合關(guān)系或聚合關(guān)系比繼承關(guān)系耦合度低址否,滿足“合成復(fù)用原則”餐蔬,所以對(duì)象結(jié)構(gòu)型模式比類結(jié)構(gòu)型模式具有更大的靈活性。
    • 提供了代理在张、適配器用含、橋接、裝飾帮匾、外觀啄骇、享元、組合等 7 種結(jié)構(gòu)型模式瘟斜。
  3. 行為型模式:用于描述類或?qū)ο笾g怎樣相互協(xié)作共同完成單個(gè)對(duì)象都無法單獨(dú)完成的任務(wù)缸夹,以及怎樣分配職責(zé)。行為型模式分為類行為模式和對(duì)象行為模式螺句,前者采用繼承機(jī)制來在類間分派行為虽惭,后者采用組合或聚合在對(duì)象間分配行為。由于組合關(guān)系或聚合關(guān)系比繼承關(guān)系耦合度低蛇尚,滿足“合成復(fù)用原則”芽唇,所以對(duì)象行為模式比類行為模式具有更大的靈活性。
    • 提供了模板方法取劫、策略匆笤、命令、職責(zé)鏈谱邪、狀態(tài)炮捧、觀察者、中介者惦银、迭代器咆课、訪問者末誓、備忘錄、解釋器等 11 種行為型模式书蚪。

根據(jù)作用范圍來分

根據(jù)模式是主要用于類上還是主要用于對(duì)象上來分喇澡,這種方式可分為類模式和對(duì)象模式兩種。

  1. 類模式:用于處理類與子類之間的關(guān)系善炫,這些關(guān)系通過繼承來建立撩幽,是靜態(tài)的,在編譯時(shí)刻便確定下來了箩艺。工廠方法窜醉、(類)適配器、模板方法艺谆、解釋器屬于該模式榨惰。
  2. 對(duì)象模式:用于處理對(duì)象之間的關(guān)系,這些關(guān)系可以通過組合或聚合來實(shí)現(xiàn)静汤,在運(yùn)行時(shí)刻是可以變化的琅催,更具動(dòng)態(tài)性。除了以上 4 種虫给,其他的都是對(duì)象模式藤抡。

GoF的23種設(shè)計(jì)模式的功能

前面說明了 GoF 的 23 種設(shè)計(jì)模式的分類,現(xiàn)在對(duì)各個(gè)模式的功能進(jìn)行介紹抹估。

  1. 單例(Singleton)模式:某個(gè)類只能生成一個(gè)實(shí)例缠黍,該類提供了一個(gè)全局訪問點(diǎn)供外部獲取該實(shí)例,其拓展是有限多例模式药蜻。
  2. 原型(Prototype)模式:將一個(gè)對(duì)象作為原型瓷式,通過對(duì)其進(jìn)行復(fù)制而克隆出多個(gè)和原型類似的新實(shí)例。
  3. 工廠方法(Factory Method)模式:定義一個(gè)用于創(chuàng)建產(chǎn)品的接口语泽,由子類決定生產(chǎn)什么產(chǎn)品贸典。
  4. 抽象工廠(AbstractFactory)模式:提供一個(gè)創(chuàng)建產(chǎn)品族的接口,其每個(gè)子類可以生產(chǎn)一系列相關(guān)的產(chǎn)品踱卵。
  5. 建造者(Builder)模式:將一個(gè)復(fù)雜對(duì)象分解成多個(gè)相對(duì)簡單的部分廊驼,然后根據(jù)不同需要分別創(chuàng)建它們,最后構(gòu)建成該復(fù)雜對(duì)象惋砂。
  6. 代理(Proxy)模式:為某對(duì)象提供一種代理以控制對(duì)該對(duì)象的訪問妒挎。即客戶端通過代理間接地訪問該對(duì)象,從而限制班利、增強(qiáng)或修改該對(duì)象的一些特性。
  7. 適配器(Adapter)模式:將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口榨呆,使得原本由于接口不兼容而不能一起工作的那些類能一起工作罗标。
  8. 橋接(Bridge)模式:將抽象與實(shí)現(xiàn)分離庸队,使它們可以獨(dú)立變化。它是用組合關(guān)系代替繼承關(guān)系來實(shí)現(xiàn)闯割,從而降低了抽象和實(shí)現(xiàn)這兩個(gè)可變維度的耦合度彻消。
  9. 裝飾(Decorator)模式:動(dòng)態(tài)的給對(duì)象增加一些職責(zé),即增加其額外的功能宙拉。
  10. 外觀(Facade)模式:為多個(gè)復(fù)雜的子系統(tǒng)提供一個(gè)一致的接口宾尚,使這些子系統(tǒng)更加容易被訪問。
  11. 享元(Flyweight)模式:運(yùn)用共享技術(shù)來有效地支持大量細(xì)粒度對(duì)象的復(fù)用谢澈。
  12. 組合(Composite)模式:將對(duì)象組合成樹狀層次結(jié)構(gòu)煌贴,使用戶對(duì)單個(gè)對(duì)象和組合對(duì)象具有一致的訪問性。
  13. 模板方法(TemplateMethod)模式:定義一個(gè)操作中的算法骨架锥忿,而將算法的一些步驟延遲到子類中牛郑,使得子類可以不改變?cè)撍惴ńY(jié)構(gòu)的情況下重定義該算法的某些特定步驟。
  14. 策略(Strategy)模式:定義了一系列算法敬鬓,并將每個(gè)算法封裝起來淹朋,使它們可以相互替換,且算法的改變不會(huì)影響使用算法的客戶钉答。
  15. 命令(Command)模式:將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象础芍,使發(fā)出請(qǐng)求的責(zé)任和執(zhí)行請(qǐng)求的責(zé)任分割開。
  16. 職責(zé)鏈(Chain of Responsibility)模式:把請(qǐng)求從鏈中的一個(gè)對(duì)象傳到下一個(gè)對(duì)象数尿,直到請(qǐng)求被響應(yīng)為止仑性。通過這種方式去除對(duì)象之間的耦合。
  17. 狀態(tài)(State)模式:允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)發(fā)生改變時(shí)改變其行為能力砌创。
  18. 觀察者(Observer)模式:多個(gè)對(duì)象間存在一對(duì)多關(guān)系虏缸,當(dāng)一個(gè)對(duì)象發(fā)生改變時(shí),把這種改變通知給其他多個(gè)對(duì)象嫩实,從而影響其他對(duì)象的行為刽辙。
  19. 中介者(Mediator)模式:定義一個(gè)中介對(duì)象來簡化原有對(duì)象之間的交互關(guān)系,降低系統(tǒng)中對(duì)象間的耦合度甲献,使原有對(duì)象之間不必相互了解宰缤。
  20. 迭代器(Iterator)模式:提供一種方法來順序訪問聚合對(duì)象中的一系列數(shù)據(jù),而不暴露聚合對(duì)象的內(nèi)部表示晃洒。
  21. 訪問者(Visitor)模式:在不改變集合元素的前提下慨灭,為一個(gè)集合中的每個(gè)元素提供多種訪問方式,即每個(gè)元素有多個(gè)訪問者對(duì)象訪問球及。
  22. 備忘錄(Memento)模式:在不破壞封裝性的前提下氧骤,獲取并保存一個(gè)對(duì)象的內(nèi)部狀態(tài),以便以后恢復(fù)它吃引。
  23. 解釋器(Interpreter)模式:提供如何定義語言的文法筹陵,以及對(duì)語言句子的解釋方法刽锤,即解釋器。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末朦佩,一起剝皮案震驚了整個(gè)濱河市并思,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌语稠,老刑警劉巖宋彼,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異仙畦,居然都是意外死亡输涕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門议泵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來占贫,“玉大人,你說我怎么就攤上這事先口⌒桶拢” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵碉京,是天一觀的道長厢汹。 經(jīng)常有香客問我,道長谐宙,這世上最難降的妖魔是什么烫葬? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮凡蜻,結(jié)果婚禮上搭综,老公的妹妹穿的比我還像新娘。我一直安慰自己划栓,他們只是感情好兑巾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著忠荞,像睡著了一般蒋歌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上委煤,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天堂油,我揣著相機(jī)與錄音,去河邊找鬼碧绞。 笑死府框,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的讥邻。 我是一名探鬼主播迫靖,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼癣诱,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了袜香?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤鲫惶,失蹤者是張志新(化名)和其女友劉穎蜈首,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體欠母,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡欢策,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赏淌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片踩寇。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖六水,靈堂內(nèi)的尸體忽然破棺而出俺孙,到底是詐尸還是另有隱情,我是刑警寧澤掷贾,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布睛榄,位于F島的核電站,受9級(jí)特大地震影響想帅,放射性物質(zhì)發(fā)生泄漏场靴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一港准、第九天 我趴在偏房一處隱蔽的房頂上張望旨剥。 院中可真熱鬧,春花似錦浅缸、人聲如沸轨帜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阵谚。三九已至,卻和暖如春烟具,著一層夾襖步出監(jiān)牢的瞬間梢什,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工朝聋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嗡午,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓冀痕,卻偏偏與公主長得像荔睹,于是被迫代替她去往敵國和親狸演。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345