Where am I
00 引言
000 什么是設(shè)計(jì)模式个绍?
每一個(gè)模式描述了一個(gè)在我們周圍不斷重復(fù)發(fā)生的問題, 以及該問題的解決方案的核心。這樣,你就能一次又一次地使用該方案而不必做重復(fù)勞動(dòng)屡贺。
- 重復(fù)發(fā)生的問題
- 問題解決方案的核心
- 復(fù)用成熟的解決方案,減少重復(fù)的勞動(dòng)
001 如何詳細(xì)描述某一設(shè)計(jì)模式锌杀?
描述角度 | 說明 |
---|---|
意圖 | 通過什么方法解決什么樣的特定設(shè)計(jì)問題 |
別名 | 模式的其他名稱 |
動(dòng)機(jī) | 實(shí)現(xiàn)意圖的基礎(chǔ)甩栈、基本原理,說明一個(gè)模式中的類抛丽、對(duì)象如何解決特定的設(shè)計(jì)問題 |
適用性 | 什么情況下可以使用該設(shè)計(jì)模式?該設(shè)計(jì)模式可以用來改良哪些不良設(shè)計(jì)饰豺?我們?cè)鯓幼R(shí)別這些情況亿鲜? |
參與者 | 指設(shè)計(jì)模式中的類或?qū)ο笠约八鼈兏髯缘穆氊?zé) |
協(xié)作 | 模式的參與者怎樣協(xié)作以實(shí)現(xiàn)它們的職責(zé) |
結(jié)構(gòu) | 采用基于對(duì)象建模技術(shù)的表示法對(duì)模式中的類進(jìn)行圖形描述 |
效果 | 模式怎樣支持它的目標(biāo)?使用模式的效果和所需做的權(quán)衡取舍冤吨?系統(tǒng)結(jié)構(gòu)的哪些方面可以獨(dú)立改變蒿柳? |
實(shí)現(xiàn) | 實(shí)現(xiàn)模式時(shí)需要知道的一些提示、技術(shù)要點(diǎn)及應(yīng)避免的缺陷漩蟆,以及是否存在某些特定于實(shí)現(xiàn)語言的問題 |
已知應(yīng)用 | 實(shí)際系統(tǒng)中發(fā)現(xiàn)的模式的例子垒探。每個(gè)模式至少包括了兩個(gè)不同領(lǐng)域的實(shí)例 |
代碼示例 | 用來說明怎樣實(shí)現(xiàn)該模式的代碼片段 |
相關(guān)模式 | 與這個(gè)模式緊密相關(guān)的模式有哪些?其間重要的不同之處是什么怠李?這個(gè)模式應(yīng)與哪些其他模式一起使用圾叼? |
002 設(shè)計(jì)模式分類
分類準(zhǔn)則
分類準(zhǔn)則 | 類型 | 類型描述 |
---|---|---|
目的 | 創(chuàng)建型 | 與對(duì)象的創(chuàng)建有關(guān) |
目的 | 結(jié)構(gòu)型 | 處理類或?qū)ο蟮慕M合 |
目的 | 行為型 | 對(duì)類或?qū)ο笤鯓咏换ズ驮鯓臃峙渎氊?zé)進(jìn)行描述 |
范圍 | 類 | 處理類和子類之間的關(guān)系,這些關(guān)系通過繼承建立捺癞,是靜態(tài)的夷蚊,在編譯時(shí)刻便確定下來了 |
范圍 | 對(duì)象 | 處理對(duì)象間的關(guān)系夭苗,這些關(guān)系在運(yùn)行時(shí)刻是可以變化的添瓷,更具動(dòng)態(tài)性 |
分類結(jié)果
類型名稱 | 類型描述 | 具體設(shè)計(jì)模式 | 設(shè)計(jì)模式描述 |
---|---|---|---|
創(chuàng)建型類模式 | 將對(duì)象的部分創(chuàng)建工作延遲到子類 | ||
工廠方法模式 | 定義一個(gè)用于創(chuàng)建對(duì)象的接口炎滞,讓子類決定將哪一個(gè)類實(shí)例化 | ||
創(chuàng)建型對(duì)象模式 | 將對(duì)象的部分創(chuàng)建工作延遲到另一個(gè)對(duì)象 | ||
抽象工廠模式 | 提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口粗悯,而無需指定它們具體的類 | ||
建造者模式 | 將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離咐低,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示 | ||
原型模式 | 用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這個(gè)原型來創(chuàng)建新的對(duì)象 | ||
單例模式 | 保證一個(gè)類僅有一個(gè)實(shí)例炎功,并提供一個(gè)訪問它的全局訪問點(diǎn) | ||
結(jié)構(gòu)型類模式 | 使用繼承機(jī)制來組合類 | ||
適配器模式(類) | 將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口栓拜。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作 | ||
結(jié)構(gòu)型對(duì)象模式 | 描述了對(duì)象的組裝方式 | ||
適配器模式(對(duì)象) | 將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作 | ||
橋接模式 | 將抽象部分與它的實(shí)現(xiàn)部分分離呀邢,使它們都可以獨(dú)立地變化 | ||
組合模式 | 將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)洒沦。Composite使得客戶對(duì)單個(gè)對(duì)象和復(fù)合對(duì)象的使用具有一致性 | ||
裝飾器模式 | 動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就擴(kuò)展功能而言驼鹅,Decorator模式比生成子類方式更為靈活 | ||
外觀模式 | 為子系統(tǒng)中的一組接口提供一個(gè)一致的界面微谓,F(xiàn)acade模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用 | ||
享元模式 | 運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象 | ||
代理模式 | 為其他對(duì)象提供一個(gè)代理以控制對(duì)這個(gè)對(duì)象的訪問 | ||
類行為型 | 使用繼承描述算法和控制流 | ||
解釋器模式 | 給定一個(gè)語言,定義它的文法的一種表示输钩,并定義一個(gè)解釋器,該解釋器使用該表示來解釋語言中的句子 | ||
模板方法模式 | 定義一個(gè)操作中的算法的骨架豺型,而將一些步驟延遲到子類中。TemplateMethod使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟 | ||
對(duì)象行為型 | 描述一組對(duì)象怎樣協(xié)作完成單個(gè)對(duì)象所無法完成的任務(wù) | ||
職責(zé)鏈模式 | 為解除請(qǐng)求的發(fā)送者和接收者之間耦合买乃,而使多個(gè)對(duì)象都有機(jī)會(huì)處理這個(gè)請(qǐng)求姻氨。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求剪验,直到有一個(gè)對(duì)象處理它 | ||
命令模式 | 將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象肴焊,從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可取消的操作 | ||
迭代器模式 | 提供一種方法順序訪問一個(gè)聚合對(duì)象中各個(gè)元素,而又不需暴露該對(duì)象的內(nèi)部表示 | ||
中介者模式 | 用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互功戚。中介者使各對(duì)象不需要顯式地相互引用娶眷,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互 | ||
備忘錄模式 | 在不破壞封裝性的前提下啸臀,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài)届宠,并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到保存的狀態(tài) | ||
觀察者模式 | 定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,以便當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并自動(dòng)刷新 | ||
狀態(tài)模式 | 允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為乘粒。對(duì)象看起來似乎修改了它所屬的類 | ||
策略模式 | 定義一系列的算法,把它們一個(gè)個(gè)封裝起來,并且使它們可相互替換豌注。本模式使得算法的變化可獨(dú)立于使用它的客戶 | ||
訪問者模式 | 表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作 |
003 常見導(dǎo)致重新設(shè)計(jì)的場(chǎng)景
場(chǎng)景 | 場(chǎng)景描述 | 解決方案 |
---|---|---|
通過顯式地指定一個(gè)類來創(chuàng)建對(duì)象 | 在創(chuàng)建對(duì)象時(shí)指定類名將使你受特定實(shí)現(xiàn)的約束而不是特定接口的約束灯萍。這會(huì)使未來的變化更復(fù)雜轧铁。要避免這種情況,應(yīng)該間接地創(chuàng)建對(duì)象 | 抽象工廠模式 工廠方法模式 原型模式 |
對(duì)特殊操作的依賴 | 當(dāng)你為請(qǐng)求指定一個(gè)特殊的操作時(shí)旦棉,完成該請(qǐng)求的方式就固定下來了齿风。為避免把請(qǐng)求代碼寫死,你將可以在編譯時(shí)刻或運(yùn)行時(shí)刻很方便地改變響應(yīng)請(qǐng)求的方法 | 職責(zé)鏈模式 命令模式 |
對(duì)硬件和軟件平臺(tái)的依賴 | 外部的操作系統(tǒng)接口和應(yīng)用編程接口(API)在不同的軟硬件平臺(tái)上是不同的绑洛。依賴于特定平臺(tái)的軟件將很難移植到其他平臺(tái)上聂宾,甚至都很難跟上本地平臺(tái)的更新。所以設(shè)計(jì)系統(tǒng)時(shí)限制其平臺(tái)相關(guān)性就很重要了 | 抽象工廠模式 橋接模式 |
對(duì)對(duì)象表示或?qū)崿F(xiàn)的依賴 | 知道對(duì)象怎樣表示诊笤、保存系谐、定位或?qū)崿F(xiàn)的客戶在對(duì)象發(fā)生變化時(shí)可能也需要變化。對(duì)客戶隱藏這些信息能阻止連鎖變化 | 抽象工廠模式 橋接模式 備忘錄模式 代理模式 |
算法依賴算法在開發(fā)和復(fù)用時(shí)常常被擴(kuò)展、優(yōu)化和替代 | 依賴于某個(gè)特定算法的對(duì)象在算法發(fā)生變化時(shí)不得不變化纪他。因此有可能發(fā)生變化的算法應(yīng)該被孤立起來 | 建造者模式 迭代器模式 策略模式 模板方法模式 訪問者模式 |
緊耦合緊耦合的類很難獨(dú)立地被復(fù)用鄙煤,因?yàn)樗鼈兪腔ハ嘁蕾嚨?/td> | 緊耦合產(chǎn)生單塊的系統(tǒng),要改變或刪掉一個(gè)類茶袒,你必須理解和改變其他許多類梯刚。這樣的系統(tǒng)是一個(gè)很難學(xué)習(xí)、移植和維護(hù)的密集體薪寓。 松散耦合提高了一個(gè)類本身被復(fù)用的可能性亡资,并且系統(tǒng)更易于學(xué)習(xí)、移植向叉、修改和擴(kuò)展锥腻。設(shè)計(jì)模式使用抽象耦合和分層技術(shù)來提高系統(tǒng)的松散耦合性 | 抽象工廠模式 命令模式 外觀模式 中介者模式 觀察者模式 職責(zé)鏈模式 |
通過生成子類來擴(kuò)充功能通常很難通過定義子類來定制對(duì)象 | 每一個(gè)新類都有固定的實(shí)現(xiàn)開銷(初始化、終止處理等)母谎。定義子類還需要對(duì)父類有深入的了解瘦黑。如,重定義一個(gè)操作可能需要重定義其他操作奇唤。一個(gè)被重定義的操作可能需要調(diào)用繼承下來的操作幸斥。并且子類方法會(huì)導(dǎo)致類爆炸,因?yàn)榧词箤?duì)于一個(gè)簡(jiǎn)單的擴(kuò)充咬扇,你也不得不引入許多新的子類甲葬。 一般的對(duì)象組合技術(shù)和具體的委托技術(shù),是繼承之外組合對(duì)象行為的另一種靈活方法懈贺。新的功能可以通過以新的方式組合已有對(duì)象经窖,而不是通過定義已存在類的子類的方式加到應(yīng)用中去。另一方面隅居,過多使用對(duì)象組合會(huì)使設(shè)計(jì)難于理解钠至。許多設(shè)計(jì)模式產(chǎn)生的設(shè)計(jì)中葛虐,你可以定義一個(gè)子類胎源,且將它的實(shí)例和已存在實(shí)例進(jìn)行組合來引入定制的功能 | 橋接模式 職責(zé)鏈模式 組合模式 裝飾器模式 觀察者模式 策略模式 |
不能方便地對(duì)類進(jìn)行修改有時(shí)你不得不改變一個(gè)難以修改的類 | 也許你需要源代碼而又沒有(對(duì)于商業(yè)類庫(kù)就有這種情況),或者可能對(duì)類的任何改變會(huì)要求修改許多已存在的其他子類屿脐。設(shè)計(jì)模式提供在這些情況下對(duì)類進(jìn)行修改的方法 | 適配器模式 裝飾器模式 訪問者模式 |
004 使用設(shè)計(jì)模式存在的缺陷
設(shè)計(jì)模式引入額外的間接層次獲得靈活性和可變性的同時(shí)涕蚤,也使設(shè)計(jì)變得更復(fù)雜或犧牲了一定的性能。一個(gè)設(shè)計(jì)模式只有當(dāng)它提供的靈活性是真正需要的時(shí)候的诵,才有必要使用万栅。