設計模式DesignPatten_第1頁
設計模式DesignPatten_第2頁
設計模式DesignPatten_第3頁
設計模式DesignPatten_第4頁
設計模式DesignPatten_第5頁
已閱讀5頁,還剩33頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第13章 設計模式(design pattern )132 可重用的面向對象設計模式可重用的面向對象設計模式13.2.1 設計模式概述設計模式概述1. 面向對象設計的任務:面向對象設計的任務:應用系統(tǒng)設計應用系統(tǒng)設計工具庫設計工具庫設計框架設計框架設計其中,框架是已形成源代碼的可重用軟件體系結構。它體現了應用程序的模塊組成關系??蚣芗翱蚣苤械母鱾€模塊是形形色色各具特色的。設計模式(design pattern)描述了軟件開發(fā)過程中若干重復出現的問題的解決方案,這些方案不是由過程、算法等底層程序構造實體實現,而是由軟件系統(tǒng)中類與類之間或不同類的對象之間的共生關系組成。設計模式可以幫助軟件設計人員

2、學習、重用前人的經驗和成果。設計模式的分類整理最早見于erich gamma在德國慕尼黑大學的博士論文。1995年,erich gamma,richard helm,ralph johnson,john vlissides合著的design patterns:elements of reusable object_oriented software系統(tǒng)地整理和描述了23個精選的設計模式(gof模式),為設計模式的學習、研究和推廣提供了良好的范例。classnamefunction1()function2()datamenber1datamenber2類的表示:子類關系:baseclasssub

3、class2設計模式的描述符號設計模式的描述符號(1)類和對象的表示 對象及對象鏈接:aobjectanotherobject(2)連接的表示)連接的表示 例如:由類a創(chuàng)建類b的對象 classaclassb對象創(chuàng)建關系:對象創(chuàng)建關系:示例代碼:classa:create() return new classb;實例引用關系實例引用關系:classaclassbrefrencename(引用名可選)window:area()return arectarea();windowarea()rectanglearea()widthheightrectangle:area() return width

4、* height; 引用關系涉及到的兩個類的實例之間可以形成一種代理關系,接受請求的對象將操作委托給它的代理者:arect對象聚合關系:對象聚合關系:objectsclassaclassb如:下圖表示類a中聚合了多個類b的對象。聚合關系可以用對象成員實現,但更經常的是將聚合的成員定義為對象成員指針或引用。由于引用關系也是以對象成員指針或引用來實現的,注意從設計意圖上區(qū)分對象聚合關系和引用關系對理解設計模式是至關重要的。聚合是對象的包容關系,容器和容器中的對象具有相同的生命期。引用關系又稱相識關系,是一種較松散的耦合關系。具有引用關系的對象,僅僅是知道被引用者的存在,并不為對方負責, 1抽象工廠

5、(抽象工廠(abstract factory)模式)模式抽象工廠定義一個抽象基類,為創(chuàng)建組合對象提供接口。在面向對象系統(tǒng)中,單個對象的創(chuàng)建由構造函數負責。一個組合對象的動態(tài)創(chuàng)建可由一個創(chuàng)建函數創(chuàng)建函數一次性完成,以保證被創(chuàng)建的組合對象的完備性。抽象工廠定義的接口稱為創(chuàng)建函數或初始化函數。抽象工廠的不同實現類(可稱為實現工廠)的對象可以按不同的風格去實現組合對象的具體創(chuàng)建,可以在保證組合對象被完備創(chuàng)建的前提下,簡化組合對象的版本替換、升級換代過程。工廠方法(工廠方法(factory method)是一些動態(tài)創(chuàng)建對象的方法。是在抽象工廠中聲明的一組虛函數,它們負責組合對象中成員對象的創(chuàng)建,其實現代

6、碼在實現工廠中定義。 抽象工廠模式通常與工廠方法配合使用抽象工廠模式通常與工廠方法配合使用product1part11part12product2part21part22productfactoryproductcreate()factorymethod1()factorymethod2()concreatbfactorymethod1()factorymethod2()concreatafactorymethod1()factorymethod2()圖13.1 抽象工廠和工廠方法模式結構舉例1創(chuàng)建函數:創(chuàng)建函數:一個抽象的產品工廠類productfactory定義了由 兩 個 零 件 組 成

7、 的 組 件 產 品 的 創(chuàng) 建 函 數product* productcreate (); 以及創(chuàng)建零件的工廠方法。抽象的產品工廠的實現工廠concreteproduct重定義了創(chuàng)建零件對象的工廠方法。創(chuàng)建函數product* productcreate ()調用工廠方法,一次性創(chuàng)建產品。返回產品指針。2產品類與零件類產品類與零件類產品類product與零件類part可以是分別定義的類,產品類以零件類為自己的對象成員。productcreate ()創(chuàng)建一個由2個part1和1個part2組合而成的product組合對象。如果將product定義為抽象基類,且part1和part2定義為它的

8、實現類,則可以得到更加復雜的product組合關系。class productfactory /抽象工廠定義public: product* productcreate ();virtual part1*factorymethod1();virtual part2*factorymethod2();/;class concretea: public productfactory /實現工廠定義public: virtual part1*factorymethod1() return new part1; ;virtual part2*factorymethod2() return new pa

9、rt2; ;/;product* productfactory: productcreate () product* ptr;part1* p11= factorymethod1();part1* p12= factorymethod1();part1* p21= factorymethod2();ptr=p11;return ptr;class product;class part1;class part2;3用工廠對象參數化參數化組合對象創(chuàng)建過程:工廠對象即實現工廠的實例對象。修改生產函數productcreate()如下:product* productcreate ( productf

10、actory* );/創(chuàng)建函數以抽象工廠的指針為形參。 若再定義一個抽象工廠的實現類:class concreteb: public productfactory然后聲明:concretea* factorya; concretetb* factoryb;則調用:productcreate (factorya);productcreate (factorya );將生產a、b兩個不同系列的產品。很容易實現產品系列的更新?lián)Q代。如:product和part分別代表電腦主機和配件,產品更新?lián)Q代只要定義新的抽象工廠的實現類,并用它來參數化生產函數即可,不必對系統(tǒng)的其它部分作任何改動。class app

11、licationstatic application * instance;application ( );public:static int count;application ( );static application* init();application *application:instance=null;int application:count=0;application *application:init() if (count=0) count=count+1; instance = new application; coutsingle instance has crea

12、ted, ok!endl; return instance; else coutcant create more than one instance!endl; return null; application:application()count=count-1;coutthe single instance has released! getpicture ()test-add(new rectangle); agraphic = arectangle;if (test = agraphic- getpicture ()test-add(new rectangle); /此次add ()操

13、作實際并不執(zhí)行 為了識別一個組件是基元還是組合,可按以下示例代碼,定義一 個 查 詢 函 數getpicture(),對其返回的組合安全地執(zhí)行add()和remove()操作:3共享對象(共享對象(flyweight)模式)模式:細粒度對象通常因為數量太大而難以用對象進行建模。共享對象模式提供解決這個難題的有效手段。例如:在文檔編輯器程序中,文檔對象可能是一個遞歸組合模式對象。若將文檔中的字符作為文檔組合對象樹的葉結點,可以將字符與文檔中的圖形、表格等嵌入部分的繪制和格式化作統(tǒng)一處理,并且在程序擴展,支持新字符集時不影響其它部分。但是成千上萬的字符對象將耗費大量內存,并產生難以接受的運行開銷。

14、共享對象模式解決了這一問題,使大量細粒度對象的使用無須付出這些過于昂貴的代價。一個共享對象(flyweight)可以在多個上下文(context)對象中使用。在每個具體的上下文對象中,flyweight作為一個獨立的對象出現,在這一點上與非共享對象沒有區(qū)別。flyweight的數據成員被看作它的“內部狀態(tài)”,是只讀的。flyweight的上下文對象為flyweight提供上下文信息,它們被看作flyweight的“外部狀態(tài)”。用戶對象負責在必要的時候將外部狀態(tài)傳遞給flyweight。以文檔編輯器應用為例,它為字母表中每一個字母創(chuàng)建一個共享對象(flyweight)。每個flyweight雖然

15、只存儲一個字母代碼,但它在文檔中的位置和排版風格可以由排版算法或格式化命令決定。邏輯上,文檔中的字符每次出現都會有一個對象與之對應。物理上,同一字符共享一個flyweight對象,即同一字符每次出現都指向同一實例,該實例位于對象的共享池中。 flyweight 對象池對象池abcdeihgflkjmnopqrvutsyxwzarowacolumnarowarowamerica4代理(代理(proxy)模式)模式代理模式的原型可以參考文件緩沖區(qū)與磁盤文件的關系。正如只有在需要訪問某個磁盤文件時才為它建立緩沖區(qū)的道理一樣,在面向對象系統(tǒng)中只有在確實需要某個對象時才對它進行創(chuàng)建和初始化。例如,當需要

16、打開一個多媒體文檔時,如果一次性打開其中包含的所有對象,往往造成不必要的巨大開銷,因為這些對象在文檔中并不是同時可見的,沒有必要同時創(chuàng)建它們。此時有必要的是在文檔中為這些暫時不需要創(chuàng)建的對象設置一個開銷極小的代理對象。由它負責在需要時創(chuàng)建由它代理的主體對象。realsubjectrealsubjectrequest()clientproxyrequest() realsubject- request();subjectrequest()(a) 代理模式結構aclientsubjectaproxyrealsubjectarealsubject(b)運行時刻的對象代理關系圖13.5 代理模式的結構

17、和對象間的關系一般來說,在需要利用一個更通用的對象一般來說,在需要利用一個更通用的對象指針來代替較為專門化的對象指針的時候就指針來代替較為專門化的對象指針的時候就應該使用代理模式。比如,除了以上所述的應該使用代理模式。比如,除了以上所述的多媒體對象的代理外,還可以為不同地址空多媒體對象的代理外,還可以為不同地址空間的對象提供本地代理,為需要提供多種訪間的對象提供本地代理,為需要提供多種訪問權限的對象提供保護代理等等。問權限的對象提供保護代理等等。智能代理是代理模式的高級形式。智能代理是代理模式的高級形式。普通代理通過簡單的指針替換實現代理任務,智能代理還可以在訪問被代理對象時執(zhí)行一些附加的操作

18、,如:在第一次引用一個持久對象時,將它裝入內存;在訪問一個實際對象前,檢查它是否被加鎖,以防止沖突;對對象進行引用計數管理,當對象不再被引用時自動將它釋放。智能代理的一種具體實現方式是重載智能代理的一種具體實現方式是重載c+的指針運算符的指針運算符-。這樣就可以在通。這樣就可以在通過指針訪問被代理對象時,執(zhí)行一些附過指針訪問被代理對象時,執(zhí)行一些附加的操作。加的操作。13.2.3 與對象行為相關的模式與對象行為相關的模式行為(行為(behavior)是指對象對請求的可預知是指對象對請求的可預知反應。反應。與對象行為相關的模式描述對象之間的通與對象行為相關的模式描述對象之間的通信關系,處理各種在

19、運行時難以跟蹤的復雜信關系,處理各種在運行時難以跟蹤的復雜控制流,描述一組對象怎樣相互協(xié)作以完成控制流,描述一組對象怎樣相互協(xié)作以完成其中任一對象都無法單獨完成的任務。其中任一對象都無法單獨完成的任務。5職責鏈(職責鏈(chain of responsibility)模式:)模式:職責鏈模式建立一些對象間的鏈接關系,使請求沿著該鏈傳遞,直到鏈上的某一個對象處理它為止。鏈上的多個對象都有機會接收和處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關系。例如圖形用戶界面中的上下文有關幫助機制,用戶可在當前界面以多種方式提交請求,啟動幫助。幫助信息窗口以含有進一步幫助的鏈接信息。這種鏈接式對象請求處理

20、通常從第一個接收請求的對象開始,或者自己處理該請求,或者轉發(fā)給鏈中下一個候選對象。 handlerrequest()concreat1request()concreat2request()clientsuccessor(a) 職責鏈結構aclientahandleraconcreatsuccessoraconcreatsuccessor(b) 職責鏈對象鏈接圖13.6 職責鏈模式結構及其對象結構實現職責鏈的代碼示例:class handlerpublic:handler(handler* sp): successor(sp)virtual void request();private: han

21、dler* successor;這是一個事件處理句柄接口,其子類可以定義自己的request()實現?;惖娜笔崿F如下:virtual void handler:request() if (successor)successor- request();這是一個事先設定的固定的鏈,只要后繼存在就會無條件轉發(fā)。若在request()中用不同的請求參數來分派請求,可以實現更靈活的鏈接。void request(abstrctrequest* therequest) switch(therequest-getkind() case 1:request(abstrctrequest *) thereq

22、uest);break;case 2:/default:/break; 6命令(命令(command)模式)模式命令模式又稱事務(transaction)模式,命令模式用于封裝向某個對象的請求。所謂請求,就是應用程序的操作人員通過圖形用戶界面(gui)構件如按鈕、圖標、菜單項等發(fā)出的操作命令。命令模式通過在請求調用對象和請求的執(zhí)行對象之間增加一個command中間對象,用以消解多對多復雜性。areceiverclientconcreatecommandexecute()areceiveaction()statecommandexecute()receiveraction()trigger clicked()acommandexecute()一個觸發(fā)器(ttri

溫馨提示

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

評論

0/150

提交評論