面向?qū)ο蠓治雠c設(shè)計(jì)(7)-高級設(shè)計(jì)原則與設(shè)計(jì)模式.ppt_第1頁
面向?qū)ο蠓治雠c設(shè)計(jì)(7)-高級設(shè)計(jì)原則與設(shè)計(jì)模式.ppt_第2頁
面向?qū)ο蠓治雠c設(shè)計(jì)(7)-高級設(shè)計(jì)原則與設(shè)計(jì)模式.ppt_第3頁
面向?qū)ο蠓治雠c設(shè)計(jì)(7)-高級設(shè)計(jì)原則與設(shè)計(jì)模式.ppt_第4頁
面向?qū)ο蠓治雠c設(shè)計(jì)(7)-高級設(shè)計(jì)原則與設(shè)計(jì)模式.ppt_第5頁
已閱讀5頁,還剩49頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、面向?qū)ο蠓治雠c設(shè)計(jì),高級設(shè)計(jì)原則與設(shè)計(jì)模式,內(nèi)容提要,高級設(shè)計(jì)原則 設(shè)計(jì)模式 AOP編程,面向?qū)ο笤O(shè)計(jì)原則-OCP,開放封閉原則(OCP) 類模塊應(yīng)該是可擴(kuò)展的,但是不可修改 Closed for Modification; Open for Extension (對擴(kuò)展開放,對更改封閉) OCP說明了軟件設(shè)計(jì)應(yīng)該盡可能地使架構(gòu)穩(wěn)定而又容易滿足不同的需求。,如何在OO中引入OCP?,把對實(shí)體的依賴改為對抽象的依賴 .,OCP舉例1-收音機(jī),收聽節(jié)目時(shí)需要打開收音機(jī)電源,對準(zhǔn)電臺頻率和進(jìn)行音量調(diào)節(jié)。 但是對于不同的收音機(jī),實(shí)現(xiàn)這三個(gè)步驟的細(xì)節(jié)往往有所不同。 不太可能針對每種不同類型的收音機(jī)通過一

2、個(gè)收音機(jī)類來實(shí)現(xiàn)(通過重載)這些不同的操作方式。,OCP舉例1-收音機(jī)(續(xù)),定義一個(gè)收音機(jī)接口,提供開機(jī)、關(guān)機(jī)、增加頻率、降低頻率、增加音量、降低音量六個(gè)抽象方法。 不同的收音機(jī)繼承并實(shí)現(xiàn)這六個(gè)抽象方法。 新增收音機(jī)類型不會影響其它原有的收音機(jī)類型,收音機(jī)類型擴(kuò)展極為方便。 已存在的收音機(jī)類型在修改其操作方法時(shí)也不會影響到其它類型的收音機(jī)。,OCP舉例1-收音機(jī)(續(xù)),OCP舉例2-賽車,OCP舉例2-賽車(續(xù)),OCP總結(jié),OCP是OO設(shè)計(jì)原則中高層次的原則,其余的原則對OCP提供了不同程度的支持。 為了實(shí)現(xiàn)OCP,我們會自覺或者不自覺地用到其它原則或是諸如Bridge、Decorator

3、等設(shè)計(jì)模式。 對于一個(gè)應(yīng)用系統(tǒng)而言,實(shí)現(xiàn)OCP并不是設(shè)計(jì)目的,我們所希望的只是一個(gè)穩(wěn)定的架構(gòu)。所以對OCP的追求也應(yīng)該適可而止,不要陷入過渡設(shè)計(jì)。,面向?qū)ο笤O(shè)計(jì)原則-SRP,Single Responsibility Principle 單一職責(zé)原則 所謂單一職責(zé),就是一個(gè)設(shè)計(jì)元素只做一件事 “單一職責(zé)”就是要在設(shè)計(jì)中為每種職責(zé)設(shè)計(jì)一個(gè)類,彼此保持正交,互不干涉。 (二重奏),SRP舉例-調(diào)制解調(diào)器,SRP總結(jié),違反SRP通常是由于過于“真實(shí)”地設(shè)計(jì)了一個(gè)類所造成的。 因此,解決辦法是往更高一層進(jìn)行抽象化提取,將對某個(gè)具體類的依賴改變?yōu)閷σ唤M接口或抽象類的依賴。,面向?qū)ο笤O(shè)計(jì)原則-LSP,Li

4、skov于1987年提出了一個(gè)關(guān)于繼承的原則“Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.” “繼承必須確保超類所擁有的性質(zhì)在子類中仍然成立?!?也就是說,當(dāng)一個(gè)子類的實(shí)例應(yīng)該能夠替換任何其超類的實(shí)例時(shí),它們之間才具有is-A關(guān)系。,LSP原則實(shí)質(zhì),一個(gè)對象是一組狀態(tài)和一系列行為的組合體。狀態(tài)是對象的內(nèi)在特性,行為是對象的外在特性。 LSP所表述的就是在同一個(gè)繼承體系中的對象應(yīng)該有共同的行為特征。 這一點(diǎn)上,表明了OO的繼承與日

5、常生活中的繼承的本質(zhì)區(qū)別。,LSP舉例,如何確保對象的行為?,每個(gè)方法調(diào)用之前,該方法應(yīng)該校驗(yàn)傳入?yún)?shù)的正確性,只有正確才能執(zhí)行該方法,否則認(rèn)為調(diào)用方違反契約,不予執(zhí)行。這稱為前置條件(Pre-condition)。 一旦通過前置條件的校驗(yàn),方法必須執(zhí)行,并且必須確保執(zhí)行結(jié)果符合契約,這稱之為后置條件(Post-condition)。 對象本身有一套對自身狀態(tài)進(jìn)行校驗(yàn)的檢查條件,以確保該對象的本質(zhì)不發(fā)生改變,這稱之為不變式(Invariant)。,如何滿足LSP?,當(dāng)存在繼承關(guān)系時(shí),子類中方法的前置條件必須與超類中被覆蓋的方法的前置條件相同或者更寬松; 子類中方法的后置條件必須與超類中被覆蓋的

6、方法的后置條件相同或者更為嚴(yán)格。,OO語言特性,繼承并且覆蓋超類方法的時(shí)候,子類中的方法的可見性必須等于或者大于超類中的方法的可見性,子類中的方法所拋出的受檢異常只能是超類中對應(yīng)方法所拋出的受檢異常的子類。 publicclassSuperClass publicvoidmethodA()throwsIOException publicclassSubClassAextendsSuperClass /thisoverridingisillegal. privatevoidmethodA()throwsException publicclassSubClassBextendsSuperClass

7、 /thisoverridingisOK. publicvoidmethodA()throwsFileNotFoundException ,JAVA語言,從Java5開始,子類中的方法的返回值也可以是對應(yīng)的超類方法的返回值的子類。這叫做“協(xié)變”(Covariant) publicclassSuperClass publicNumbercaculate() returnnull; publicclassSubClassextendsSuperClass /onlycompilesinJava5orlater. publicIntegercaculate() returnnull; ,LSP總結(jié),

8、嚴(yán)格按照接口和虛擬類的語法規(guī)范來做就能很好遵循此原則 如果有兩個(gè)具體類A和B之間的關(guān)系違反了LSP,可以采用以下重構(gòu)方案 創(chuàng)建一個(gè)新的抽象類C,作為兩個(gè)具體類的超類,將A和B共同的行為移動到C中,從而解決A和B行為不完全一致的問題。 從B到A的繼承關(guān)系改寫為委派關(guān)系。,面向?qū)ο笤O(shè)計(jì)原則-DIP,依賴倒置原則 (針對接口編程,不要針對實(shí)現(xiàn)編程 ) 高層模塊不應(yīng)該依賴于低層模塊。二者都應(yīng)該依賴于抽象。 抽象不應(yīng)該依賴于細(xì)節(jié)。細(xì)節(jié)應(yīng)該依賴于抽象 針對接口編程:使用接口和抽象類進(jìn)行變量的類型聲明、參量的類型聲明,方法的返還類型聲明,以及數(shù)據(jù)類型的轉(zhuǎn)換 不要針對實(shí)現(xiàn)編程:不應(yīng)當(dāng)使用具體類進(jìn)行變量的類型聲

9、明、參量的類型聲明,方法的返還類型聲明,以及數(shù)據(jù)類型的轉(zhuǎn)換,DIP舉例,DIP總結(jié),DIP雖然強(qiáng)大,但卻不易實(shí)現(xiàn),因?yàn)橐蕾嚨罐D(zhuǎn)的緣故,對象的創(chuàng)建很可能要使用對象工廠,以避免對具體類的直接引用,此原則的使用將導(dǎo)致大量的類文件。給維護(hù)帶來不必要的麻煩。所以,正確的做法是只對程序中頻繁變化的部分進(jìn)行依賴倒置。,面向?qū)ο笤O(shè)計(jì)原則-ISP,接口隔離原則 不要強(qiáng)迫客戶依賴于它們不用的方法。 一個(gè)類對另外一個(gè)類的依賴性應(yīng)當(dāng)是建立在最小的接口上的。如果客戶端只需要某一些方法的話,那么就應(yīng)當(dāng)向客戶端提供這些需要的方法,而不要提供不需要的方法。提供接口意味著向客戶端作出承諾,過多的承諾會給系統(tǒng)的維護(hù)造成不必要的負(fù)

10、擔(dān)。 使用多個(gè)專門的接口比使用單一的接口要好。,ISP的實(shí)質(zhì),如果你擁有一個(gè)針對多個(gè)客戶的類,為每一個(gè)客戶創(chuàng)建特定業(yè)務(wù)接口,然后使該客戶類繼承多個(gè)特定業(yè)務(wù)接口將比直接加載客戶所需所有方法有效。,ISP舉例,三個(gè)基本面向?qū)ο笤O(shè)計(jì)原則, 針對接口編程,而不是針對實(shí)現(xiàn)編程 優(yōu)先使用對象組合,而不是類繼承 封裝變化點(diǎn),設(shè)計(jì)模式定義,設(shè)計(jì)模式的廣義定義: 設(shè)計(jì)模式概念是由建筑設(shè)計(jì)師Christopher Alexander提出:“每一個(gè)模式描述了一個(gè)在我們周圍不斷重復(fù)發(fā)生的問題,以及該問題的解決方案的核心。這樣,你就能一次又一次地使用該方案而不必做重復(fù)勞動。” 設(shè)計(jì)模式的狹義定義: 可以簡單的認(rèn)為:設(shè)計(jì)

11、模式就是解決某個(gè)特定的面向?qū)ο筌浖栴}的特定方法。,框架和設(shè)計(jì)模式的區(qū)別,框架可以認(rèn)為是一個(gè)適用于某個(gè)領(lǐng)域的軟件包。這個(gè)軟件包提供了相應(yīng)領(lǐng)域的各個(gè)問題的解決方法 設(shè)計(jì)模式針對面向?qū)ο蟮膯栴}域;框架針對特定業(yè)務(wù)的問題域 設(shè)計(jì)模式在碰到具體問題后,才能產(chǎn)生代碼;框架已經(jīng)可以用代碼表示。 設(shè)計(jì)模式是比框架更小的體系結(jié)構(gòu)元素 ,框架中可以包括多個(gè)設(shè)計(jì)模式。,為什么要用設(shè)計(jì)模式?,作為程序員都知道良好程序的一個(gè)基本標(biāo)準(zhǔn):高聚合,低耦合。面向?qū)ο笳Z言比結(jié)構(gòu)化語言要復(fù)雜的多,不良或者沒有充分考慮的設(shè)計(jì)將會導(dǎo)致軟件重新設(shè)計(jì)和開發(fā)。然而實(shí)際的設(shè)計(jì)過程中,設(shè)計(jì)人員更多的考慮如何解決業(yè)務(wù)問題,對于軟件內(nèi)部結(jié)構(gòu)考慮較

12、少;設(shè)計(jì)模式則補(bǔ)充了這個(gè)缺陷,它主要考慮如何減少對象之間的依賴性,降低耦合程度,使得系統(tǒng)更易于擴(kuò)展,提高了對象可復(fù)用性。因此,設(shè)計(jì)人員正確的使用設(shè)計(jì)模式就可以優(yōu)化系統(tǒng)內(nèi)部的結(jié)構(gòu)。,設(shè)計(jì)模式描述,模式名稱 便于使用者在更高的抽象層次上進(jìn)行設(shè)計(jì)并交流有關(guān)設(shè)計(jì)思想 問題描述 指明可以被應(yīng)用的所必須的環(huán)境條件,解釋了設(shè)計(jì)問題及其背景 解決方案 描述了設(shè)計(jì)方案的組成部分、它們之間的關(guān)系及各自的職責(zé)和協(xié)作方式 效果 描述應(yīng)用設(shè)計(jì)模式后的結(jié)果及使用模式時(shí)應(yīng)權(quán)衡的問題,設(shè)計(jì)模式的種類,創(chuàng)建型(Creational):解決如何創(chuàng)建對象的問題。 結(jié)構(gòu)型(Structural):解決如何正確的組合類或?qū)ο蟮膯栴}。

13、行為型(Behavioral):解決類或?qū)ο笾g如何交互和如何分配職責(zé)的問題。,創(chuàng)建型模式,使系統(tǒng)獨(dú)立于對象的產(chǎn)生、組合和表示 將系統(tǒng)使用哪些具體的類的相關(guān)信息封裝起來 隱蔽了這些具體類的實(shí)例是如何被創(chuàng)建和使用 的 創(chuàng)建型模式在創(chuàng)建“什么”、“怎樣”被創(chuàng)建、由“誰”創(chuàng)建以及“何時(shí)”創(chuàng)建等方面具有很大的靈活性,創(chuàng)建型模式類別,抽象工廠(Abstract Factory) 提供創(chuàng)建相關(guān)的或相互依賴的一組對象的接口而無須指定具體的類 生成器(Builder) 將一個(gè)復(fù)雜對象的創(chuàng)建與表示分離,使得同樣的構(gòu)建過程可以用于創(chuàng)建不同的表示 工廠方法(Factory Method) 定義一個(gè)用于創(chuàng)建對象的接口

14、,由子類決定實(shí)例化哪一個(gè)類 原型(Prototype) 使用一個(gè)原型指定要創(chuàng)建的類的類型,通過復(fù)制這個(gè)原型得到新的對象 單件(Singleton) 保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)全局性的訪問點(diǎn),工廠方法模式,實(shí)現(xiàn)代碼,public interface Product public class ConcreteProduct implements Product public ConcreteProduct() public interface Creator public Product factorymethod(); public class ConcreteCretor implem

15、ents Cretor public Product factorymethod() return new ConcreteProduct(); public class Client private static Creator creator; private static Product product; public static void main(String args) creator = new ConcreteCretor(); product =creator.factorymethod(); ,適用范圍,一個(gè)類不知道它所必須創(chuàng)建的對象的類 一個(gè)類希望由其子類確定它創(chuàng)建的對

16、象 類將創(chuàng)建對象的職責(zé)分配給多個(gè)幫助者子類中的一個(gè),且將哪一個(gè)幫助者子類作為代表者這項(xiàng)信息局部化,結(jié)構(gòu)型模式,涉及如何組合類和對象以構(gòu)成更大的結(jié)構(gòu) 一種方法是采用繼承機(jī)制來組合接口或?qū)崿F(xiàn)以形成更大的結(jié)構(gòu) 另一種方法通過對象組合方式來形成 對象組合可以在運(yùn)行時(shí)刻改變 繼承機(jī)制為靜態(tài)組合,創(chuàng)建型模式類別,適配器(Adapter) 將一個(gè)類的接口轉(zhuǎn)換成用戶希望的另一種接口 橋(Bridge) 將類的抽象部分與實(shí)現(xiàn)部分分離,使它們可以相互獨(dú)立地變化 組合(Composite) 將對象組成樹結(jié)構(gòu)來表示局部和整體的層次關(guān)系,使單個(gè)對象和組合對象的使用具有一致性 裝飾(Decorator) 動態(tài)地給一個(gè)對象

17、添加新功能 外觀(Facade) 給一個(gè)子系統(tǒng)的所有接口提供一個(gè)統(tǒng)一接口,使子系統(tǒng)便于使用 輕量(Flyweight) 運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度對象 代理(Proxy) 為其他對象提供一個(gè)代理,以控制對該對象的訪問,適配器模式,實(shí)現(xiàn)代碼,public interface Target public void request(); public class Adaptee public void operation() public class Adapter ectends Adaptee implements Target public void request() operatio

18、n(); public class Adapter implements Target private Adaptee adaptee; public Adapter(Adaptee adaptee) this.adaptee=adaptee; public void request() adaptee.operation(); ,實(shí)現(xiàn)代碼(續(xù)),public class Client private static Target target; public static void main(String args) target = new Adapter(); public class C

19、lient private static Target target; private static Adaptee adaptee; public static void main(String args) target = new Adapter(adaptee); ,適用范圍,希望使用一個(gè)已存在的類,但它的接口與希望的接口不匹配 要創(chuàng)建一個(gè)可復(fù)用的類,該類可以與其他不相關(guān)的類或不可預(yù)見的類協(xié)同工作 想使用一些已存在的類,但不能對每一個(gè)類子類化以匹配它們的接口,行為型模式,不僅描述對象或類的模式,還描述它們之間的通信模式,這些模式刻畫了在運(yùn)行時(shí)難以跟蹤的復(fù)雜的控制流 行為型模式使設(shè)計(jì)者的注

20、意力從控制流轉(zhuǎn)移到對象間的聯(lián)系方式上,行為型模式類別,職責(zé)鏈(Chian of Responsibility) 命令(Command) 解釋器(Interpreter) 迭代器(Iterator) 中介者(Mediator) 備忘錄(Memento) 觀察者(Observer) 狀態(tài)(State) 策略(Strategy) 模板方法(Template Method) 訪問者(Visitor),數(shù)據(jù)庫操作超類,AOP是什么?,AOP是OOP的延續(xù),是Aspect Oriented Programming的縮寫,意思是面向方面編程。AOP實(shí)際是GoF設(shè)計(jì)模式的延續(xù),設(shè)計(jì)模式孜孜不倦追求的是調(diào)用者和

21、被調(diào)用者之間的解耦,AOP可以說也是這種目標(biāo)的一種實(shí)現(xiàn)。 面向方面編程 (AOP) 是施樂公司帕洛阿爾托研究中心 (Xerox PARC) 在上世紀(jì) 90 年代發(fā)明的一種編程范式,實(shí)現(xiàn)舉例,假設(shè)有在一個(gè)應(yīng)用系統(tǒng)中,有一個(gè)共享的數(shù)據(jù)必須被并發(fā)同時(shí)訪問,首先,將這個(gè)數(shù)據(jù)封裝在數(shù)據(jù)對象中,稱為Data Class,同時(shí),將有多個(gè)訪問類,專門用于在同一時(shí)刻訪問這同一個(gè)數(shù)據(jù)對象。 abstract class Worker abstract void locked();abstract void accessDataObject();abstract void unlocked(); ,這種實(shí)現(xiàn)方式的缺

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(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

提交評論