面向模式的軟件體系架構(gòu)_第1頁
面向模式的軟件體系架構(gòu)_第2頁
面向模式的軟件體系架構(gòu)_第3頁
面向模式的軟件體系架構(gòu)_第4頁
面向模式的軟件體系架構(gòu)_第5頁
已閱讀5頁,還剩211頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、Agenda概述概述 - 簡要介紹模式的概念、地位、構(gòu)成、分類以及描述方法。設(shè)計(jì)原則設(shè)計(jì)原則 - 設(shè)計(jì)原則是設(shè)計(jì)目標(biāo)的高度抽象,模式是實(shí)現(xiàn)這些原則的具體方法。設(shè)計(jì)設(shè)計(jì)模式模式 - 主要介紹了GOF23種軟件設(shè)計(jì)模式。架構(gòu)模式架構(gòu)模式 - 主要介紹了架構(gòu)設(shè)計(jì)的幾種模式。練習(xí)練習(xí)參考資料參考資料 - 培訓(xùn)只能入門,需要在日常工作中積累提高,請保持閱讀習(xí)慣。概 述模式是什么 模式是指從生產(chǎn)經(jīng)驗(yàn)和生活經(jīng)驗(yàn)中經(jīng)過抽象和升華提煉出來的核心知識體系核心知識體系。模式其實(shí)就是解決某一類問題的方法論方法論。把解決某類問題的方法總結(jié)歸納到理論高度,那就是模式。模式是一種指導(dǎo),在一個(gè)良好的指導(dǎo)下,有助于你完成任務(wù),

2、有助于你作出一個(gè)優(yōu)良的設(shè)計(jì)方案,達(dá)到事半功倍的效果。而且,會(huì)得到解決問題的最佳辦法。模式在知識理念中的地位抽象抽象的(的(abstract)具體具體的(的(concrete)模式的構(gòu)成u ContextContext(語境)(語境) 設(shè)計(jì)問題產(chǎn)生的上下文背景u ProblemProblem(問題)(問題) 給定語境中重復(fù)出現(xiàn)的問題 - 解決方案必須滿足的需求 - 你必須考慮的約束 - 解決方案必須具有期望的特性u SolutionSolution(解決方案)(解決方案) 針對該問題,證實(shí)有效的解決方案 - 規(guī)定了一個(gè)特定的結(jié)構(gòu) - 規(guī)定了運(yùn)行期間的行為模式的作用u 一個(gè)模式關(guān)注一個(gè)在特定設(shè)計(jì)環(huán)

3、境中出現(xiàn)的重復(fù)設(shè)計(jì)問題一個(gè)模式關(guān)注一個(gè)在特定設(shè)計(jì)環(huán)境中出現(xiàn)的重復(fù)設(shè)計(jì)問題u 各種模式用文檔方式記錄現(xiàn)有的、經(jīng)充分考驗(yàn)的設(shè)計(jì)經(jīng)驗(yàn)各種模式用文檔方式記錄現(xiàn)有的、經(jīng)充分考驗(yàn)的設(shè)計(jì)經(jīng)驗(yàn)u 模式明確并指明處于單個(gè)類和實(shí)例層次或組件層次之上的抽象模式明確并指明處于單個(gè)類和實(shí)例層次或組件層次之上的抽象u 模式為設(shè)計(jì)原則提供一種公共的詞匯和理解模式為設(shè)計(jì)原則提供一種公共的詞匯和理解u 模式是為軟件體系結(jié)構(gòu)建立文檔的一種手段模式是為軟件體系結(jié)構(gòu)建立文檔的一種手段u 模式模式支持用已定義的屬性來構(gòu)造軟件支持用已定義的屬性來構(gòu)造軟件u 模式有助于建立一個(gè)復(fù)雜的和異構(gòu)的軟件體系結(jié)構(gòu)模式有助于建立一個(gè)復(fù)雜的和異構(gòu)的軟件

4、體系結(jié)構(gòu)u 模式有助于管理軟件復(fù)雜度模式有助于管理軟件復(fù)雜度 一個(gè)軟件體系結(jié)構(gòu)的模式描述了一個(gè)出現(xiàn)在特定設(shè)計(jì)語境中的特殊的再現(xiàn)設(shè)計(jì)問題,并為它的解決方案提供了一個(gè)經(jīng)過充分驗(yàn)證的通用圖式。解決方案圖式通過描述其組成組件、它們的責(zé)任和相互關(guān)系以及它們的協(xié)作方式來具體指定。模式的層次分類架構(gòu)模式架構(gòu)模式(Architecture Styles)- 是系統(tǒng)的高層次策略 ,涉及到大尺度的組件以及整體性質(zhì)- 可作為具體軟件體系結(jié)構(gòu)的模板,是開發(fā)一個(gè)軟件系統(tǒng)時(shí)的基本設(shè)計(jì)決策 -規(guī)定了系統(tǒng)范圍結(jié)構(gòu)特性,架構(gòu)模式的好壞影響到總體布局和框架性結(jié)構(gòu) 設(shè)計(jì)設(shè)計(jì)模式模式(Design Patterns)-是中等尺度的結(jié)

5、構(gòu)策略。實(shí)現(xiàn)了一些大尺度組件的行為和它們之間的關(guān)系 -模式的好壞不會(huì)影響到系統(tǒng)的總體布局和總體框架-設(shè)計(jì)模式定義出子系統(tǒng)或組件的微觀結(jié)構(gòu) 代碼代碼模式模式(Idioms)-是特定的范例和與特定語言有關(guān)的編程技巧 -處理特定設(shè)計(jì)問題的實(shí)現(xiàn),關(guān)注設(shè)計(jì)和實(shí)現(xiàn)方面 -模式的好壞會(huì)影響中等尺度組件的內(nèi)部、外部的結(jié)構(gòu)或行為的底層細(xì)節(jié) 模式描述u 名稱:模式的名稱和一個(gè)簡短的摘要名稱:模式的名稱和一個(gè)簡短的摘要u 別名:模式的其他名稱,如果知道的話別名:模式的其他名稱,如果知道的話u 例子:用來說明問題存在和需要模式的一個(gè)真實(shí)世界的例子例子:用來說明問題存在和需要模式的一個(gè)真實(shí)世界的例子u 語境:模式可以應(yīng)

6、用的情形語境:模式可以應(yīng)用的情形u 問題:模式解決的問題,包括其相關(guān)強(qiáng)制條件的討論問題:模式解決的問題,包括其相關(guān)強(qiáng)制條件的討論u 解決解決方案:以該模式為基礎(chǔ)的基本解決方案原理方案:以該模式為基礎(chǔ)的基本解決方案原理u 結(jié)構(gòu):模式結(jié)構(gòu)方面的詳細(xì)的規(guī)格說明結(jié)構(gòu):模式結(jié)構(gòu)方面的詳細(xì)的規(guī)格說明u 動(dòng)態(tài)特性:描述模式運(yùn)行期間行為的典型場景動(dòng)態(tài)特性:描述模式運(yùn)行期間行為的典型場景u 實(shí)現(xiàn):實(shí)現(xiàn)模式的指南實(shí)現(xiàn):實(shí)現(xiàn)模式的指南u 已解決已解決的例子:針對解決沒有包括在上述小節(jié)中例子的一些重要方面討論的例子:針對解決沒有包括在上述小節(jié)中例子的一些重要方面討論u 變體:模式變體或特例的簡短描述變體:模式變體或特

7、例的簡短描述u 已知使用:從已存在的系統(tǒng)中給出模式使用的例子已知使用:從已存在的系統(tǒng)中給出模式使用的例子u 效果:模式提供的優(yōu)點(diǎn)和模式存在的潛在不足效果:模式提供的優(yōu)點(diǎn)和模式存在的潛在不足u 參見:參考那些解決相似問題的模式,并且參考其他一些模式,有助細(xì)化參見:參考那些解決相似問題的模式,并且參考其他一些模式,有助細(xì)化設(shè)計(jì)原則參考:Design Principles and Design Patterns, Robert C. Martinhttp:/ - SOLIDu * *開放開放封閉原則(封閉原則(OCP, Open Closed PrincipleOCP, Open Closed Pr

8、inciple) 模塊應(yīng)該對擴(kuò)展開放,對更改封閉u 依賴倒置原則(依賴倒置原則(DIP, Dependency Inversion PrincipleDIP, Dependency Inversion Principle) 依賴抽象,不要依賴實(shí)現(xiàn);高層模塊(穩(wěn)定)不應(yīng)該依賴于底層模塊(變化),二者都應(yīng)該依賴于抽象;抽象(穩(wěn)定)不應(yīng)該依賴于實(shí)現(xiàn)細(xì)節(jié)(變化),實(shí)現(xiàn)細(xì)節(jié)應(yīng)該依賴于抽象u 單一職責(zé)原則(單一職責(zé)原則(SRP, Single Responsibility PrincipleSRP, Single Responsibility Principle) 一個(gè)類應(yīng)該僅有一個(gè)引起它變化的原因,應(yīng)該

9、只有一個(gè)職責(zé);每一個(gè)職責(zé)都是變化的一個(gè)軸線,如果一個(gè)類有多個(gè)職責(zé),這些職責(zé)就耦合在了一起u LiskovLiskov替換原則(替換原則(LSP, LSP, LiskovLiskov Substitution Principle Substitution Principle) 子類必須能夠替換它們的基類(IS-A);如果調(diào)用的是父類的話,那么換成子類也完全可以運(yùn)行u 接口隔離原則(接口隔離原則(ISP, Interface Segregation PrincipleISP, Interface Segregation Principle) 每一個(gè)接口應(yīng)該是一種角色;多個(gè)客戶特定的接口強(qiáng)于一個(gè)通用

10、目的的接口,不應(yīng)該強(qiáng)迫客戶程序依賴它們不用的方法面向?qū)ο笤O(shè)計(jì)原則(2)u * *最少知識原則(迪米特法則)最少知識原則(迪米特法則) 一個(gè)對象應(yīng)當(dāng)對其他對象有盡可能少的了解,不和陌生人說話。一個(gè)軟件實(shí)體應(yīng)當(dāng)盡可能少的與其他實(shí)體發(fā)生相互作用;每一個(gè)軟件單位對其他的單位都只有最少的知識,而且局限于那些與本單位密切相關(guān)的軟件單位。u 針對針對接口編程,而不是針對實(shí)現(xiàn)編程接口編程,而不是針對實(shí)現(xiàn)編程 客戶無需知道所使用對象的特定類型,只需要知道對象擁有客戶所期望的接口u 優(yōu)先使用對象組合,而不是類繼承優(yōu)先使用對象組合,而不是類繼承 類繼承通常為“白箱復(fù)用”,對象組合通常為“黑箱復(fù)用”。繼承在某種程度上

11、破壞了封裝性,子類父類耦合度高;而對象組合則只要求被組合的對象具有良好定義的接口,耦合度低。u 封裝變化點(diǎn)封裝變化點(diǎn) 使用封裝來創(chuàng)建對象之間的分界層,讓設(shè)計(jì)者可以在分界層的一側(cè)進(jìn)行修改,而不會(huì)對另一側(cè)產(chǎn)生不良的影響,從而實(shí)現(xiàn)層次間的松耦合。面向?qū)ο笤O(shè)計(jì)原則(3:包結(jié)構(gòu)原則)u The Release Reuse Equivalency PrincipleThe Release Reuse Equivalency Principle(REPREP) The granule of reuse is the granule of release(軟件包的粒度與可重用的粒度保持一致)u The Com

12、mon Closure PrincipleThe Common Closure Principle(CCPCCP) Classes that change together, belong together(一致變化的類,應(yīng)該屬于同一個(gè)包)u The Common Reuse PrincipleThe Common Reuse Principle(CRPCRP) Classes that arent reused together should not be grouped together(不被一起重用的類,不放到一個(gè)包里)高內(nèi)聚(Cohesion)面向?qū)ο笤O(shè)計(jì)原則(4:包結(jié)構(gòu)原則)u Th

13、e Acyclic Dependencies PrincipleThe Acyclic Dependencies Principle(ADPADP) The dependencies between packages must not form cycles(軟件包之間不能相互依賴,構(gòu)成依賴循環(huán))u The Stable Dependencies PrincipleThe Stable Dependencies Principle(SDPSDP) Depend in the direction of stability(包之間的依賴關(guān)系都應(yīng)該是穩(wěn)定方向依賴的,包要依賴的包要比自己更具穩(wěn)定性)u

14、 The Stable Abstractions PrincipleThe Stable Abstractions Principle(SAPSAP) Stable packages should be abstract packages(穩(wěn)定的包,應(yīng)該是抽象的包,以此帶來可變性)低耦合(Coupling)設(shè)計(jì)模式(Design Patterns)設(shè)計(jì)模式u 起源起源 Design Patterns: Elements of Reusable Object-Oriented Software,GOF23種設(shè)計(jì)模式。u 發(fā)展發(fā)展 增加了一些類別,最重要的是使涵蓋范圍擴(kuò)展到更具體的問題類型。例如:

15、 -Patterns in Java增加了解決涉及諸如并發(fā)等問題的模式, -Core J2EE Patterns主要關(guān)注使用Java2企業(yè)技術(shù)的多層應(yīng)用程序上的模式。GOF-23設(shè)計(jì)模式分類從目的來看從目的來看u 創(chuàng)建型模式(創(chuàng)建型模式(CreationalCreational):): 將對象的部分創(chuàng)建工作延遲到子類或者其他對象,從而應(yīng)對需求變化為對象創(chuàng)建時(shí)具體類型實(shí)現(xiàn)引來的沖擊。u 結(jié)構(gòu)型模式(結(jié)構(gòu)型模式(StructuralStructural):):通過類繼承或者對象組合獲得更靈活的結(jié)構(gòu),從而應(yīng)對需求變化為對象的結(jié)構(gòu)帶來的沖擊。u 行為型模式(行為型模式(BehavioralBehavi

16、oral):):通過類繼承或者對象組合來劃分類與對象間的職責(zé),從而應(yīng)對需求變化為多個(gè)交互的對象帶來的沖擊。從范圍來看從范圍來看u 類模式類模式處理類與子類的靜態(tài)關(guān)系u 對象對象模式模式處理對象間的動(dòng)態(tài)關(guān)系GOF-23設(shè)計(jì)模式概覽創(chuàng)建型結(jié)構(gòu)型行為型類Factory Method Adapter_Class InterpreterTemplate Method 對象Abstract FactoryBuilderPrototypeSingleton Adapter_ObjectBridgeCompositeDecoratorFacadeFlyweightProxy Chain of Responsi

17、bilityCommandIteratorMediatorMementoObserverStateStrategyVisitor 從封裝變化角度對模式分類u 對象創(chuàng)建對象創(chuàng)建 Factory Method Abstract Factory Prototype Builderu 組件組件協(xié)作協(xié)作 Template Method Observer / Event Strategyu 單一職責(zé)單一職責(zé) Decorator Bridgeu 對象對象性能性能 Singleton Flyweightu 接口接口隔離隔離 Facade Proxy Mediator Adaptoru 狀態(tài)變化狀態(tài)變化 Mem

18、ento Stateu 數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu) Composite Iterator Chain of Responsibilityu 行為變化行為變化 Command Visitoru 領(lǐng)域問題領(lǐng)域問題 Interpreter來源:祝成科技軟件開發(fā)培訓(xùn)“對象創(chuàng)建”模式u通過通過“對象創(chuàng)建對象創(chuàng)建”模式對象繞開模式對象繞開newnew,來避免對象創(chuàng)建(,來避免對象創(chuàng)建(newnew)過)過程中所導(dǎo)致的緊耦合(依賴具體類),從而支持對象創(chuàng)建的穩(wěn)定。程中所導(dǎo)致的緊耦合(依賴具體類),從而支持對象創(chuàng)建的穩(wěn)定。它是接口抽象之后的第一步工作。它是接口抽象之后的第一步工作。u典型模式典型模式 Factory M

19、ethod Abstract Factory Prototype BuilderFactory Method模式u舉例舉例 你是一個(gè)ATM機(jī)軟件的開發(fā)工程師,需要測試ATM軟件的存取款功能,但在測試時(shí)不想產(chǎn)生實(shí)際的銀行業(yè)務(wù),該怎么辦呢?public class ATMGui private Status doWithdrawal(Account account, float amount) Transaction transaction = new Transaction(); transaction.setSourceAccount(account); transaction.setDest

20、Account(myCashAccount(); transaction.setAmount(amount); cess(); if (transaction.successful() dispense(amount); return transaction.getStatus(); Public class ATMGuiTest public void testCheckingWithdrawal() float startingBalance = balanceForTestCheckingAccount(); AtmGui atm = new AtmGui(

21、); insertCardAndInputPin(atm); atm.pressButton(Withdraw); atm.pressButton(Checking); atm.pressButtons(1, 0, 0, 0, 0); assertContains($100.00, atm.getDisplayContents(); atm.pressButton(Continue); assertEquals(startingBalance - 100, balanceForTestCheckingAccount(); Factory Method模式Factory Method模式u動(dòng)機(jī)動(dòng)

22、機(jī) 在軟件系統(tǒng)中,經(jīng)常面臨著創(chuàng)建對象的工作;由于需求的變化,需要?jiǎng)?chuàng)建的對象的具體類型經(jīng)常變化。 如何應(yīng)對這種變化?如何繞過常規(guī)的對象創(chuàng)建方法(new),提供一種“封裝機(jī)制”來避免客戶程序和這種“具體對象創(chuàng)建工作”的緊耦合?u意圖意圖 定義一個(gè)用于創(chuàng)建對象的接口,讓子類決定實(shí)例化哪一個(gè)類。Factory Method使得一個(gè)類的實(shí)例化延遲到子類Factory Method模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 當(dāng)一個(gè)類不知道它所必須創(chuàng)建的對象的類的時(shí)候 當(dāng)一個(gè)類希望由它的子類來指定它所創(chuàng)建的對象的時(shí)候 當(dāng)類將創(chuàng)建對象的職責(zé)委托給多個(gè)幫助子類中的某一個(gè),并且你希望將哪一個(gè)幫助子類是代理者這一信息局部化的時(shí)候

23、。 解決“單個(gè)對象”的需求變化。缺點(diǎn)在于要求創(chuàng)建方法/參數(shù)相同Template Method,具有實(shí)際的邏輯和意義該類型對客戶端是否隱藏呢?Abstract Factory模式u舉例舉例 Java可以根據(jù)變成人員的要求改變界面風(fēng)格,如Windows風(fēng)格,Java風(fēng)格等,這是怎么做到的呢?Abstract Factory模式Abstract Factory模式u動(dòng)機(jī)動(dòng)機(jī) 在軟件系統(tǒng)中,經(jīng)常面臨著“一系列相互依賴的對象”的創(chuàng)建工作;同時(shí),由于需求的變化,往往存在更多系列對象的創(chuàng)建工作。 如何應(yīng)對這種變化?如何繞過常規(guī)的對象創(chuàng)建方法(new),提供一種“封裝機(jī)制”來避免客戶程序和這種“多系列具體對象

24、創(chuàng)建工作”的緊耦合?u意圖意圖 提供一個(gè)接口,讓該接口負(fù)責(zé)創(chuàng)建一系列“相關(guān)或者相互依賴的對象”,無需指定它們具體的類。Abstract Factory模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 一個(gè)系統(tǒng)要獨(dú)立于它的產(chǎn)品的創(chuàng)建、組合和表示時(shí)。 一個(gè)系統(tǒng)要由多個(gè)產(chǎn)品系列中的一個(gè)來配置時(shí)。 當(dāng)你要強(qiáng)調(diào)一系列相關(guān)的產(chǎn)品對象的設(shè)計(jì)以便進(jìn)行聯(lián)合使用時(shí)。 當(dāng)你提供一個(gè)產(chǎn)品類庫,而只想顯示它們的接口而不是實(shí)現(xiàn)時(shí)。 主要用于應(yīng)對“新系列”的需求變動(dòng)。缺點(diǎn)在于難以應(yīng)對“新對象”的需求變動(dòng)Prototype模式u舉例舉例 細(xì)胞通常具有非常復(fù)雜的結(jié)構(gòu)。在生物工程模擬細(xì)胞分裂時(shí),如何快速實(shí)現(xiàn)從一個(gè)細(xì)胞到兩個(gè)細(xì)胞的創(chuàng)建工作?Proto

25、type模式u動(dòng)機(jī)動(dòng)機(jī) 在軟件系統(tǒng)中,經(jīng)常面臨著“某些結(jié)構(gòu)復(fù)雜的對象”的創(chuàng)建工作;由于需求的變化,這些對象經(jīng)常面臨著劇烈的變化,但是它們卻擁有比較穩(wěn)定一致的接口。 如何應(yīng)對這種變化?如何向“客戶程序(使用這些對象的程序)”隔離出“這些易變對象”,從而使得“依賴這些易變對象的客戶程序”不隨著需求改變而改變?u意圖意圖 使用原型實(shí)例指定創(chuàng)建對象的種類,然后通過拷貝這些原型來創(chuàng)建新的對象。Prototype模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 當(dāng)要實(shí)例化的類是在運(yùn)行時(shí)刻指定時(shí),例如,通過動(dòng)態(tài)裝載;或者 為了避免創(chuàng)建一個(gè)與產(chǎn)品類層次平行的工廠類層次時(shí);或者 當(dāng)一個(gè)類的實(shí)例只能有幾個(gè)不同狀態(tài)組合中的一種時(shí)。建立

26、相應(yīng)數(shù)目的原型并克隆它們可能比每次用合適的狀態(tài)手工實(shí)例化該類更方便一些。Builder模式u舉例舉例 ProtocolBuffer中,要實(shí)現(xiàn)協(xié)議類的快速序列化與反序列化,在協(xié)議類的實(shí)現(xiàn)中封裝了非常復(fù)雜的數(shù)據(jù)結(jié)構(gòu),而ProtocolBuffer的使用者,不希望用很復(fù)雜的方法來創(chuàng)建該協(xié)議類。message Request / RPC service full name required string service_name = 1; / RPC method name required string method_name = 2; / RPC request proto required by

27、tes request_proto = 3;Request.Builder builder = Request.newBuilder();builder.setServiceName();builder.setMethodName();builder.setRequestProto();Request request = builder.build();Builder模式u場景場景 在軟件系統(tǒng)中,有時(shí)候面臨著“一個(gè)復(fù)雜對象”的創(chuàng)建工作,其通常由各個(gè)部分的子對象用一定的算法構(gòu)成;由于需求的變化,這個(gè)復(fù)雜對象的各個(gè)部分經(jīng)常面臨著劇烈的變化,但是將它們組合在一起的算法卻相對穩(wěn)定。Builder模式u

28、動(dòng)機(jī)動(dòng)機(jī) 在軟件系統(tǒng)中,有時(shí)候面臨著“一個(gè)復(fù)雜對象”的創(chuàng)建工作,其通常由各個(gè)部分的子對象用一定的算法構(gòu)成;由于需求的變化,這個(gè)復(fù)雜對象的各個(gè)部分經(jīng)常面臨著劇烈的變化,但是將它們組合在一起的算法卻相對穩(wěn)定。 如何應(yīng)對這種變化?如何提供一種“封裝機(jī)制”來隔離出“復(fù)雜對象的各個(gè)部分”的變化,從而保持系統(tǒng)中的“穩(wěn)定構(gòu)建算法”不隨著需求改變而改變?u意圖意圖 將一個(gè)復(fù)雜對象的構(gòu)建與其表示相分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。Builder模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 當(dāng)創(chuàng)建復(fù)雜對象的算法應(yīng)該獨(dú)立于該對象的組成部分以及它們的裝配方式時(shí)。 當(dāng)構(gòu)造過程必須允許被構(gòu)造的對象有不同的表示時(shí)。 (變化點(diǎn)在哪

29、里,封裝在哪里)主要在于 “分步驟構(gòu)建一個(gè)復(fù)雜的對象” 。其中“分步驟”是一個(gè)穩(wěn)定的算法,復(fù)雜對象的各個(gè)部分則經(jīng)常變化。缺點(diǎn)在于難以應(yīng)對“分步驟構(gòu)建算法”的需求變動(dòng)?!敖M件協(xié)作”模式u現(xiàn)代軟件專業(yè)分工之后的第一個(gè)結(jié)果是現(xiàn)代軟件專業(yè)分工之后的第一個(gè)結(jié)果是“框架與應(yīng)用程序的劃分框架與應(yīng)用程序的劃分”,“組件協(xié)作組件協(xié)作”模式通過晚期綁定,來實(shí)現(xiàn)框架與應(yīng)用程序之間的松模式通過晚期綁定,來實(shí)現(xiàn)框架與應(yīng)用程序之間的松耦合,是二者之間協(xié)作時(shí)常用的模式耦合,是二者之間協(xié)作時(shí)常用的模式。u典型模式典型模式 Template Method Observer / Event StrategyTemplate Me

30、thod模式u舉例舉例對于寫Servlet的開發(fā)人員,常常只需要指定如何處理Get、Post、Put等幾個(gè)少數(shù)的方法就可以了,而對于一些復(fù)雜的處理過程,如把字節(jié)流轉(zhuǎn)換為ServletRequest對象,或從字節(jié)流中識別不同請求類型并分發(fā)到合適的處理方法,可以一概都不需要知道。public abstract class HttpServlet extends GenericServlet implements java.io.Serializable protected void doGet(HttpServletRequest req, HttpServletResponse resp)thr

31、ows ServletException, IOException /略略 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException String method = req.getMethod(); / 取得請求的方法取得請求的方法 if (method.equals(METHOD_GET) / HTTP GET / 略略. doGet(req, resp); / 略略 . else if (method.equals(METHOD_

32、HEAD) / HTTP HEAD / 略略 . doHead(req, resp); else if (method.equals(METHOD_POST) / HTTP POST / 略略 . doPost(req, resp); else if (method.equals(METHOD_PUT) / HTTP PUT / 略略 . Template Method模式u動(dòng)機(jī)動(dòng)機(jī) 在軟件構(gòu)建過程中,對于某一項(xiàng)任務(wù),它常常有穩(wěn)定的整體操作結(jié)構(gòu),但各個(gè)子步驟卻有很多改變的需求,或者由于固有的原因(比如框架與應(yīng)用之間的關(guān)系)而無法和任務(wù)的整體結(jié)構(gòu)同時(shí)實(shí)現(xiàn)。 如何在確定穩(wěn)定操作結(jié)構(gòu)的前提下,來靈活

33、應(yīng)對各個(gè)子步驟的變化或者晚期實(shí)現(xiàn)需求?u意圖意圖 定義一個(gè)操作中的算法的骨架(穩(wěn)定),而將一些步驟(變化)延遲到子類中。Template Method使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義(override 重寫)該算法的某些特定步驟。Template Method模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 一次性實(shí)現(xiàn)一個(gè)算法的不變的部分,將可變的行為留給子類來實(shí)現(xiàn)。 各子類中公共的行為應(yīng)被提取出來并集中到一個(gè)公共父類中以避免代碼重復(fù)。是“重分解以一般化”的一個(gè)很好的例子。 控制子類擴(kuò)展。模板方法只在特定點(diǎn)調(diào)用“hook”操作(參見效果一節(jié)),這樣就只允許在這些點(diǎn)進(jìn)行擴(kuò)展。 被Template Meth

34、od調(diào)用的虛方法一般推薦設(shè)置為protected。Observer / Event模式u舉例舉例Java NIO非堵塞技術(shù)是如何實(shí)現(xiàn)的?以下是采用Netty創(chuàng)建服務(wù)端的代碼片段。public class HelloServer public static void main(String args) / Server服務(wù)啟動(dòng)器 ServerBootstrap bootstrap = new ServerBootstrap(); / 設(shè)置一個(gè)處理客戶端消息和各種消息事件的類(Handler) bootstrap .setPipelineFactory(new ChannelPipelineFac

35、tory() Override public ChannelPipeline getPipeline() throws Exception return Channels .pipeline(new HelloServerHandler(); ); / 開放8000端口供客戶端訪問。 bootstrap.bind(new InetSocketAddress(8000); private static class HelloServerHandler extends SimpleChannelHandler / 當(dāng)有客戶端綁定到服務(wù)端的時(shí)候觸發(fā),打印Hello world, Im server.

36、 Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) System.out.println(Hello world, Im server.); Observer / Event模式u動(dòng)機(jī)動(dòng)機(jī) 在軟件構(gòu)建過程中,我們需要為某些對象建立一種“通知依賴關(guān)系”,即一個(gè)對象(目標(biāo)對象)的狀態(tài)發(fā)生改變,所有的依賴對象(觀察者對象)都將得到通知。如果這樣的依賴關(guān)系過于緊密,將使軟件不能很好地抵御變化。 使用面向?qū)ο蠹夹g(shù),可以將這種依賴關(guān)系弱化,并形成一種穩(wěn)定的依賴關(guān)系。從而實(shí)現(xiàn)軟件體系結(jié)構(gòu)

37、的松耦合。u意圖意圖 定義對象間的一種一對多的依賴關(guān)系,以便當(dāng)一個(gè)對象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對象都得到通知并自動(dòng)更新Observer / Event模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 當(dāng)一個(gè)抽象模型有兩個(gè)方面, 其中一個(gè)方面依賴于另一方面。將這二者封裝在獨(dú)立的對象中以使它們可以各自獨(dú)立地改變和復(fù)用。 當(dāng)對一個(gè)對象的改變需要同時(shí)改變其它對象, 而不知道具體有多少對象有待改變。 當(dāng)一個(gè)對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不希望這些對象是緊密耦合的。Strategy模式u舉舉例例負(fù)載均衡是分布式計(jì)算中常見的問題,實(shí)現(xiàn)負(fù)載均衡有很多不同算法,如隨機(jī)算法、RoundRobi

38、n算法、一致性Hash算法等。(1) 運(yùn)維人員可能根據(jù)需要隨時(shí)調(diào)整負(fù)載均衡策略;(2) 將來可能有更新更好的負(fù)載均衡算法。我們應(yīng)該如何設(shè)計(jì)我們的分布式框架? Protected Node getNode(LoadBalanceType type) if (RANDOM = type) return getRandomNode(); else if (ROUNDROBIN = type) return getRoundRobinNode(); else if Strategy模式u動(dòng)機(jī)動(dòng)機(jī) 在軟件構(gòu)建過程中,某些對象使用的算法可能多種多樣,經(jīng)常改變,如果將這些算法都編碼到對象中,將會(huì)使對象變得異

39、常復(fù)雜;而且有時(shí)候支持不使用的算法也是一個(gè)性能負(fù)擔(dān)。 如何在運(yùn)行時(shí)根據(jù)需要透明地更改對象的算法?將算法與對象本身解耦,從而避免上述問題?u意圖意圖 定義一系列算法,把它們一個(gè)個(gè)封裝起來,并且使它們可互相替換。該模式使得算法可獨(dú)立于使用它的客戶而變化。Strategy模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 “策略”及其子類為組件提供了一系列可重用的算法,從而可以使得類型在運(yùn)行時(shí)方便地根據(jù)需要在各個(gè)算法間進(jìn)行切換。 提供了用條件判斷語句以外的另一種選擇,消除條件判斷語句,就是在解耦合。 算法使用客戶不應(yīng)該知道的數(shù)據(jù)??墒褂貌呗阅J揭员苊獗┞稄?fù)雜的、與算法相關(guān)的數(shù)據(jù)結(jié)構(gòu)。 “單一職責(zé)”模式u在軟件組件的設(shè)計(jì)中

40、在軟件組件的設(shè)計(jì)中”,如果責(zé)任劃分的不清晰,使用繼承得到的,如果責(zé)任劃分的不清晰,使用繼承得到的結(jié)果往往是隨著需求的變化,子類急劇膨脹,同時(shí)充斥著重復(fù)代碼,結(jié)果往往是隨著需求的變化,子類急劇膨脹,同時(shí)充斥著重復(fù)代碼,這時(shí)候的關(guān)鍵是劃清責(zé)任這時(shí)候的關(guān)鍵是劃清責(zé)任。u典型模式典型模式 Decorator BridgeDecorator模式u舉例舉例SiteMesh是由一個(gè)基于Web頁面布局、裝飾以及與現(xiàn)存Web應(yīng)用整合的框架。它能幫助我們在由大量頁面構(gòu)成的項(xiàng)目中創(chuàng)建一致的頁面布局和外觀,如一致的導(dǎo)航條,一致的banner,一致的版權(quán),等等。 它不僅僅能處理動(dòng)態(tài)的內(nèi)容,如jsp,php,asp等產(chǎn)生

41、的內(nèi)容,它也能處理靜態(tài)的內(nèi)容,如htm的內(nèi)容,使得它的內(nèi)容也符合你的頁面結(jié)構(gòu)的要求。甚至于它能將HTML文件象include那樣將該文件作為一個(gè)面板的形式嵌入到別的文件中去。所有的這些,都是GOF的Decorator模式的最生動(dòng)的實(shí)現(xiàn)。盡管它是由java語言來實(shí)現(xiàn)的,但它能與其他Web應(yīng)用很好地集成。Decorator模式u動(dòng)機(jī)動(dòng)機(jī) 在某些情況下我們可能會(huì)“過度地使用繼承來擴(kuò)展對象的功能”,由于繼承為類型引入的靜態(tài)特質(zhì),使得這種擴(kuò)展方式缺乏靈活性;并且隨著子類的增多(擴(kuò)展功能的增多),各種子類的組合(擴(kuò)展功能的組合)會(huì)導(dǎo)致更多子類的膨脹(多繼承)。 如何使“對象功能的擴(kuò)展”能夠根據(jù)需要來動(dòng)態(tài)地

42、實(shí)現(xiàn)?同時(shí)避免“擴(kuò)展功能的增多”帶來的子類膨脹問題?從而使得任何“功能擴(kuò)展變化”所導(dǎo)致的影響將為最低?u意圖意圖 動(dòng)態(tài)地給一個(gè)對象增加一些額外的職責(zé)。就增加功能而言,Decorator模式比生成子類更為靈活。Decorator模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 在不影響其他對象的情況下,以動(dòng)態(tài)、透明的方式給單個(gè)對象添加職責(zé)。 處理那些可以撤消的職責(zé)。 當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時(shí)。一種情況是,可能有大量獨(dú)立的擴(kuò)展,為支持每一種組合將產(chǎn)生大量的子類,子類數(shù)目呈爆炸性增長。另一種情況可能是因?yàn)轭惗x被隱藏,或類定義不能用于生成子類。 并非解決“多子類衍生的多繼承”問題,應(yīng)用的要點(diǎn)在于解決“主體類在

43、多個(gè)方向上的擴(kuò)展能力”是為“裝飾”的含義Bridge模式u舉例舉例手機(jī)品牌和軟件是兩個(gè)概念,不同的軟件可以在不同的手機(jī)上,不同的手機(jī)可以有相同的軟件,兩者都具有很大的變動(dòng)性。如果我們單獨(dú)以手機(jī)品牌或手機(jī)軟件為基類來進(jìn)行繼承擴(kuò)展的話,無疑會(huì)使類的數(shù)目劇增并且耦合性很高。這時(shí)候我們應(yīng)該怎么辦?(如果更改品牌或增加軟件都會(huì)增加很多的變動(dòng))兩種方式的結(jié)構(gòu)如下:手機(jī)這個(gè)例子可能很直觀,想想關(guān)于狀態(tài)的例子?當(dāng)我們需要各種不同狀態(tài)的復(fù)雜組合時(shí),考慮一下Bridge模式吧。Bridge模式Bridge模式u動(dòng)機(jī)動(dòng)機(jī) 由于某些類型的固有邏輯,使得它們具有兩個(gè)變化的維度,乃至多個(gè)緯度的變化。 如何應(yīng)對這種“多維度

44、的變化”?如何利用面向?qū)ο蠹夹g(shù)來使得類型可以輕松地沿著兩個(gè)乃至多個(gè)方向變化,而不引入額外的復(fù)雜度?u意圖意圖 將抽象部分與實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。Bridge模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 使用“對象間的組合關(guān)系”解耦了抽象和實(shí)現(xiàn)之間固有的綁定關(guān)系,使得抽象和實(shí)現(xiàn)可以沿著各自的維度來變化。所謂抽象和實(shí)現(xiàn)沿著各自緯度的變化,即“子類化”它們。 有時(shí)候類似于多繼承方案,但是多繼承方案往往違背單一職責(zé)原則(即一個(gè)類只有一個(gè)變化的原因),復(fù)用性比較差。Bridge模式是比多繼承方案更好的解決方法。 應(yīng)用一般在“兩個(gè)非常強(qiáng)的變化強(qiáng)度”“對象性能”模式u面向?qū)ο蠛芎玫亟鉀Q了面向?qū)ο蠛芎玫亟鉀Q了

45、“抽象抽象”的問題,但是必不可免地要付出一的問題,但是必不可免地要付出一定的代價(jià)。對于通常情況來講,面向?qū)ο蟮某杀敬蠖伎梢院雎圆挥?jì)。定的代價(jià)。對于通常情況來講,面向?qū)ο蟮某杀敬蠖伎梢院雎圆挥?jì)。但是某些情況,面向?qū)ο笏鶐淼某杀颈仨氈?jǐn)慎處理但是某些情況,面向?qū)ο笏鶐淼某杀颈仨氈?jǐn)慎處理。u典型模式典型模式 Singleton FlyweightSingleton模式u舉例舉例每一個(gè)Java程序?qū)嶋H上都是啟動(dòng)了一個(gè)JVM進(jìn)程。我們?nèi)绾卧贘ava程序中獲取當(dāng)前JVM的狀態(tài)呢? Runtime類封裝了運(yùn)行時(shí)的環(huán)境。每個(gè) Java 應(yīng)用程序都有一個(gè) Runtime 類實(shí)例,使應(yīng)用程序能夠與其運(yùn)行的環(huán)境相

46、連接。 一般不能實(shí)例化一個(gè)Runtime對象,應(yīng)用程序也不能創(chuàng)建自己的 Runtime 類實(shí)例,但可以通過 getRuntime 方法獲取當(dāng)前Runtime運(yùn)行時(shí)對象的引用。 一旦得到了一個(gè)當(dāng)前的Runtime對象的引用,就可以調(diào)用Runtime對象的方法去控制Java虛擬機(jī)的狀態(tài)和行為。 Runtime run = Runtime.getRuntime();System.out.println(“JVM最大內(nèi)存:” + run.maxMemory();System.out.println(“JVM空閑內(nèi)存:” + run.freeMemory();Singleton模式u動(dòng)機(jī)動(dòng)機(jī) 在軟件系統(tǒng)

47、中,經(jīng)常有這樣一些特殊的類,必須保證它們在系統(tǒng)中只存在一個(gè)實(shí)例,才能確保它們的邏輯正確性、以及良好的效率。 如何繞過常規(guī)的構(gòu)造器,提供一種機(jī)制來保證一個(gè)類只有一個(gè)實(shí)例?這應(yīng)該是類設(shè)計(jì)者的責(zé)任,而不是使用者的責(zé)任。u意圖意圖 保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)該實(shí)例的全局訪問點(diǎn)。Singleton模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 當(dāng)類只能有一個(gè)實(shí)例而且客戶可以從一個(gè)眾所周知的訪問點(diǎn)訪問它時(shí)。 當(dāng)這個(gè)唯一實(shí)例應(yīng)該是通過子類化可擴(kuò)展的,并且客戶應(yīng)該無需更改代碼就能使用一個(gè)擴(kuò)展的實(shí)例時(shí)。 實(shí)例構(gòu)造器可以設(shè)置為protected以允許子類派生;一般不要支持序列化和ICloneable接口,因?yàn)橛锌赡軐?dǎo)致多個(gè)

48、對象實(shí)例。 不能應(yīng)對多線程環(huán)境:在多線程環(huán)境下,仍然有可能得到多個(gè)實(shí)例對象(需要加信號量)Flyweight模式u舉例舉例 字符串在大多數(shù)應(yīng)用程序中的出現(xiàn)頻率較高,Java必須對字符串的執(zhí)行進(jìn)行優(yōu)化以保證效率。執(zhí)行以下代碼,看看結(jié)果和你預(yù)期的是否一致?public class StringTest public static void main(String args) String fly = fly, weight = weight; String fly2 = fly, weight2 = weight; System.out.println(fly = fly2); / ? Syste

49、m.out.println(weight = weight2); / ? String distinctString = fly + weight; System.out.println(distinctString = flyweight); / ? String flyweight = (fly + weight).intern(); System.out.println(flyweight = flyweight); / ? Flyweight的另一個(gè)典型例子是Java Swing。請查閱相關(guān)資料,指出Swing樹的速度是如何做到這么快的。(秘密在TreeCellRenderer.get

50、TreeCellRendererComponent()里)Flyweight模式u動(dòng)機(jī)動(dòng)機(jī) 采用純粹對象方案的問題在于大量細(xì)粒度的對象會(huì)很快充斥在系統(tǒng)中,從而帶來很高的運(yùn)行時(shí)代價(jià)主要指內(nèi)存需求方面的代價(jià)。 如何在避免大量細(xì)粒度對象問題的同時(shí),讓外部客戶程序仍然能夠透明地使用面向?qū)ο蟮姆绞絹磉M(jìn)行操作?u意圖意圖 運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對象。Flyweight模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 主要解決面向?qū)ο蟮拇鷥r(jià)問題,一般不觸及面向?qū)ο蟮某橄笮詥栴}。 采用對象共享的做法降低系統(tǒng)中對象的個(gè)數(shù),從而降低細(xì)粒度對象給系統(tǒng)帶來的內(nèi)存壓力。具體實(shí)現(xiàn)時(shí),要注意對象狀態(tài)的處理。對象的大多數(shù)狀態(tài)都可變?yōu)?/p>

51、外部狀態(tài),如果刪除對象的外部狀態(tài),那么可以用相對較少的共享對象取代很多組對象。 對象的數(shù)量太大從而導(dǎo)致對象內(nèi)存開銷加大什么樣的數(shù)量才算大?需要根據(jù)具體應(yīng)用情況進(jìn)行評估,而不能憑空臆斷?!敖涌诟綦x”模式u在組件構(gòu)建過程中,某些接口之間直接的依賴常常會(huì)帶來很多問題、在組件構(gòu)建過程中,某些接口之間直接的依賴常常會(huì)帶來很多問題、甚至根本無法實(shí)現(xiàn)。采用添加一層間接接口,來隔離本來互相緊密甚至根本無法實(shí)現(xiàn)。采用添加一層間接接口,來隔離本來互相緊密關(guān)聯(lián)的接口是一種常見的解決方案關(guān)聯(lián)的接口是一種常見的解決方案。u典型模式典型模式 Facade Proxy Mediator AdaptorFacade模式u舉例

52、舉例汽車啟動(dòng)時(shí),電瓶中的電能轉(zhuǎn)化成起動(dòng)機(jī)機(jī)械能,從而由曲軸帶動(dòng)發(fā)動(dòng)機(jī)轉(zhuǎn)動(dòng),同時(shí)點(diǎn)火、噴油在缸內(nèi)燃燒,作工。發(fā)動(dòng)機(jī)是一種能量轉(zhuǎn)換機(jī)構(gòu),它將燃料燃燒產(chǎn)生的熱能轉(zhuǎn)變成機(jī)械能,發(fā)動(dòng)機(jī)的一個(gè)工作循環(huán)包括四個(gè)過程:進(jìn)氣、壓縮、作功、排氣。發(fā)動(dòng)機(jī)有很多種,如四行程汽油機(jī)、二行程汽油機(jī)等,工作機(jī)制又各有不同,其實(shí)說了這么多,開車司機(jī)點(diǎn)火的時(shí)候所要做的就是,把點(diǎn)火鑰匙插入鑰匙孔,輕輕一轉(zhuǎn)就可以了。Facade模式u動(dòng)機(jī)動(dòng)機(jī) 上述A方案的問題在于組件的客戶和組件中各種復(fù)雜的子系統(tǒng)有了過多的耦合,隨著外部客戶程序和各子系統(tǒng)的演化,這種過多的耦合面臨很多變化的挑戰(zhàn)。 如何簡化外部客戶程序和系統(tǒng)間的交互接口?如何將外部

53、客戶程序的演化和內(nèi)部子系統(tǒng)的變化之間的依賴相互解耦?u意圖意圖 為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,F(xiàn)aade模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。A方案方案B方案方案Facade模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 簡化了整個(gè)組件系統(tǒng)的接口,同時(shí)對于組件內(nèi)部與外部客戶程序來說,從某種程度上也達(dá)到了一種“解耦”的效果內(nèi)部子系統(tǒng)的任何變化不會(huì)影響到Faade接口的變化。 更注重從架構(gòu)的層次去看整個(gè)系統(tǒng),而不是單個(gè)類的層次 并非一個(gè)集裝箱,可以任意地放進(jìn)任何多個(gè)對象。Faade模式中組件的內(nèi)部應(yīng)該是“相互耦合關(guān)系比較大的一系列組件”,而不是一個(gè)簡單的功能集合。Proxy模式u舉例

54、舉例(1)遠(yuǎn)程代理(Remote Proxy)(2)虛代理(Virtual Proxy)(3)保護(hù)代理(Protection Proxy)(4)智能指針(Smart Reference)Proxy模式u動(dòng)機(jī)動(dòng)機(jī) 在面向?qū)ο笙到y(tǒng)中,有些對象由于某種原因(比如對象創(chuàng)建的開銷很大,或者某些操作需要安全控制,或者需要進(jìn)程外的訪問等),直接訪問會(huì)給使用者、或者系統(tǒng)結(jié)構(gòu)帶來很多麻煩。 如何在不失去透明操作對象的同時(shí)來管理/控制這些對象特有的復(fù)雜性?增加一層間接層是軟件開發(fā)中常見的解決方式。u意圖意圖 為其他對象提供一種代理以控制對這個(gè)對象的訪問。Proxy模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 在需要用比較通用和復(fù)

55、雜的對象指針代替簡單的指針的時(shí)候,使用Proxy模式。 具體實(shí)現(xiàn)方法、實(shí)現(xiàn)粒度都相差很大??赡茚槍蝹€(gè)對象也可能針對組件模塊做proxy 并不一定要求保持接口的一致性,只要能夠?qū)崿F(xiàn)間接控制,有時(shí)候損失一些透明性是可以接受的Mediator模式u舉例舉例試想繁忙的首都國際機(jī)場,每天進(jìn)出港航班達(dá)上千次,如果沒有機(jī)場飛行控制系統(tǒng)(就是傳說中的塔臺(tái))是難以想象的。塔臺(tái)具有絕對的權(quán)利,他可以控制任何一架飛機(jī)的起飛和降落時(shí)間以及地方,而飛機(jī)和飛機(jī)之間不允許通信。同事關(guān)系中介者M(jìn)ediator模式u動(dòng)機(jī)動(dòng)機(jī) 在軟件構(gòu)建過程中,經(jīng)常會(huì)出現(xiàn)多個(gè)對象互相關(guān)聯(lián)交互的情況,對象之間常常會(huì)維持一種復(fù)雜的引用關(guān)系,如果遇

56、到一些需求的更改,這種直接的引用關(guān)系將面臨不斷的變化。 在這種情況下,我們可使用一個(gè)“中介對象”來管理對象間的關(guān)聯(lián)關(guān)系,避免相互交互的對象之間的緊耦合引用關(guān)系,從而更好地抵御變化。u意圖意圖 用一個(gè)中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式的相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。Mediator模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 一組對象以定義良好但是復(fù)雜的方式進(jìn)行通信。產(chǎn)生的相互依賴關(guān)系結(jié)構(gòu)混亂且難以理解。 一個(gè)對象引用其他很多對象并且直接與這些對象通信,導(dǎo)致難以復(fù)用該對象。 想定制一個(gè)分布在多個(gè)類中的行為,而又不想生成太多的子類。 將多個(gè)對象間復(fù)雜的關(guān)聯(lián)關(guān)系

57、解耦,將多個(gè)對象間的控制邏輯進(jìn)行集中管理。Faade是解耦系統(tǒng)外到系統(tǒng)內(nèi)(單向)的對象關(guān)聯(lián)關(guān)系;Mediator模式是解耦系統(tǒng)內(nèi)各個(gè)對象之間(雙向)的關(guān)聯(lián)關(guān)系。 隨著控制邏輯的復(fù)雜化,可能需要對Mediator具體對象進(jìn)行分解處理。Adapter模式u舉例舉例電源插座在不同國家有多種標(biāo)準(zhǔn),如國標(biāo)、美標(biāo)、英標(biāo)、南非標(biāo)、德標(biāo)、意標(biāo)等,此外各國生活用電電壓標(biāo)準(zhǔn)也各有不同,如美國的生活用電電壓是110V,而中國的電壓是220V。如果要在中國使用美國電器,你有什么好主意嗎?我們有多款OBD設(shè)備,協(xié)議都各不相同,并且在某些項(xiàng)目中客戶還不排除引入第三方廠商的OBD硬件,我們的OBD核心平臺(tái)應(yīng)該采取什么樣的設(shè)

58、計(jì)模式呢?Adapter模式u動(dòng)機(jī)動(dòng)機(jī) 在軟件系統(tǒng)中,由于應(yīng)用環(huán)境的變化,常常需要將“一些現(xiàn)存的對象”放在新的環(huán)境中應(yīng)用,但是新環(huán)境要求的接口是這些現(xiàn)存對象所不滿足的。 如何應(yīng)對這種“遷移的變化”?如何既能利用現(xiàn)有對象的良好實(shí)現(xiàn),同時(shí)又能滿足新的應(yīng)用環(huán)境所要求的接口?u意圖意圖 將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另一個(gè)接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。Adapter模式u結(jié)構(gòu)結(jié)構(gòu)u適用性適用性 你想使用一個(gè)已經(jīng)存在的類,而它的接口不符合你的需求。 你想創(chuàng)建一個(gè)可以復(fù)用的類,該類可以與其他不相關(guān)的類或不可預(yù)見的類(即那些接口可能不一定兼容的類)協(xié)同工作

59、。 (僅適用于對象Adaptor)你想使用一些已經(jīng)存在的子類,但是不可能對每一個(gè)都進(jìn)行子類化以匹配它們的接口。對象適配器可以適配它的父類接口。 Adapter模式本身要求我們盡可能地使用“面向接口的編程風(fēng)格”,這樣才能在后期很方便地適配?!皩ο髮ο蟆边m配器適配器推薦推薦“狀態(tài)變化”模式u在組件構(gòu)建過程中,某些對象的狀態(tài)經(jīng)常面臨變化,如何對這些變在組件構(gòu)建過程中,某些對象的狀態(tài)經(jīng)常面臨變化,如何對這些變化進(jìn)行有效的管理?同時(shí)又維持高層模塊的穩(wěn)定?化進(jìn)行有效的管理?同時(shí)又維持高層模塊的穩(wěn)定?“狀態(tài)變化狀態(tài)變化”模模式為這一問題提供了一種解決方案式為這一問題提供了一種解決方案。u典型模式典型模式 M

60、emento StateMemento模式u舉例舉例我們玩單機(jī)游戲的時(shí)候總會(huì)遇到MM大人的各種事情,一會(huì)兒陪逛街,一會(huì)兒去打個(gè)醬油,會(huì)耽誤我們玩游戲的進(jìn)程,但是此時(shí)我們能有“保存游戲”這個(gè)寶貝,我們的主基地就不會(huì)在我們打醬油的時(shí)候被對手拆掉?!氨4嬗螒颉钡墓δ芷鋵?shí)就是備忘錄模式的很好應(yīng)用,它在不破壞封裝的前提下,捕獲一個(gè)對象的內(nèi)部狀態(tài),并在該對象之外保存這個(gè)狀態(tài)。這樣以后就可以把該對象恢復(fù)到原先保存的狀態(tài)。你能想到其它類似的例子嗎?Memento模式u動(dòng)機(jī)動(dòng)機(jī) 在軟件構(gòu)建過程中,某些對象的狀態(tài)在轉(zhuǎn)換過程中,可能由于某種需要,要求程序能夠回溯到對象之前處于某個(gè)點(diǎn)時(shí)的狀態(tài)。如果使用一些公有接口來讓

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論