第10講:軟件設(shè)計(jì)模式_第1頁
第10講:軟件設(shè)計(jì)模式_第2頁
第10講:軟件設(shè)計(jì)模式_第3頁
第10講:軟件設(shè)計(jì)模式_第4頁
第10講:軟件設(shè)計(jì)模式_第5頁
已閱讀5頁,還剩223頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、哈爾濱工業(yè)大學(xué)計(jì)算機(jī)學(xué)院唐好選Email:主要內(nèi)容主要內(nèi)容p軟件設(shè)計(jì)模式基礎(chǔ)p創(chuàng)建型模式p結(jié)構(gòu)型模式p行為型模式軟件設(shè)計(jì)模式基礎(chǔ)p 廣義講,軟件設(shè)計(jì)模式是可解決某類軟件問題并能重復(fù)使用的軟件設(shè)計(jì)方案p 狹義講,軟件設(shè)計(jì)模式是“對(duì)特定場景下解決一般設(shè)計(jì)問題的類和相互通信對(duì)象的描述”。是在類和對(duì)象的層次描述的可重復(fù)使用的軟件設(shè)計(jì)問題的解決方案p 模式體現(xiàn)程序整體構(gòu)思,也會(huì)出現(xiàn)在分析或概要設(shè)計(jì)階段 p 模式的核心思想:通過增加抽象層,把變化部分從那些不變部分里分離出來設(shè)計(jì)模式的概念設(shè)計(jì)模式的概念(1)模式名稱(Pattern Name)(2)問題(Problem):描述應(yīng)在何時(shí)使用模式。解釋了設(shè)計(jì)問

2、題和問題存在的前因后果,可能還描述模式必須滿足的先決條件(3)解決方案(Solution):描述設(shè)計(jì)的組成成分、相互關(guān)系及各自的職責(zé)和協(xié)作方式。模式就像一個(gè)模板,可用于多種場合,所以解決方案并不描述一個(gè)具體的設(shè)計(jì)或?qū)崿F(xiàn),而是提供設(shè)計(jì)問題的抽象描述和解決問題所采用的元素組合(類和對(duì)象)(4)效果(consequences ):描述模式的應(yīng)用效果及使用模式應(yīng)權(quán)衡的問題模式的基本要素模式的基本要素p模式名和分類p意圖:設(shè)計(jì)模式是做什么的?它的基本原理和意圖是什么?它解決的是什么樣的特定設(shè)計(jì)問題?p動(dòng)機(jī):說明一個(gè)設(shè)計(jì)問題以及如何用模式中的類、對(duì)象來解決該問題的特定情景p適用性:什么情況下可以使用該設(shè)計(jì)

3、模式?該模式可用來改進(jìn)哪些不良設(shè)計(jì)?如何識(shí)別這些情況?p結(jié)構(gòu):采用對(duì)象建模技術(shù)對(duì)模式中的類進(jìn)行描述如何描述設(shè)計(jì)模式如何描述設(shè)計(jì)模式p參與者:指設(shè)計(jì)模式中的類 和/或 對(duì)象以及它們各自的職責(zé)p協(xié)作:模式的參與者如何協(xié)作并實(shí)現(xiàn)其職責(zé)p效果:模式如何支持其目標(biāo)?使用模式的效果和所需做的權(quán)衡取舍?系統(tǒng)結(jié)構(gòu)的哪些方面可以獨(dú)立改變?p實(shí)現(xiàn):實(shí)現(xiàn)模式時(shí)需了解的一些技術(shù)要點(diǎn)及應(yīng)避免的缺陷,以及是否存在某些特定于實(shí)現(xiàn)語言的問題p代碼示例:說明怎樣實(shí)現(xiàn)該模式的代碼片段p相關(guān)模式:與這個(gè)模式緊密相關(guān)的模式有哪些?其不同之處是什么?這個(gè)模式應(yīng)與哪些其他模式一起使用?描述設(shè)計(jì)模式(續(xù))描述設(shè)計(jì)模式(續(xù))設(shè)計(jì)模式的原則設(shè)

4、計(jì)模式的原則p 開-閉原則(Open Closed Principal)p 單一職責(zé)原則(Single Responsibility Principle )p 里氏替換原則(Liskov Substitution Principle )p 依賴倒置原則(Dependence Inversion Principle )p 接口隔離原則(Interface Segregation Principle )p 迪米特法則(最少知道原則)(Least Knowledge Principle)p 設(shè)計(jì)模式就是實(shí)現(xiàn)了上述原則,從而達(dá)到代碼復(fù)用、增加可維護(hù)性的目的p 定義:對(duì)擴(kuò)展是開放的,對(duì)修改是關(guān)閉的。開發(fā)

5、軟件時(shí),可對(duì)其功能進(jìn)行擴(kuò)展(開放),進(jìn)行擴(kuò)展時(shí),不需要對(duì)原程序進(jìn)行修改(關(guān)閉)p 優(yōu)點(diǎn)p 軟件可用性較靈活,可對(duì)完成后的軟件進(jìn)行擴(kuò)展,加入新功能,可通過不斷增加新模塊滿足不斷變化的新需求p 由于不修改軟件原有的模塊,不用擔(dān)心軟件的穩(wěn)定性開閉原則(開閉原則(OCP)u就一個(gè)類而言,應(yīng)該僅有一個(gè)引起它變化的原因。每一個(gè)引起類變化的原因就是一個(gè)職責(zé),當(dāng)類具有多職責(zé)時(shí),應(yīng)把多余職責(zé)分離出去,分別創(chuàng)建一些類來完成每一個(gè)職責(zé)u每一個(gè)職責(zé)都是一個(gè)變化的軸線,當(dāng)需求變化時(shí)會(huì)反映為類的職責(zé)的變化舉例: interface Modem public void dial(String pno); public vo

6、id hangup(); public send(char c); public char recv(); Modem類有兩個(gè)職責(zé):連接管理和數(shù)據(jù)通信,應(yīng)將它們分離單一職責(zé)原則(單一職責(zé)原則(SRP)interface ModemCon public void dial(String pno); public void hangup(); interface ModemCom public send(char c); public char recv(); 里氏替換原則(里氏替換原則(LSP)p 里氏替換原則是繼承復(fù)用的基石,只有當(dāng)派生類可以替換掉其基類,而軟件功能不受影響時(shí),基類才能真正被復(fù)

7、用,派生類也才能夠在基類的基礎(chǔ)上增加新的行為p LSP本質(zhì):在同一個(gè)繼承體系中的對(duì)象應(yīng)該有共同的行為特征p 例子:企鵝是鳥嗎? 生物學(xué):企鵝屬于鳥類 LSP原則:企鵝不屬于鳥類,因?yàn)槠簌Z不會(huì)“飛”p 違反LSP的后果:有可能需要修改客戶代碼依賴倒置原則(依賴倒置原則(DIP)p 高層模塊不應(yīng)依賴于低層模塊,二者都依賴于抽象;抽象不應(yīng)該依賴細(xì)節(jié);細(xì)節(jié)應(yīng)該依賴抽象p 高層模塊只應(yīng)該包含重要的業(yè)務(wù)模型和策略選擇,低層模塊則是不同業(yè)務(wù)和策略的實(shí)現(xiàn)p 高層抽象不依賴高層和低層模塊的具體實(shí)現(xiàn),最多只依賴于低層的抽象p 低層抽象和實(shí)現(xiàn)也只依賴于高層抽象 p 輔助原則 p 任何變量都不應(yīng)該持有一個(gè)指向具體類的

8、引用p 任何類都不應(yīng)該從具體類派生p 任何方法都不應(yīng)覆蓋其任何基類中已經(jīng)實(shí)現(xiàn)了的方法 接口隔離原則(接口隔離原則(ISP)p使用多個(gè)專門的接口比使用單一的總接口要好 p一個(gè)類對(duì)另一個(gè)類的依賴性應(yīng)當(dāng)建立在最小的接口上 p一個(gè)接口代表一個(gè)角色,不應(yīng)當(dāng)將不同的角色都交給一個(gè)接口,沒有關(guān)系的接口合并在一起,形成一個(gè)臃腫的大接口,這是對(duì)角色和接口的污染p“不應(yīng)該強(qiáng)迫客戶依賴于它們不用的方法。接口屬于客戶,不屬于它所在的類層次結(jié)構(gòu)?!睋Q句話說,不要強(qiáng)迫客戶使用它們不用的方法,如果強(qiáng)迫用戶使用它們不用的方法,那么這些客戶就會(huì)面臨由于這些不使用方法的改變所帶來的改變最少知道原則(最少知道原則(LKP)p 一個(gè)

9、軟件實(shí)體應(yīng)當(dāng)盡可能少地與其他實(shí)體發(fā)生相互作用p 每一個(gè)軟件單位對(duì)其他單位都只有最少的知識(shí),而且局限于那些與本單位密切相關(guān)的軟件單位p 迪米特法則的初衷在于降低類之間的耦合。由于每個(gè)類盡量減少對(duì)其他類的依賴,因此,很容易使得系統(tǒng)的功能模塊功能獨(dú)立,相互之間不存在(或很少有)依賴關(guān)系 p在設(shè)計(jì)模式經(jīng)典著作GOF95中,設(shè)計(jì)模式從應(yīng)用的角度被分為三大類型 p創(chuàng)建型模式/結(jié)構(gòu)型模式/行為型模式p根據(jù)模式應(yīng)用范圍分,模式可應(yīng)用于類,也可應(yīng)用于對(duì)象p類模式:處理類和子類之間的關(guān)系,這些關(guān)系通過繼承建立,是靜態(tài)的,在編譯時(shí)刻便確定下來了p對(duì)象模式:處理對(duì)象間的關(guān)系,這些關(guān)系在運(yùn)行時(shí)刻是可以變化的,更具動(dòng)態(tài)性

10、p從某種意義上來說,幾乎所有模式都使用繼承機(jī)制,所以“類模式”只指那些集中于處理類間關(guān)系的模式,而大部分模式都屬于對(duì)象模式的范疇設(shè)計(jì)模式的類型設(shè)計(jì)模式的類型p 創(chuàng)建型設(shè)計(jì)模式是用來創(chuàng)建對(duì)象的模式,該類模式抽象了實(shí)例化過程 p 工廠模式:父類負(fù)責(zé)定義創(chuàng)建對(duì)象的公共接口,而子類則負(fù)責(zé)生成具體對(duì)象,將類的實(shí)例化操作延遲到子類中完成p 抽象工廠模式:為一個(gè)產(chǎn)品族提供統(tǒng)一的創(chuàng)建接口。當(dāng)需要這個(gè)產(chǎn)品族的某一系列的時(shí)候,可以從抽象工廠中選出相應(yīng)的系列創(chuàng)建一個(gè)具體的工廠類p 單件(Singleton)模式:保證一個(gè)類有且僅有一個(gè)實(shí)例,提供一個(gè)全局訪問點(diǎn)創(chuàng)建型設(shè)計(jì)模式創(chuàng)建型設(shè)計(jì)模式創(chuàng)建型設(shè)計(jì)模式創(chuàng)建型設(shè)計(jì)模式p

11、 生成器(Builder)模式:將復(fù)雜對(duì)象創(chuàng)建與表示分離,同樣的創(chuàng)建過程可創(chuàng)建不同的表示。允許用戶通過指定復(fù)雜對(duì)象類型和內(nèi)容來創(chuàng)建對(duì)象,用戶不需要知道對(duì)象內(nèi)部的具體構(gòu)建細(xì)節(jié)p 原型(Prototype)模式:通過“復(fù)制”一個(gè)已經(jīng)存在的實(shí)例來返回新的實(shí)例(不新建實(shí)例)。被復(fù)制的實(shí)例就是“原型”,這個(gè)原型是可定制的。原型模式多用于創(chuàng)建復(fù)雜的或者耗時(shí)的實(shí)例,因?yàn)檫@種情況下,復(fù)制一個(gè)已經(jīng)存在的實(shí)例使程序運(yùn)行更高效p 結(jié)構(gòu)型模式討論的是類和對(duì)象的結(jié)構(gòu),它采用繼承機(jī)制來組合接口或?qū)崿F(xiàn)(類結(jié)構(gòu)型模式),或者通過組合一些對(duì)象來實(shí)現(xiàn)新的功能(對(duì)象結(jié)構(gòu)型模式)p 組合(Composite)模式:定義一個(gè)接口,使之

12、用于單一對(duì)象,也可以應(yīng)用于多個(gè)單一對(duì)象組成的對(duì)象組p 裝飾(Decorator)模式:給對(duì)象動(dòng)態(tài)添加額外的職責(zé),就好像給一個(gè)物體加上裝飾物,完善其功能p 代理(Proxy)模式:有些對(duì)象由于跨越網(wǎng)絡(luò)或其他障礙,而不能或者不想直接訪問另一個(gè)對(duì)象,直接訪問會(huì)給系統(tǒng)帶來不必要的復(fù)雜性,這時(shí)候可以在客戶程序和目標(biāo)對(duì)象之間增加一個(gè)中間代理對(duì)象,讓代理對(duì)象來代替目標(biāo)對(duì)象結(jié)構(gòu)型設(shè)計(jì)模式結(jié)構(gòu)型設(shè)計(jì)模式結(jié)構(gòu)型設(shè)計(jì)模式結(jié)構(gòu)型設(shè)計(jì)模式p 享元(Flyweight)模式:享元是一個(gè)共享對(duì)象,它可以同時(shí)在不同上下文(Context)使用p 外觀(Facade)模式:外觀模式為子系統(tǒng)提供了一個(gè)更高層次、更簡單的接口,從而

13、降低了子系統(tǒng)的復(fù)雜度,使子系統(tǒng)更易于使用和管理。外觀承擔(dān)了子系統(tǒng)中類交互的責(zé)任p 橋梁(Bridge)模式:橋梁模式的用意是將問題的抽象和實(shí)現(xiàn)分離開來實(shí)現(xiàn),通過用聚合代替繼承來解決子類爆炸性增長的問題p 適配器(Adapter)模式:將一個(gè)類的接口適配成用戶期待接口。一個(gè)適配器允許因?yàn)榻涌诓患嫒荻荒茉谝黄鸸ぷ鞯念惞ぷ髟谝黄?,做法是將類自己的接口包裝在一個(gè)已存在的類中 p 著力解決的是類實(shí)體之間的通訊關(guān)系,希望以面向?qū)ο蟮姆绞矫枋鲆粋€(gè)控制流程p 模版(Template ) 模式:定義了一個(gè)算法步驟,并允許子類為一個(gè)或多個(gè)步驟提供實(shí)現(xiàn)。子類在不改變算法架構(gòu)的情況下,可重新定義算法中某些步驟p 觀

14、察者(Observer)模式:定義了對(duì)象之間一對(duì)多的依賴,當(dāng)這個(gè)對(duì)象的狀態(tài)發(fā)生改變的時(shí)候,多個(gè)對(duì)象會(huì)接受到通知,有機(jī)會(huì)做出反饋p 迭代子(Iterator)模式:提供一種方法順序訪問一個(gè)聚合對(duì)象中各個(gè)元素, 而又不需暴露該對(duì)象的內(nèi)部表示行為型設(shè)計(jì)模式行為型設(shè)計(jì)模式p 責(zé)任鏈(Chain of Responsibility)模式:多個(gè)對(duì)象由每一個(gè)對(duì)象對(duì)其下一個(gè)對(duì)象的引用而連接起來形成一條鏈。請(qǐng)求在這個(gè)鏈上傳遞,直到鏈上的某一個(gè)對(duì)象決定處理此請(qǐng)求。發(fā)出這個(gè)請(qǐng)求的客戶端并不知道鏈上的哪一個(gè)對(duì)象最終處理這個(gè)請(qǐng)求,這使系統(tǒng)可以在不影響客戶端的情況下動(dòng)態(tài)的重新組織鏈和分配責(zé)任p 備忘錄(Memento)模

15、式:在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)p 命令(Command)模式:將請(qǐng)求及其參數(shù)封裝成一個(gè)對(duì)象,作為命令發(fā)起者和接收者的中介,可以對(duì)這些請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤銷操作行為型設(shè)計(jì)模式行為型設(shè)計(jì)模式p 狀態(tài)(State)模式:允許一個(gè)“對(duì)象”在其內(nèi)部狀態(tài)改變的時(shí)候改變其行為,不同狀態(tài)表現(xiàn)不同行為p 訪問者(Visitor)模式:表示作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。可在不改變元素類的前提下定義作用于這些元素的新操作p 解釋器(Interpreter) 模式:給定一個(gè)語言,定義其文法的表示,并定義一個(gè)解

16、釋器,該解釋器使用文法表示來解釋語言中的句子p 中介者(Mediator)模式:用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互p 策略(Strategy)模式:定義一組算法,將每個(gè)算法都封裝起來,并且使它們之間可以互換。策略模式使這些算法在客戶端調(diào)用它們的時(shí)候能夠互不影響地變化行為型設(shè)計(jì)模式行為型設(shè)計(jì)模式創(chuàng)建型設(shè)計(jì)模式p工廠模式p抽象工廠模式p建造者模式p單件模式p原型模式創(chuàng)建型設(shè)計(jì)模式創(chuàng)建型設(shè)計(jì)模式p 在面向?qū)ο缶幊讨? 使用new操作符構(gòu)造對(duì)象實(shí)例是一種常規(guī)方法,但該方法存在一些約束條件和缺陷:(1)創(chuàng)建對(duì)象前須明確對(duì)象的類信息,但某些情況可能無法達(dá)到此要求,譬如打開一個(gè)視頻文件需要一個(gè)播放器對(duì)象,

17、但用戶可能并不知道具體播放器,需要系統(tǒng)分派一個(gè)合適的播放器(2)復(fù)雜對(duì)象的創(chuàng)建需要多個(gè)步驟p 需計(jì)算或取得對(duì)象的初始設(shè)置p 需選擇生成哪個(gè)子對(duì)象實(shí)例p 在生成所需對(duì)象之前必須先生成一些輔助對(duì)象p 新對(duì)象的創(chuàng)建是一個(gè)“過程”,而不是一個(gè)簡單操作。為了能方便完成這些復(fù)雜對(duì)象的創(chuàng)建工作,可引入工廠模式 工廠模式的由來工廠模式的由來工廠模式的結(jié)構(gòu)工廠模式的結(jié)構(gòu)p Product:定義工廠方法所創(chuàng)建對(duì)象的接口p ConcreteProduct:實(shí)現(xiàn)Product接口p Factory:聲明工廠方法,返回一個(gè)Product對(duì)象。Factory也可定義工廠方法的缺省實(shí)現(xiàn),返回一個(gè)缺省ConcreteProd

18、uct對(duì)象p Concrete Factory:重定義工廠方法,返回一個(gè)ConcreteProduct對(duì)象工廠模式的參與者工廠模式的參與者p日志管理器,支持兩種類型日志pFileLogpEventLog工廠模式實(shí)例工廠模式實(shí)例/ LogFactory類public abstract class LogFactory public abstract Log Create();工廠模式實(shí)例分析工廠模式實(shí)例分析/ FileFactory類 public class FileFactory:LogFactory public override FileLog Create() return new F

19、ileLog(); / EventFactory類 public class EventFactory:LogFactory public override EventLog Create() return new EventLog(); public class App public static void Main(string args) LogFactory factory1 = new EventFactory(); FileFactory factory2 = new FileFactory(); Log log1 = factory1.Create(); Log log2 = f

20、actory2.Create(); log1.Write(); log2.Write(); 工廠模式客戶端程序工廠模式客戶端程序p 有效避免了具體產(chǎn)品對(duì)象和應(yīng)用程序之間的耦合,增加了具體工廠對(duì)象和應(yīng)用程序之間的耦合p 在類內(nèi)部創(chuàng)建對(duì)象通常比直接創(chuàng)建對(duì)象更靈活p 工廠模式通過面向?qū)ο蟮氖址?,將具體對(duì)象的創(chuàng)建工作延遲到子類,提供了一種擴(kuò)展策略,較好的解決了緊耦合問題工廠模式實(shí)例分析工廠模式實(shí)例分析抽象工廠模式的由來抽象工廠模式的由來p 在軟件系統(tǒng)中,經(jīng)常面臨“一系列相互依賴對(duì)象”的創(chuàng)建工作,由于需求變化,“一系列相互依賴的對(duì)象”也要改變,如何應(yīng)對(duì)這種變化呢?如何像工廠模式一樣繞過常規(guī)的”new”,

21、提供一種“封裝機(jī)制”來避免客戶程序和這種“多系列具體對(duì)象創(chuàng)建工作”的緊耦合?p 一種說法:可以通過工廠模式創(chuàng)建每個(gè)對(duì)象,但無法保證“相互依賴對(duì)象”之間的聯(lián)系 p 實(shí)例:Windows桌面主題,當(dāng)更換一個(gè)桌面主題的時(shí)候,系統(tǒng)的開始按鈕、任務(wù)欄、菜單欄、工具欄等都變了,而且是一起變的,色調(diào)都保持一致,類似這樣的問題如何解決呢?p 應(yīng)用抽象工廠模式,是一種有效的解決途徑抽象工廠模式的意圖抽象工廠模式的意圖p意圖:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無需指定他們具體的類p適用場合p一個(gè)系統(tǒng)由多個(gè)產(chǎn)品系列中的一個(gè)來配置時(shí)p強(qiáng)調(diào)一系列相關(guān)產(chǎn)品對(duì)象的設(shè)計(jì)以便進(jìn)行聯(lián)合時(shí)p提供一個(gè)產(chǎn)品類庫,只想顯示其

22、接口而非實(shí)現(xiàn)時(shí)p需要?jiǎng)?chuàng)建的對(duì)象是一系列相互關(guān)聯(lián)或相互依賴的產(chǎn)品族時(shí)抽象工廠模式的結(jié)構(gòu)抽象工廠模式的結(jié)構(gòu)p Abstract Factory:聲明創(chuàng)建抽象產(chǎn)品對(duì)象的操作接口p ConcreteFactory:實(shí)現(xiàn)創(chuàng)建具體對(duì)象的操作p Abstract Product:為一類產(chǎn)品對(duì)象聲明一個(gè)接口p ConcreteProduct:定義一個(gè)被具體工廠創(chuàng)建的產(chǎn)品對(duì)象抽象工廠模式的參與者抽象工廠模式的參與者實(shí)例:需要設(shè)計(jì)一個(gè)花園布局 花園有三種風(fēng)格:典雅型、實(shí)用型和懶人型 花園中有3個(gè)位置需要種植植物:花臺(tái)、墻角和花園中心抽象工廠模式的應(yīng)用實(shí)例抽象工廠模式的應(yīng)用實(shí)例風(fēng)格/位置花臺(tái)中心墻角典雅型郁金香榕樹

23、蘭草實(shí)用型葡萄石榴絲瓜懶人型月季茶花竹子建造者(建造者(Builder)模式的由來)模式的由來p 在軟件系統(tǒng)中,有時(shí)面臨“復(fù)雜對(duì)象”的創(chuàng)建工作,該復(fù)雜對(duì)象通常由各個(gè)部分的子對(duì)象用一定的算法構(gòu)成p 這個(gè)復(fù)雜對(duì)象的各個(gè)部分經(jīng)常面臨劇烈變化,但是將它們組合在一起的算法卻相對(duì)穩(wěn)定p 如何應(yīng)對(duì)這種變化?如何提供一種“封裝機(jī)制”來隔離出“復(fù)雜對(duì)象的各個(gè)部分”的變化,從而保持系統(tǒng)中的“穩(wěn)定構(gòu)建算法”不隨著需求改變而改變?建造者模式的意圖和適用性建造者模式的意圖和適用性p 意圖:將一個(gè)復(fù)雜的構(gòu)建與表示相分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示p 適用性場合p 需要生成的產(chǎn)品對(duì)象有復(fù)雜的內(nèi)部結(jié)構(gòu)p 創(chuàng)建復(fù)雜對(duì)

24、象的算法穩(wěn)定,或可強(qiáng)迫生成一定順序p 當(dāng)構(gòu)造過程允許被構(gòu)造的對(duì)象有不同的表示時(shí)建造者模式的結(jié)構(gòu)建造者模式的結(jié)構(gòu)建造者模式的參與者建造者模式的參與者p Builder:為創(chuàng)建一個(gè)Product對(duì)象的各個(gè)部件指定抽象接口p ConcreteBuilder:實(shí)現(xiàn)Builder接口來構(gòu)造和裝配產(chǎn)品各個(gè)部件,提供一個(gè)檢索產(chǎn)品的接口p Director:構(gòu)造一個(gè)使用Builder接口的對(duì)象p Product:表示被構(gòu)造的復(fù)雜對(duì)象p 實(shí)例:設(shè)計(jì)游戲場景中的房屋p房屋由五個(gè)部分組成:地板、墻壁、窗戶、門和天花板p構(gòu)建房屋的步驟固定,而具體組件(門、窗等)易變p采用建造者模式分離易變組件和穩(wěn)定的構(gòu)建過程建造者模

25、式的應(yīng)用示例建造者模式的應(yīng)用示例public abstract class House /定義一個(gè)房屋抽象類 public abstract class Builder /這部分是易變的 public abstract void BuildFloor(); /地板 public abstract void BuildDoor(); /門 public abstract void BuildWindows(); /窗戶 public abstract void BuildWall(); /墻壁 public abstract void BuildHouseCeiling() /天花板 publi

26、c abstract House GetHouse(); 建造者模式的應(yīng)用示例建造者模式的應(yīng)用示例建造者模式的應(yīng)用示例建造者模式的應(yīng)用示例public abstract class GameManager /規(guī)定構(gòu)建次序 public static House CreateHouse(Builder builder) builder.BuildFloor(); builder.BuildDoor(); builder.Buildwall(); builder.BuildWindows(); builder.BuildHouseCeiling(); return builder.GetHouse

27、(); 建造者模式的應(yīng)用示例建造者模式的應(yīng)用示例public class RomanHouseBuilder : Builder public override void BuildDoor() public override void BuildFloor() public override void BuildWindows() public override void BuildWall() public override void BuildHouseCeiling() public override House GetHouse() 建造者模式的應(yīng)用示例建造者模式的應(yīng)用示例class

28、 App public static void main() House house = GameManager.CreateHouse(new RomanHouseBuilder(); 建造者模式分析建造者模式分析p 建造者模式的使用使產(chǎn)品內(nèi)部表象可以獨(dú)立變化;可以使客戶端不必知道產(chǎn)品內(nèi)部組成細(xì)節(jié)p 每一個(gè)Builder都相對(duì)獨(dú)立,與其它Builder無關(guān)p 可對(duì)構(gòu)造過程更加精細(xì)控制p 將構(gòu)建代碼和表示代碼分開p 缺點(diǎn):難于應(yīng)付“分步驟構(gòu)建算法”的需求變動(dòng)單件(單件(SingletonSingleton)模式的由來)模式的由來p 單件模式的實(shí)例較為普遍:p 系統(tǒng)中只能有一個(gè)窗口管理器p 系統(tǒng)

29、中只能有一個(gè)文件系統(tǒng)p 一個(gè)數(shù)字濾波器只能有一個(gè)A/D轉(zhuǎn)換器p 一個(gè)會(huì)計(jì)系統(tǒng)只能用于一個(gè)公司單件模式的由來單件模式的由來p 如何才能保證一個(gè)類只有一個(gè)實(shí)例并且這個(gè)實(shí)例易于被訪問呢?全局變量使得一個(gè)對(duì)象可以被訪問,但不能防止實(shí)例化多個(gè)對(duì)象p 更好的辦法: 讓類自身保存其唯一實(shí)例,可以保證該類沒有其他實(shí)例可以被創(chuàng)建,并且它可以提供一個(gè)訪問該實(shí)例的方法單件模式的意圖和適用性單件模式的意圖和適用性p 意圖:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)p 適用場合:p 當(dāng)類只能有一個(gè)實(shí)例而且需要使用戶可從一個(gè)統(tǒng)一訪問點(diǎn)訪問它時(shí)p 當(dāng)這個(gè)唯一實(shí)例通過子類化可擴(kuò)展,并且客戶應(yīng)該無需更改代碼就能使用一個(gè)擴(kuò)展實(shí)

30、例時(shí)單件模式的結(jié)構(gòu)單件模式的結(jié)構(gòu)p Singleton :被調(diào)用的單件對(duì)象p 定義一個(gè)Instance操作,允許客戶訪問它的唯一實(shí)例。Instance是一個(gè)類操作(靜態(tài)成員函數(shù)) ,負(fù)責(zé)創(chuàng)建自己的唯一實(shí)例單件模式的應(yīng)用示例單件模式的應(yīng)用示例Class Singleton /單件模式的定義 public:static Singleton* Instance(); /通過該成員函數(shù)訪問單件 protected:Singleton(); /構(gòu)造函數(shù)為受保護(hù)型,直接實(shí)例化將出錯(cuò) private:static Singleton* _instance; /指向本身唯一實(shí)例的指針;單件模式的應(yīng)用示例單件模

31、式的應(yīng)用示例Singleton * Singleton:_instance = 0; /初始化類成員Singleton* Singleton:Instance()If(_instance = 0) _instance =new Singleton; return _instance;單件模式的效果分析單件模式的效果分析p 可實(shí)現(xiàn)對(duì)唯一實(shí)例的受控訪問:因?yàn)镾ingleton類封裝唯一實(shí)例,所以它可以嚴(yán)格的控制客戶怎樣以及何時(shí)訪問它p 縮小了名空間:Singleton模式是對(duì)全局變量的一種改進(jìn)。它避免了那些存儲(chǔ)唯一實(shí)例的全局變量污染名空間原型(原型(Prototype)模式的由來)模式的由來p 在

32、軟件系統(tǒng)中,客戶希望創(chuàng)建一個(gè)產(chǎn)品時(shí),可能有三種情況:p 知道產(chǎn)品具體型號(hào):使用new運(yùn)算符創(chuàng)建p 不知道產(chǎn)品型號(hào),知道特定的需求:使用工廠模式p 不知道需求,但想要一個(gè)和已知對(duì)象相同的對(duì)象:使用原型模式原型(原型(Prototype)模式的意圖和適用性)模式的意圖和適用性p 意圖:用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象p 適用性:p 一個(gè)系統(tǒng)獨(dú)立于其產(chǎn)品創(chuàng)建,構(gòu)成和表示時(shí)p 要實(shí)例化的類在運(yùn)行時(shí)刻指定時(shí)p 為避免創(chuàng)建一個(gè)與產(chǎn)品類層次平行的工廠類層次時(shí)原型模式的結(jié)構(gòu)原型模式的結(jié)構(gòu)p Client:客戶端向原型管理器提出創(chuàng)建對(duì)象請(qǐng)求p Prototype:是對(duì)各種具體原型的

33、抽象,通常由一個(gè)接口或抽象類實(shí)現(xiàn)p ConcretePrototype:被復(fù)制的對(duì)象。此角色需要實(shí)現(xiàn)抽象的原型角色所要求的接口p PrototypeManager:創(chuàng)建具體原型類的對(duì)象,記錄每一個(gè)被創(chuàng)建的對(duì)象原型模式的參與者原型模式的參與者p 開發(fā)一個(gè)調(diào)色板,用戶單擊調(diào)色板上任一個(gè)方塊,返回一個(gè)對(duì)應(yīng)顏色的實(shí)例p 把每種顏色作為一個(gè)對(duì)象,并為他們抽象出一個(gè)公共父類原型模式應(yīng)用示例原型模式應(yīng)用示例原型模式應(yīng)用示例原型模式應(yīng)用示例p 優(yōu)點(diǎn)(1)對(duì)客戶隱藏具體產(chǎn)品類,減少了客戶知道的名字的數(shù)目(2)允許客戶只通過注冊原型實(shí)例就可以將一個(gè)具體產(chǎn)品類并入系統(tǒng)中,客戶可以在運(yùn)行時(shí)刻建立和刪除原型(3)具有給

34、一個(gè)應(yīng)用軟件動(dòng)態(tài)加載新功能的能力。由于其獨(dú)立性較高,可以很容易動(dòng)態(tài)加載新功能而不影響老系統(tǒng)(4)產(chǎn)品類不需要非得有任何事先確定的等級(jí)結(jié)構(gòu),適用于任何的等級(jí)結(jié)構(gòu)p 缺點(diǎn) Prototype模式的最主要缺點(diǎn)就是每個(gè)類必須配備一個(gè)克隆方法原型模式的應(yīng)用效果分析原型模式的應(yīng)用效果分析p 工廠模式是一種極端情況下的抽象工廠模式,而抽象工廠模式可以看成是工廠模式的一種推廣p 工廠模式的特點(diǎn)p一個(gè)抽象產(chǎn)品類,可以派生出多個(gè)具體產(chǎn)品類p一個(gè)抽象工廠類,可以派生出多個(gè)具體工廠類p每個(gè)具體工廠類只能創(chuàng)建一個(gè)具體的產(chǎn)品類實(shí)例p 抽象工廠模式的特點(diǎn)p多個(gè)抽象產(chǎn)品類,每個(gè)抽象產(chǎn)品類可以派生出多個(gè)具體產(chǎn)品類p一個(gè)抽象工廠

35、類,可以派生出多個(gè)具體工廠類p每個(gè)具體工廠類可以創(chuàng)建多個(gè)具體產(chǎn)品類的實(shí)例抽象工廠模式與工廠模式的區(qū)別抽象工廠模式與工廠模式的區(qū)別p抽象工廠允許客戶使用抽象接口來創(chuàng)建一組相關(guān)產(chǎn)品,而不需要關(guān)心具體產(chǎn)出產(chǎn)品是什么p總結(jié)p 所有工廠都是用來封裝對(duì)象的創(chuàng)建p 簡單工廠,可以把客戶程序從具體類解耦p 工廠方法使用繼承,把對(duì)象創(chuàng)建委托給子類,子類實(shí)現(xiàn)工廠方法來創(chuàng)建對(duì)象p 抽象工廠使用對(duì)象組合:對(duì)象的創(chuàng)建被實(shí)現(xiàn)在工廠接口所暴露出來的方法中p 所有工廠模式都通過減少應(yīng)用程序與具體類之間的依賴關(guān)系促進(jìn)松耦合p 工廠方法允許類將實(shí)例化延遲到子類進(jìn)行p 抽象工廠創(chuàng)建相關(guān)的家族,而不需要依賴他們的具體類p 工廠幫助我

36、們針對(duì)抽象編程,而不是針對(duì)具體類編程抽象工廠模式與工廠模式的區(qū)別抽象工廠模式與工廠模式的區(qū)別p 工廠模式:定義一個(gè)創(chuàng)建對(duì)象的接口,由子類決定要實(shí)例化的具體類,工廠方法讓類把實(shí)例化推遲到子類p 抽象工廠模式:提供一個(gè)接口,用于創(chuàng)建相關(guān)或依賴對(duì)象的家族,而不需要明確指定具體類p 建造者模式:封裝一個(gè)產(chǎn)品(復(fù)雜對(duì)象)的構(gòu)造過程,并允許按照步驟構(gòu)造,向客戶隱藏了產(chǎn)品的內(nèi)部表現(xiàn)p 單件模式:確保一個(gè)類只有一個(gè)實(shí)例,并提供全局訪問點(diǎn)p 原型模式:當(dāng)創(chuàng)建給定類實(shí)例的過程很昂貴或很復(fù)雜時(shí),使用原型模式,向客戶隱藏制造新實(shí)例的復(fù)雜性創(chuàng)建型設(shè)計(jì)模式總結(jié)創(chuàng)建型設(shè)計(jì)模式總結(jié)結(jié)構(gòu)型設(shè)計(jì)模式p 適配器模式p 外觀模式p

37、裝飾模式p 橋接模式p 享元模式p 代理模式p 組合模式結(jié)構(gòu)型模式的主要內(nèi)容結(jié)構(gòu)型模式的主要內(nèi)容軟件開發(fā)過程中常見的問題軟件開發(fā)過程中常見的問題p 系統(tǒng)組件更新問題:軟件系統(tǒng)的某組件過時(shí)了,要從廠商那里引進(jìn)一個(gè)新的組件,但原系統(tǒng)的組件接口和新組件的接口不一致,同時(shí)又不想改變現(xiàn)有的代碼,如何實(shí)現(xiàn)從舊組件更新到新組件現(xiàn)有現(xiàn)有系統(tǒng)系統(tǒng)接口接口廠廠商商類類兩個(gè)接口兩個(gè)接口無法匹配,無法匹配,所以無法所以無法工作工作軟件開發(fā)過程中常見的問題軟件開發(fā)過程中常見的問題p 生活中相似問題的解決方案不合適的插座問題p 電腦的插頭是三相的p 墻上的插座只有兩相的p 插頭和插座的“接口”不匹配,怎么辦?組件更新問題

38、的可行解決方案組件更新問題的可行解決方案現(xiàn)有現(xiàn)有系統(tǒng)系統(tǒng)接口接口廠廠商商類類兩個(gè)接口兩個(gè)接口無法匹配,無法匹配,所以無法所以無法工作工作現(xiàn)有現(xiàn)有系統(tǒng)系統(tǒng)接口接口廠廠商商類類適適配配器器適配器模式的動(dòng)機(jī)適配器模式的動(dòng)機(jī)p 一個(gè)team要為外界提供S類服務(wù),但team里面沒有能夠完成此項(xiàng)任務(wù)的member,只有team外的A可以完成這項(xiàng)服務(wù)。為保證對(duì)外服務(wù)類別的一致性(能提供S服務(wù))p 將A招安到team內(nèi),負(fù)責(zé)提供S類服務(wù)p A不準(zhǔn)備接受招安,可安排B去完成這項(xiàng)任務(wù),并讓B做好A的工作,讓B工作的時(shí)候向A請(qǐng)教,此時(shí),B是一個(gè)復(fù)合體(提供S服務(wù),是A的繼承弟子)p 動(dòng)機(jī):將一個(gè)類的接口,轉(zhuǎn)換成客戶

39、期望的另一個(gè)接口,適配器讓原本接口不兼容的類可以一起工作適配器模式使用過程適配器模式使用過程p 客戶(Client)通過目標(biāo)接口調(diào)用適配器(Adapter)的方法對(duì)適配器發(fā)出請(qǐng)求p 適配器(Adapter)使用被適配者(Adaptee)接口把請(qǐng)求轉(zhuǎn)換成被適配者的一個(gè)或者多個(gè)調(diào)用接口p 客戶接收到調(diào)用的結(jié)果,但并未察覺這一切是適配器在起轉(zhuǎn)換作用適配器模式的適用性適配器模式的適用性p 適用場合:p 使用一個(gè)已經(jīng)存在的類,而它的接口不符合要求p 創(chuàng)建一個(gè)可以復(fù)用的類,該類可以與其他不相關(guān)的類或不可預(yù)見的類(即那些接口可能不一定兼容的類)協(xié)同工作p 使用一些已經(jīng)存在的子類,但不可能通過子類化以匹配各自

40、接口。對(duì)象適配器可以適配它的父類接口p 分類:p 類適配器:通過多重繼承匹配一個(gè)接口和另一個(gè)接口p 對(duì)象適配器:在一個(gè)類中定義另一個(gè)類的實(shí)例對(duì)象,實(shí)現(xiàn)類和對(duì)象的組合類適配器類適配器p 用一個(gè)具體的Adapter類對(duì)Adaptee和Target進(jìn)行匹配,Adapter類多重繼承Adaptee和Target類p Adapter可重定義Adaptee的部分行為,因?yàn)锳dapter是Adaptee的一個(gè)子類類適配器模式示例類適配器模式示例/Target:定義Client使用的與特定領(lǐng)域相關(guān)的接口 public interface Target void request(); /Adaptee:需要適配

41、的已經(jīng)存在的接口 public class Adaptee public void specificRequest() /Adapter:對(duì)對(duì)Adaptee 的接口與的接口與Target接口進(jìn)行適配接口進(jìn)行適配 public class Adapter extends Adaptee implements Target public void request() super. specificRequest(); 對(duì)象適配器對(duì)象適配器p 允許一個(gè)Adapter與多個(gè)Adaptee同時(shí)工作,即Adaptee本身以及它的所有子類(如果有子類的話)同時(shí)工作。Adapter可以一次給所有的Adapte

42、e添加功能p 使用組合,不僅可以適配某個(gè)類,也可以適配該類的任何子類對(duì)象適配器模式示例對(duì)象適配器模式示例/Target:定義Client使用的與特定領(lǐng)域相關(guān)的接口 public interface Target void request(); /Adaptee:現(xiàn)在需要適配的已經(jīng)存在的接口 public class Adaptee public void specificRequest() /Adapter:對(duì)對(duì)Adaptee 的接口與的接口與Target接口進(jìn)行適配接口進(jìn)行適配 public class Adapter implements Target private Adaptee ad

43、aptee; public Adapter(Adaptee adaptee) super(); this.adaptee = adaptee; public void request() adaptee.specificRequest(); 適配器模式效果分析適配器模式效果分析p 優(yōu)點(diǎn)p 方便設(shè)計(jì)者自由定義接口,不用擔(dān)心匹配問題p 缺點(diǎn)p 屬于靜態(tài)結(jié)構(gòu) ,由于只能單繼承,所以不適用于多種不同的源適配到同一個(gè)目標(biāo)兩種適配器模式的比較兩種適配器模式的比較外觀(外觀(Facade)模式的由來)模式的由來畢業(yè)生教務(wù)處公安處后勤處圖書館飯卡飯卡余額借書證借書證押金身份證、學(xué)生證派遣證學(xué)生證畢業(yè)證、學(xué)位證

44、外觀(外觀(Facade)模式的由來)模式的由來畢業(yè)生畢業(yè)手續(xù)代辦處教務(wù)處后勤處圖書館公安處學(xué)生證 身份證 借書證 飯卡畢業(yè)證 學(xué)位證 派遣證 飯卡余額 借書證押金外觀(外觀(Facade)模式的由來)模式的由來外觀外觀(Faade)模式的由來模式的由來外觀(外觀(Facade)模式的意圖和適用性)模式的意圖和適用性p 提供了一個(gè)統(tǒng)一的接口,用來訪問子系統(tǒng)中的一群接口。外觀定義了一個(gè)高層接口,讓子系統(tǒng)更容易使用p 解除客戶程序?qū)Τ橄箢惥唧w實(shí)現(xiàn)部分的依賴,有利于移植和更改p 當(dāng)需要構(gòu)建層次結(jié)構(gòu)的子系統(tǒng)時(shí),使用Faade模式定義每層入口點(diǎn)。如果子系統(tǒng)間相互依賴,只需通過Faade進(jìn)行通訊p 外觀模

45、式的本質(zhì)是讓接口變得更簡單外觀(外觀(Facade)模式的結(jié)構(gòu))模式的結(jié)構(gòu)外觀(外觀(Facade)模式的參與者)模式的參與者p Faadep 知道哪些子系統(tǒng)類負(fù)責(zé)處理請(qǐng)求p 將客戶的請(qǐng)求代理給適當(dāng)?shù)淖酉到y(tǒng)對(duì)象p Subsystem Classesp 實(shí)現(xiàn)子系統(tǒng)的功能p 處理由Faade 對(duì)象指派的任務(wù)p 沒有Faade的任何相關(guān)信息外觀(外觀(Facade)模式的效果分析)模式的效果分析p 根據(jù)“單一職責(zé)原則”,在軟件中將一個(gè)子系統(tǒng)劃分為若干個(gè)子系統(tǒng)有利于降低整個(gè)系統(tǒng)的復(fù)雜性,一個(gè)常見的設(shè)計(jì)目標(biāo)是使子系統(tǒng)之間的通信和相互依賴關(guān)系達(dá)到最小,而達(dá)到該目標(biāo)的途徑之一就是引入一個(gè)外觀對(duì)象,它為子系統(tǒng)

46、的訪問提供了一個(gè)簡單而單一的入口p 外觀模式也是“迪米特法則”的體現(xiàn),通過引入一個(gè)新的外觀類可以降低原有系統(tǒng)的復(fù)雜度,同時(shí)降低客戶類與子系統(tǒng)類的耦合度外觀(外觀(Facade)模式的效果分析)模式的效果分析p 外觀模式要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信通過一個(gè)統(tǒng)一的外觀對(duì)象進(jìn)行,外觀類將客戶端與子系統(tǒng)的內(nèi)部復(fù)雜性分隔開,使得客戶端只需要與外觀對(duì)象打交道,而不需要與子系統(tǒng)內(nèi)部的很多對(duì)象打交道p 外觀模式的目的在于降低系統(tǒng)的復(fù)雜程度p 外觀模式從很大程度上提高了客戶端使用的便捷性,使得客戶端無須關(guān)心子系統(tǒng)的工作細(xì)節(jié),通過外觀角色即可調(diào)用相關(guān)功能p 如何增加新的子系統(tǒng)?是否可能違背“開閉原則”外觀(

47、外觀(Facade)模式的缺點(diǎn))模式的缺點(diǎn)p 不能很好的限制客戶使用子系統(tǒng)類,如果對(duì)客戶訪問子系統(tǒng)類做太多的限制,則減少了可變形和靈活性p 增加一個(gè)新的子系統(tǒng),可能需要修改外觀類或客戶端的源代碼,違背了“開閉原則”,怎么辦?p 引入抽象外觀類,客戶端針對(duì)抽象外觀類編程裝飾(裝飾(Decorator)解決的問題)解決的問題p 新買一輛車,但外表不夠美觀p 對(duì)車的外表進(jìn)行必要的裝飾裝飾(裝飾(Decorator)模式的由來)模式的由來p 動(dòng)態(tài)給對(duì)象添加額外職責(zé)。比如:一幅畫有沒有畫框都可以掛在墻上,畫是被裝飾者。在掛在墻上之前,畫可以被蒙上玻璃,裝到框子里,玻璃畫框就是裝飾p 不改變接口,但加入了

48、責(zé)任。Decorator提供了一種給類增加職責(zé)的方法,不是通過繼承,而是通過組合實(shí)現(xiàn)的裝飾(裝飾(Decorator)模式的意圖和適用性)模式的意圖和適用性p 意圖p 動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來說,Decorator 模式比生成子類更為靈活p 適用場合p 在不影響其他對(duì)象的情況下,以動(dòng)態(tài)、透明的方式給單個(gè)對(duì)象添加職責(zé)p 當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時(shí)。一種情況是,可能有大量獨(dú)立擴(kuò)展,每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長。另一種情況是因?yàn)轭惗x被隱藏,或類定義不能用于生成子類裝飾(裝飾(Decorator)模式的結(jié)構(gòu))模式的結(jié)構(gòu)p Component:定

49、義對(duì)象的接口,可以給對(duì)象動(dòng)態(tài)添加職責(zé)p ConcreteComponent:定義具體對(duì)象,裝飾抽象類可以給它添加額外的職責(zé)p Decorator:維持一個(gè)指向Component對(duì)象的指針,并定義一個(gè)與Component接口一致的接口p ConcreteDecorator:具體裝飾對(duì)象,向具體對(duì)象添加職責(zé)p Decorator將請(qǐng)求轉(zhuǎn)發(fā)給它的Component對(duì)象,并有可能在轉(zhuǎn)發(fā)請(qǐng)求前后執(zhí)行一些附加的動(dòng)作裝飾(裝飾(Decorator)模式的結(jié)構(gòu))模式的結(jié)構(gòu)裝飾(裝飾(Decorator)模式的應(yīng)用)模式的應(yīng)用ComponentConcreteComponent裝飾(裝飾(Decorator)模

50、式的應(yīng)用)模式的應(yīng)用Decorator裝飾(裝飾(Decorator)模式的應(yīng)用)模式的應(yīng)用ConcreteDecorator裝飾(裝飾(Decorator)模式的應(yīng)用)模式的應(yīng)用裝飾(裝飾(Decorator)模式的評(píng)價(jià))模式的評(píng)價(jià)p 使用Decorator模式可以很容易地向?qū)ο筇砑勇氊?zé)??梢杂锰砑雍头蛛x的方法,在運(yùn)行時(shí)添加和刪除職責(zé)p 使用Decorator模式可以很容易地重復(fù)添加一個(gè)特性,而兩次繼承則極容易出錯(cuò)p 避免在層次結(jié)構(gòu)高層的類有太多的特征:可以從簡單的部件組合出復(fù)雜的功能。具有低依賴性和低復(fù)雜性橋接(橋接(Bridge)模式的由來)模式的由來p 例子:設(shè)想如果要繪制矩形、圓形、

51、橢圓、正方形,至少需要4個(gè)形狀類,但是如果繪制的圖形需要具有不同的顏色,如紅色、綠色、藍(lán)色等,此時(shí)至少有如下兩種設(shè)計(jì)方案p 為每一種形狀都提供一套各種顏色的版本p 根據(jù)實(shí)際需要對(duì)形狀和顏色進(jìn)行組合橋接(橋接(Bridge)模式的由來)模式的由來12方案表示橋接模式,將繼承關(guān)系轉(zhuǎn)換為關(guān)聯(lián)關(guān)系,降低了類與類之間的耦合,減少了代碼量橋接(橋接(Bridge)模式的由來)模式的由來p 例子:相同模塊的跨平臺(tái)使用p 設(shè)計(jì)模塊A和Bp 希望模塊A和B能應(yīng)用在X操作系統(tǒng)上,讓A和B繼承X操作系統(tǒng)的接口p 希望模塊A和B能應(yīng)用在Y操作系統(tǒng)上,讓A和B繼承Y操作系統(tǒng)的接口,以此類推p 問題:模塊A和B缺乏復(fù)用性

52、p 解決:抽象出統(tǒng)一的操作系統(tǒng)類的接口連接模塊A和B的平臺(tái)無關(guān)接口,通過橋接兩個(gè)抽象模塊來消除模塊間的繼承耦合,提高復(fù)用性擴(kuò)展Window抽象使之用于不同種類的窗口或新的平臺(tái)很不方便繼承機(jī)制使得客戶代碼與平臺(tái)相關(guān)橋接(橋接(Bridge)模式的由來)模式的由來1將Window抽象和它的實(shí)現(xiàn)部分分別放在獨(dú)立的類層次結(jié)構(gòu)中針對(duì)窗口接口針對(duì)平臺(tái)的窗口實(shí)現(xiàn)橋接(橋接(Bridge)模式的由來)模式的由來2u對(duì)于有兩個(gè)變化維度(即兩個(gè)變化的原因)的系統(tǒng),采用方案二進(jìn)行設(shè)計(jì),系統(tǒng)中類的個(gè)數(shù)更少,且系統(tǒng)擴(kuò)展更為方便u設(shè)計(jì)方案二即是橋接模式的應(yīng)用。橋接模式將繼承關(guān)系轉(zhuǎn)換為關(guān)聯(lián)關(guān)系,從而降低了類與類之間的耦合,

53、減少了代碼量橋接(橋接(Bridge)模式的動(dòng)機(jī))模式的動(dòng)機(jī)橋接(橋接(Bridge)模式的意圖和適用性)模式的意圖和適用性p 意圖:橋接模式的作用就是將抽象部分與實(shí)現(xiàn)部分分離,使它可以獨(dú)立的變化p 適用的情況p 不希望在抽象和它的實(shí)現(xiàn)部分之間有一個(gè)固定的綁定關(guān)系p 想對(duì)客戶完全隱藏抽象的實(shí)現(xiàn)部分橋接(橋接(Bridge)模式的結(jié)構(gòu))模式的結(jié)構(gòu)橋接(橋接(Bridge)模式的參與者)模式的參與者p Abstractionp 定義抽象類的接口p 維護(hù)一個(gè)指向Implementor類型對(duì)象的指針p RefinedAbstractionp 擴(kuò)充由Abstraction定義的接口p Implement

54、orp 定義實(shí)現(xiàn)類的接口,不一定要與Abstraction的接口完全一致,甚至可以完全不同p ConcreteImplementorp 實(shí)現(xiàn)Implementor接口并定義它的具體實(shí)現(xiàn)p Abstraction將Client的請(qǐng)求轉(zhuǎn)發(fā)給它的Implementor對(duì)象橋接(橋接(Bridge)模式的意義)模式的意義p 脫耦是指將抽象和實(shí)現(xiàn)之間的耦合解脫開,或者說將他們之間的強(qiáng)關(guān)聯(lián)改成若弱關(guān)聯(lián)p 強(qiáng)關(guān)聯(lián)是指在編譯時(shí)期已經(jīng)確定的,無法在運(yùn)行時(shí)期動(dòng)態(tài)改變的關(guān)聯(lián)p 弱關(guān)聯(lián)是可以動(dòng)態(tài)確定并可在運(yùn)行時(shí)刻動(dòng)態(tài)改變的關(guān)聯(lián)p 繼承關(guān)系是強(qiáng)關(guān)聯(lián),聚合關(guān)系是弱關(guān)聯(lián),將兩個(gè)角色之間的繼承關(guān)系修改為聚合關(guān)系,就是將他們之

55、間的強(qiáng)關(guān)聯(lián)變換成弱關(guān)聯(lián)。橋模式中的所謂脫耦就是指在一個(gè)軟件系統(tǒng)的抽象和實(shí)現(xiàn)之間使用組合/聚合關(guān)系而不是繼承關(guān)系,從而可以使兩者可以相對(duì)獨(dú)立的變化橋接(橋接(Bridge)模式的優(yōu)點(diǎn))模式的優(yōu)點(diǎn)p分離抽象接口及其實(shí)現(xiàn)部分 p橋接模式有時(shí)類似于多繼承方案,但是多繼承方案違背了類的單一職責(zé)原則(即一個(gè)類只有一個(gè)變化的原因),復(fù)用性比較差,而且多繼承結(jié)構(gòu)中類的個(gè)數(shù)非常龐大,橋接模式是比多繼承方案更好的解決方法p橋接模式提高了系統(tǒng)的可擴(kuò)充性,在兩個(gè)變化維度中任意擴(kuò)展一個(gè)維度,都不需要修改原有系統(tǒng)p實(shí)現(xiàn)細(xì)節(jié)對(duì)客戶透明,可以對(duì)用戶隱藏實(shí)現(xiàn)細(xì)節(jié)橋接(橋接(Bridge)模式的缺點(diǎn))模式的缺點(diǎn)p橋接模式的引入會(huì)

56、增加系統(tǒng)的理解與設(shè)計(jì)難度,由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,要求開發(fā)者針對(duì)抽象進(jìn)行設(shè)計(jì)與編程p橋接模式要求正確識(shí)別出系統(tǒng)中兩個(gè)獨(dú)立變化的維度,因此其使用范圍具有一定的局限性橋接(橋接(Bridge)模式的應(yīng)用案例)模式的應(yīng)用案例橋接(橋接(Bridge)模式的應(yīng)用案例)模式的應(yīng)用案例享元(享元(Flyweght)模式的由來)模式的由來享元(享元(Flyweght)模式的由來)模式的由來p 當(dāng)大量使用同一種類型的實(shí)例(每個(gè)實(shí)例中包含部分相同的數(shù)據(jù)),可能極大的耗費(fèi)資源,使用Flyweight模式可以提高內(nèi)存效率p 以CD唱片為例,每個(gè)CD有三個(gè)屬性:出片日期、歌唱者姓名、唱片曲目p 姓名可能重復(fù),可

57、能有同一個(gè)演唱者的多個(gè)不同時(shí)期不同曲目的CD。歌唱者姓名可共享,其他字段均不可共享p 當(dāng)你有幾千張甚至更多CD時(shí),Flyweight模式將節(jié)省更多空間,共享的flyweight越多,空間節(jié)省也就越大享元(享元(Flyweght)模式的意圖和適用性)模式的意圖和適用性p 意圖:避免大量擁有相同內(nèi)容的小類的開銷,共享一元類p 動(dòng)機(jī):通過共享技術(shù)實(shí)現(xiàn)相同或相似對(duì)象的重用p 適用性p 一個(gè)應(yīng)用程序使用了大量的對(duì)象p 冗余使用了大量的對(duì)象,造成了很大的存儲(chǔ)開銷享元(享元(Flyweght)模式的結(jié)構(gòu))模式的結(jié)構(gòu)享元(享元(Flyweght)模式的參與者)模式的參與者p Flyweight:描述一個(gè)接口,

58、可接受并作用于外部狀態(tài)p ConcreteFlyweight:實(shí)現(xiàn)Flyweight接口,并為內(nèi)部狀態(tài)增加存儲(chǔ)空間。必須是可共享的,存儲(chǔ)的狀態(tài)必須是內(nèi)部的p UnsharedConcreteFlyweight:不強(qiáng)制共享p FlyweightFactory:創(chuàng)建并管理flyweight對(duì)象;確保合理地共享flyweight,提供已創(chuàng)建的flyweight實(shí)例或者創(chuàng)建一個(gè)p Client:維持一個(gè)對(duì)flyweight的引用;計(jì)算或存儲(chǔ)一個(gè)(多個(gè))flyweight的外部狀態(tài)享元(享元(Flyweght)模式的參與者)模式的參與者p Flyweight執(zhí)行時(shí)所需的狀態(tài)必定是內(nèi)部或外部的。內(nèi)部狀態(tài)存

59、儲(chǔ)在ConcreteFlyweight中,外部對(duì)象則由Client對(duì)象存儲(chǔ)或計(jì)算。當(dāng)用戶調(diào)用flyweight對(duì)象操作時(shí),將該狀態(tài)傳遞給它p 用戶不應(yīng)直接對(duì)ConcreteFlyweight類進(jìn)行實(shí)例化,而只能從FlyweightFactory對(duì)象得到ConcreteFlyweight對(duì)象,以保證對(duì)它們適當(dāng)?shù)剡M(jìn)行共享享元(享元(Flyweght)模式的效果分析)模式的效果分析p Flyweight模式的核心就是把大量共享的對(duì)象收集在一起使用簡單工廠模式進(jìn)行管理,避免由于大量的小對(duì)象導(dǎo)致系統(tǒng)的內(nèi)存過渡消耗p 當(dāng)重復(fù)對(duì)象較多時(shí), Flyweight模式具有較好的空間性能,但在查找搜索上消耗了時(shí)間復(fù)

60、雜度代理(代理(Proxy)模式的幾個(gè)來源)模式的幾個(gè)來源代理(代理(Proxy)模式的由來)模式的由來p 某個(gè)客戶端不能直接操作到某個(gè)對(duì)象,但又必須和那個(gè)對(duì)象有所互動(dòng)p 如果對(duì)象是一個(gè)大圖片,需要花費(fèi)很長時(shí)間才能顯示出來,此時(shí)需要做個(gè)圖片Proxy來代替真正的圖片p 如果對(duì)象在某遠(yuǎn)端服務(wù)器上,直接操作這個(gè)對(duì)象因?yàn)榫W(wǎng)絡(luò)速度原因可能比較慢,可以用Proxy來代替那個(gè)對(duì)象p 如何應(yīng)對(duì)這種變化?如何提供一種機(jī)制讓原本交互起來比較困難的兩個(gè)對(duì)象實(shí)現(xiàn)暢通無阻地交流呢?如何保持系統(tǒng)的結(jié)構(gòu)不隨著需求改變而輕易改變?這就是代理模式代理(代理(Proxy)模式的意圖和適用性)模式的意圖和適用性p 意圖:為其他對(duì)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論