




已閱讀5頁,還剩64頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
JAVA,面向?qū)ο笈c設(shè)計(jì)模式 董新軍 2013.7.9,面向?qū)ο笈c設(shè)計(jì)模式,目 錄 面向?qū)ο?UML幾個(gè)概念 設(shè)計(jì)模式,一、面向?qū)ο?1.1 為什么面向?qū)ο蟮木幊虝?huì)在軟件開發(fā)領(lǐng)域造成如此震憾的影響? 1.2 面向?qū)ο蟪绦蛟O(shè)計(jì)中的概念 1.3 多態(tài)性,1.1 為什么面向?qū)ο蟮木幊虝?huì)在軟件開發(fā)領(lǐng)域造成如此震憾的影響?,面向?qū)ο缶幊蹋∣OP)具有多方面的吸引力。對管理人員,它實(shí)現(xiàn)了更快和更廉價(jià)的開發(fā)與維護(hù)過程。對分析與設(shè)計(jì)人員,建模處理變得更加簡單,能生成清晰、易于維護(hù)的設(shè)計(jì)方案。對程序員,對象模型顯得如此高雅和淺顯。此外,面向?qū)ο蠊ぞ咭约皫斓木薮笸κ咕幊坛蔀橐豁?xiàng)更使人愉悅的任務(wù)。每個(gè)人都可從中獲益,至少表面如此。 五大基本特征: (1) 所有東西都是對象??蓪ο笙胂蟪梢环N新型變量;它保存著數(shù)據(jù),但可要求它對自身進(jìn)行操作。 (2) 程序是一大堆對象的組合;通過消息傳遞,各對象知道自己該做些什么。 (3) 每個(gè)對象都有自己的存儲(chǔ)空間,可容納其他對象。或者說,通過封裝現(xiàn)有對象,可制作出新型對象。 (4) 每個(gè)對象都有一種類型。根據(jù)語法,每個(gè)對象都是某個(gè)“類”的一個(gè)“實(shí)例”。 (5) 同一類所有對象都能接收相同的消息。這一特性稱為對象的“可替換性”,是OOP最重要的概念之一。,1.2 面向?qū)ο蟪绦蛟O(shè)計(jì)中的概念,面向?qū)ο蟪绦蛟O(shè)計(jì)中的概念主要包括:對象、類、數(shù)據(jù)抽象、繼承、動(dòng)態(tài)綁定、數(shù)據(jù)封裝、多態(tài)性、消息傳遞。通過這些概念面向?qū)ο蟮乃枷氲玫搅司唧w的體現(xiàn)。 1)對象(Object) 可以對其做事情的一些東西。一個(gè)對象有狀態(tài)、行為和標(biāo)識三種屬性。 2)類(class) 一個(gè)共享相同結(jié)構(gòu)和行為的對象的集合。 3)封裝(encapsulation): 第一層意思:將數(shù)據(jù)和操作捆綁在一起,創(chuàng)造出一個(gè)新的類型的過程。 第二層意思:將接口與實(shí)現(xiàn)分離的過程。 4)繼承 類之間的關(guān)系,在這種關(guān)系中,一個(gè)類共享了一個(gè)或多個(gè)其他類定義的結(jié)構(gòu)和行為。繼承描述了類之間的“是一種”關(guān)系。子類可以對基類的行為進(jìn)行擴(kuò)展、覆蓋、重定義。 5)組合 既是類之間的關(guān)系也是對象之間的關(guān)系。在這種關(guān)系中一個(gè)對象或者類包含了其他的對象和類。 組合描述了“有”關(guān)系。 6)多態(tài) 類型理論中的一個(gè)概念,一個(gè)名稱可以表示很多不同類的對象,這些類和一個(gè)共同超類有關(guān)。因此,這個(gè)名稱表示的任何對象可以以不同的方式響應(yīng)一些共同的操作集合。 7)動(dòng)態(tài)綁定 也稱動(dòng)態(tài)類型,指的是一個(gè)對象或者表達(dá)式的類型直到運(yùn)行時(shí)才確定。通常由編譯器插入特殊代碼來實(shí)現(xiàn)。與之對立的是靜態(tài)類型。 8)靜態(tài)綁定 也稱靜態(tài)類型,指的是一個(gè)對象或者表達(dá)式的類型在編譯時(shí)確定。 9)消息傳遞 指的是一個(gè)對象調(diào)用了另一個(gè)對象的方法(或者稱為成員函數(shù))。 10)方法 也稱為成員函數(shù),是指對象上的操作,作為類聲明的一部分來定義。方法定義了可以對一個(gè)對象執(zhí)行那些操作,1.3 多態(tài)性,指相同對象收到不同消息或不同對象收到相同消息時(shí)產(chǎn)生不同的實(shí)現(xiàn)動(dòng)作。兩種多態(tài)性:編譯時(shí)多態(tài)性,運(yùn)行時(shí)多態(tài)性。 a、編譯時(shí)多態(tài)性:通過重載函數(shù)實(shí)現(xiàn)。 b、運(yùn)行時(shí)多態(tài)性:通過重寫覆蓋實(shí)現(xiàn)。,二、UML幾個(gè)概念,2.1 泛化關(guān)系(Generalization) 2.2 關(guān)聯(lián)關(guān)系(Association) 2.3 依賴關(guān)系(Dependency) 2.4 實(shí)現(xiàn)關(guān)系(Realization),2.1 泛化關(guān)系(Generalization),對于面向?qū)ο笳Z言,UML中所說的泛化關(guān)系就是指類的繼承關(guān)系。如果一個(gè)類是另一個(gè)類的子類,那么UML通過使用一個(gè)實(shí)線連接兩個(gè)類的UML圖來表示二者之間的繼承關(guān)系,實(shí)線的起始端是子類的UML圖,終點(diǎn)端是父類的UML圖,但終點(diǎn)端使用一個(gè)空心的三角形表示實(shí)線的結(jié)束 。,2.2 關(guān)聯(lián)關(guān)系(Association),如果A類中成員變量是用B類(接口)來聲明的變量,那么A和B的關(guān)系是關(guān)聯(lián)關(guān)系,稱A關(guān)聯(lián)于B。那么UML通過使用一個(gè)實(shí)線連A和B的UML圖,實(shí)線的起始端是A的UML圖,終點(diǎn)端是B的UML圖,但終點(diǎn)端使用一個(gè)指向B的UML圖的方向箭頭表示實(shí)線的結(jié)束 。,2.3 依賴關(guān)系(Dependency),7/13/2019,10,如果A類中某個(gè)方法的參數(shù)用B類(接口)來聲明的變量或某個(gè)方法返回的數(shù)據(jù)類型是B類型的,那么A和B的關(guān)系是依賴關(guān)系,稱A依賴于B。那么UML通過使用一個(gè)虛線連A和B的UML圖,虛線的起始端是A的UML圖,終點(diǎn)端是B的UML圖,但終點(diǎn)端使用一個(gè)指向B的UML圖的方向箭頭表示虛線的結(jié)束。,2.4 實(shí)現(xiàn)關(guān)系(Realization),如果一個(gè)類實(shí)現(xiàn)了一個(gè)接口,那么類和接口的關(guān)系是實(shí)現(xiàn)關(guān)系,稱類實(shí)現(xiàn)接口。UML通過使用虛線連接類和它所實(shí)現(xiàn)的接口,虛線起始端是類,虛線的終點(diǎn)端是它實(shí)現(xiàn)的接口,但終點(diǎn)端使用一個(gè)空心的三角形表示虛線的結(jié)束 。,三、設(shè)計(jì)模式,設(shè)計(jì)模式分類: 3.1創(chuàng)建型:與對象的創(chuàng)建有關(guān) 3.2結(jié)構(gòu)型:處理類或?qū)ο蟮慕M合 3.3行為型:對類或?qū)ο笤鯓咏换ズ驮鯓臃峙渎氊?zé)進(jìn)行描述,Christopher Alexander說:“每一個(gè)設(shè)計(jì)模式描述一個(gè)在我們周圍不斷重復(fù)發(fā)生的問題,以及該問題的解決方案的核心。這樣,你就能一次一次地使用該方案而不必做重復(fù)勞動(dòng)?!?-典型問題的經(jīng)典解決方法!,設(shè)計(jì)模式分類,3.1.1 Factory method(工廠方法)-創(chuàng)建型模式,1. 意圖 定義一個(gè)用于創(chuàng)建對象的接口,讓子類決定實(shí)例化哪一個(gè)類。 Factory Method使一個(gè)類的實(shí)例化延遲到其子類。 2. 別名 虛構(gòu)造器( Virtual Constructor) 3. 動(dòng)機(jī) 框架使用抽象類定義和維護(hù)對象之間的關(guān)系。這些對象的創(chuàng)建通常也由框架負(fù)責(zé)??紤]這樣一個(gè)應(yīng)用框架,它可以向用戶顯示多個(gè)文檔。在這個(gè)框架中,兩個(gè)主要的抽象是類Application和Document。這兩個(gè)類都是抽象的,客戶必須通過它們的子類來做與具體應(yīng)用相關(guān)的實(shí)現(xiàn)。例如,為創(chuàng)建一個(gè)繪圖應(yīng)用,我們定義類 DrawingApplication和DrawingDocument。 A p p l i c a t i o n類負(fù)責(zé)管理 D o c u m e n t并根據(jù)需要?jiǎng)?chuàng)建它們 例如,當(dāng)用戶從菜單中選擇 O p e n或New的時(shí)候。,3.1.1 Factory method:適用性及參與者,適用性: 當(dāng)一個(gè)類不知道它所必須創(chuàng)建的對象的類的時(shí)候。 當(dāng)一個(gè)類希望由它的子類來指定它所創(chuàng)建的對象的時(shí)候。 當(dāng)類將創(chuàng)建對象的職責(zé)委托給多個(gè)幫助子類中的某一個(gè),并且你希望將哪一個(gè)幫助子類是代理者這一信息局部化的時(shí)候。 參與者: Product(Document) 定義工廠方法所創(chuàng)建的對象的接口。 ConcreteProduct(MyDocument) 實(shí)現(xiàn)Product接口。 Creator(Application) 聲明工廠方法,該方法返回一個(gè) P r o d u c t類型的對象。 C r e a to r也可以定義 一個(gè)工廠方 法的缺省實(shí)現(xiàn),它返回一個(gè)缺省的 ConcreteProduct對象。 可以調(diào)用工廠方法以創(chuàng)建一個(gè) Product對象。 ConcreteCreator(MyApplication) 重定義工廠方法以返回一個(gè) ConcreteProduct實(shí) 例。,3.1.1 Factory method模式的UML類圖(1),3.1.1 Factory method模式的UML類圖(2),3.1.2 Abstruct Factory(抽象工廠),1. 意 圖 提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類。 2. 動(dòng) 機(jī) 考慮一個(gè)支持多種視感( l o o k - a n d - f e e l )標(biāo)準(zhǔn)的用戶界面工具包。不同的視感風(fēng)格為諸如滾動(dòng)條、窗口和按鈕等用戶界面“窗口組件”定義不同的外觀和行為。為保證視感風(fēng)格標(biāo)準(zhǔn)間的可移植性,一個(gè)應(yīng)用不應(yīng)該為一個(gè)特定的視感外觀硬編碼它的窗口組件。在整個(gè)應(yīng)用中實(shí)例化特定視感風(fēng)格的窗口組件類將使得以后很難改變視感風(fēng)格。 一個(gè)通俗的例子: 請MM吃飯,麥當(dāng)勞的雞翅和肯德基的雞翅都是 MM 愛吃的東西,雖然口味有所不同,但不管你帶 MM 去麥當(dāng)勞或肯德基,只管向服務(wù)員說“來四個(gè)雞翅”就行了。麥當(dāng)勞和肯德基就是生產(chǎn)雞翅的 Factory。,3.1.2 Abstruct Factory:適用性與參與者,適用性: 一個(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í)。 參與者: AbstractFactory 聲明一個(gè)創(chuàng)建抽象產(chǎn)品對象的操作接口。 ConcreteFactory 實(shí)現(xiàn)創(chuàng)建具體產(chǎn)品對象的操作。 AbstractProduct 為一類產(chǎn)品對象聲明一個(gè)接口。 ConcreteProduct 定義一個(gè)將被相應(yīng)的具體工廠創(chuàng)建的產(chǎn)品對象。 實(shí)現(xiàn)AbstractProduct接口。,3.1.2 Abstruct Factory模式的UML類圖,3.1.3 Builder(生成器),1. 意圖 將一個(gè)復(fù)雜對象的構(gòu)建與它的內(nèi)部表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 該模式使得產(chǎn)品內(nèi)部表象可以獨(dú)立的變化,客戶不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié) ,可以強(qiáng)制實(shí)行一種分步驟進(jìn)行的建造過程。 2. 動(dòng)機(jī) 我們生活當(dāng)中有許多設(shè)備都是以組裝的形式存在的,例如臺式電腦,那么有些廠商就會(huì)推出一些具有默認(rèn)配置的組裝電腦主機(jī),顧客可以購買默認(rèn)配置的產(chǎn)品,也可以要求廠商重新組裝一部不同配置不同組裝方式的主機(jī)。此時(shí),我們就可以使用建造者模式來滿足特殊顧客的要求了。 注意到這個(gè)例子中廠商是重新組裝一部主機(jī),即關(guān)注點(diǎn)是主機(jī)的每個(gè)組成部分,這就符合上面Builder模式給出的使用場景了。,3.1.3 Builder(生成器) :適用性、參與者,在以下情況下使用Builder模式: 1.當(dāng)創(chuàng)建復(fù)雜對象的算法應(yīng)該獨(dú)立于該對象的組成部分以及它們的裝配方式 時(shí)。 2.當(dāng)構(gòu)造過程必須允許被構(gòu)造的對象有不同表示時(shí)。 參與者: 1.Builder 為創(chuàng)建一個(gè)Product對象的各個(gè)部件指定抽象接口。提供一個(gè)檢索產(chǎn)品的 接口。 2.ConcreteBuilder 實(shí)現(xiàn)Builder的接口以構(gòu)造和裝配該產(chǎn)品的各個(gè)部件。定義并明確它所創(chuàng)建的表示。 3.Director 構(gòu)造一個(gè)使用Builder接口的對象。 4.Product 表示被構(gòu)造的復(fù)雜對象。ConcreteBuilder創(chuàng)建該產(chǎn)品的內(nèi)部表示并定義它的裝配過程。,3.1.3 Builder模式的UML類圖,3.1.3生成器模式的優(yōu)點(diǎn),7/13/2019,24,生成器模式將對象的構(gòu)造過程封裝在具體生成器中,用戶使用不同的具體生成器就可以得到該對象的不同表示。 生成器模式將對象的構(gòu)造過程從創(chuàng)建該對象的類中分離出來,使得用戶無須了解該對象的具體組件。 可以更加精細(xì)有效地控制對象的構(gòu)造過程。生成器將對象的構(gòu)造過程分解成若干步驟,這就使得程序可以更加精細(xì),有效地控制整個(gè)對象的構(gòu)造。 生成器模式將對象的構(gòu)造過程與創(chuàng)建該對象類解耦,使得對象的創(chuàng)建更加靈活有彈性。 當(dāng)增加新的具體生成器時(shí),不必修改指揮者的代碼,即該模式滿足開-閉原則。,3.1.4 Prototype(原型),1. 意圖 用原型實(shí)例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象。 2. 動(dòng)機(jī) 當(dāng)我們已經(jīng)擁有某個(gè)得來不易的寶貝時(shí),往往我們會(huì)很想再“變”一些出來,即這個(gè)寶貝的“復(fù)制品”,這種方式簡單又理想,誰都想要學(xué)會(huì)這項(xiàng)本事。不可能的事情!不過,這種手段在軟件設(shè)計(jì)中是完全可以實(shí)現(xiàn)的,在OO中的原型模式就是這樣基于思想的。,3.1.4 Prototype(原型):適用性與參與者,適用性: 1當(dāng)一個(gè)系統(tǒng)應(yīng)該獨(dú)立于它的產(chǎn)品創(chuàng)建、構(gòu)成和表示時(shí)。 2.當(dāng)要實(shí)例化的類是在運(yùn)行時(shí)刻指定時(shí),例如,通過動(dòng)態(tài)裝載。 3.為了避免創(chuàng)建一個(gè)與產(chǎn)品類層次平行的工廠層次時(shí)。 4.當(dāng)一個(gè)類的實(shí)例只能有幾個(gè)不同狀態(tài)組合中的一種時(shí)。 建立相應(yīng)數(shù)目的原型并克隆它們可能比每次用合適的狀態(tài)手工實(shí)例化該類更方便一些。 參與者: 1. Prototype 聲明一個(gè)克隆自身的接口。 2. ConcretePrototype 實(shí)現(xiàn)一個(gè)克隆自身的操作。 3. Client 讓一個(gè)原型克隆自身從而創(chuàng)建一個(gè)新的對象。,3.1.4 Prototype模式的UML類圖,3.2.1 Adapter(適配器)類對象結(jié)構(gòu)型模式,1. 意圖 將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。 A d a p t- -e r模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。 2. 別名 包裝器 Wrapper。,3.2.1 Adapter(適配器):適應(yīng)性與參與者,以下情況使用Adapter模式 你想使用一個(gè)已經(jīng)存在的類,而它的接口不符合你的需求。 你想創(chuàng)建一個(gè)可以復(fù)用的類,該類可以與其他不相關(guān)的類或不可預(yù)見的類(即那些接口可能不一定兼容的類)協(xié)同工作。 (僅適用于對象 A d a p t e r)你想使用一些已經(jīng)存在的子類,但是不可能對每一個(gè)都進(jìn)行子類化以匹配它們的接口。對象適配器可以適配它的父類接口。 參與者: Target 定義Client使用的與特定領(lǐng)域相關(guān)的接口。 Client 與符合Target接口的對象協(xié)同。 Adaptee 定義一個(gè)已經(jīng)存在的接口,這個(gè)接口需要適配。 Adapter 對Adaptee的接口與Ta rg e t接口進(jìn)行適配。,07/07/13,30,3.2.1 Adapter模式的UML類圖(對象適配器),3.2.2 Decorator(裝飾模式),1. 意圖 動(dòng)態(tài)地給一個(gè)對象添加一些額外的職責(zé)。就增加功能來說, D e c o r a t o r模式相比生成子類更為靈活。 2. 別名 包裝器Wrapper 3. 動(dòng)機(jī) 有時(shí)我們希望給某個(gè)對象而不是整個(gè)類添加一些功能。例如,一個(gè)圖形用戶界面工具箱允許你對任意一個(gè)用戶界面組件添加一些特性,例如邊框,或是一些行為,例如窗口滾動(dòng)。 使用繼承機(jī)制是添加功能的一種有效途徑,從其他類繼承過來的邊框特性可以被多個(gè)子類的實(shí)例所使用。但這種方法不夠靈活,因?yàn)檫吙虻倪x擇是靜態(tài)的,用戶不能控制對組件加邊框的方式和時(shí)機(jī)。 一種較為靈活的方式是將組件嵌入另一個(gè)對象中,由這個(gè)對象添加邊框。我們稱這個(gè)嵌入的對象為 裝飾 。這個(gè)裝飾與它所裝飾的組件接口一致,因此它對使用該組件的客戶透明。它將客戶請求轉(zhuǎn)發(fā)給該組件,并且可能在轉(zhuǎn)發(fā)前后執(zhí)行一些額外的動(dòng)作(例如畫一個(gè)邊框)。透明性使得你可以遞歸的嵌套多個(gè)裝飾,從而可以添加任意多的功能。,3.2.2 Decorator(裝飾模式):適用性及參與者,以下情況使用Decorator模式 在不影響其他對象的情況下,以動(dòng)態(tài)、透明的方式給單個(gè)對象添加職責(zé)。 處理那些可以撤消的職責(zé)。 當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時(shí)。一種情況是,可能有大量獨(dú)立的擴(kuò)展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長。另一種情況可能是因?yàn)轭惗x被隱藏,或類定義不能用于生成子類。 參與者: Component 定義一個(gè)對象接口,可以給這些對象動(dòng)態(tài)地添加職責(zé)。 ConcreteComponent 定義一個(gè)對象,可以給這個(gè)對象添加一些職責(zé)。 Decorator 維持一個(gè)指向Component對象的指針,并定義一個(gè)與 Component接口一致的接口。 ConcreteDecorator 向組件添加職責(zé)。,07/07/13,33,3.2.2 Decorator裝飾模式的UML類圖,裝飾性功能,3.2.3 Bridge(橋接模式),1. 意圖 將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。 2. 別名 Handle/Body 3. 動(dòng)機(jī) 通常方法的弊端: 當(dāng)一個(gè)抽象可能有多個(gè)實(shí)現(xiàn)時(shí),通常用繼承來協(xié)調(diào)它們。抽象類定義對該抽象的接口,而具體的子類則用不同方式加以實(shí)現(xiàn)。但是此方法有時(shí)不夠靈活。繼承機(jī)制將抽象部分與它的實(shí)現(xiàn)部分固定在一起,使得難以對抽象部分和實(shí)現(xiàn)部分獨(dú)立地進(jìn)行修改、擴(kuò)充和重用。,3.2.3 Bridge:適用性及參與者,適用性: 你不希望在抽象和它的實(shí)現(xiàn)部分之間有一個(gè)固定的綁定關(guān)系。例如這種情況可能是因?yàn)?在程序運(yùn)行時(shí)刻實(shí)現(xiàn)部分應(yīng)可以被選擇或者切換。 類的抽象以及它的實(shí)現(xiàn)都應(yīng)該可以通過生成子類的方法加以擴(kuò)充。這時(shí) B r i d g e模式使你可以對不同的抽象接口和實(shí)現(xiàn)部分進(jìn)行組合,并分別對它們進(jìn)行擴(kuò)充。 對一個(gè)抽象的實(shí)現(xiàn)部分的修改應(yīng)對客戶不產(chǎn)生影響,即客戶的代碼不必重新編譯。 參與者: Abstraction 定義抽象類的接口。 維護(hù)一個(gè)指向Implementor類型對象的指針。 RefinedAbstraction 擴(kuò)充由Abstraction定義的接口。 Implementor 定義實(shí)現(xiàn)類的接口,該接口不一定要與 A b s t r a c t i o n的接口完全一致;事實(shí)上這兩個(gè)接口可以完全不同。一般來講, I m p l e m e n t o r接口僅提供基本操作,而 A b s t r a c t i o n則定義了基于這些基本操作的較高層次的組合操作。 ConcreteImplementor 實(shí)現(xiàn)Implementor接口并定義它的具體實(shí)現(xiàn)。,07/07/13,36,3.2.3 Bridge模式的UML類圖,3.2.4 Proxy(代理模式),1. 意圖 為其他對象提供一種代理以控制對這個(gè)對象的訪問。 2. 別名 Surrogate 3. 動(dòng)機(jī) 對一個(gè)對象進(jìn)行訪問控制的一個(gè)原因是為了只有在我們確實(shí)需要這個(gè)對象時(shí)才對它進(jìn)行創(chuàng)建和初始化。我們考慮一個(gè)可以在文檔中嵌入圖形對象的文檔編輯器。有些圖形對象(如大型光柵圖像)的創(chuàng)建開銷很大。但是打開文檔必須很迅速,因此我們在打開文檔時(shí)應(yīng)避免一次性創(chuàng)建所有開銷很大的對象。因?yàn)椴⒎撬羞@些對象在文檔中都同時(shí)可見,所以也沒有必要同時(shí)創(chuàng)建這些對象。 這一限制條件意味著,對于每一個(gè)開銷很大的對象,應(yīng)該根據(jù)需要進(jìn)行創(chuàng)建,當(dāng)一個(gè)圖像變?yōu)榭梢姇r(shí)會(huì)產(chǎn)生這樣的需要。但是在文檔中我們用什么來代替這個(gè)圖像呢? 問題的解決方案是使用另一個(gè)對象,即圖像 P r o x y,替代那個(gè)真正的圖像。 P r o x y可以代替一個(gè)圖像對象,并且在需要時(shí)負(fù)責(zé)實(shí)例化這個(gè)圖像對象。,3.2.4 Proxy:適用性和參與者,適用性: 遠(yuǎn) 程 代 理 ( Remote Proxy ) 為 一 個(gè) 對 象在 不 同 的 地 址 空間 提 供 局 部 代 表。 虛代理(Virtual Proxy)根據(jù)需要?jiǎng)?chuàng)建開銷很大的對象。在動(dòng)機(jī)一節(jié)描述的 ImageProxy就是這樣一種代理的例子。 保護(hù)代理(Protection Proxy)控制對原始對象的訪問。保護(hù)代理用于對象應(yīng)該有不同的訪問權(quán)限的時(shí)候。 智能指引 (Smart Reference)取代了簡單的指針,它在訪問對象時(shí)執(zhí)行一些附加操作。(C+智能指針:auto_ptr) 參與者: Proxy 保存一個(gè)引用使得代理可以訪問實(shí)體。 Subject 定義RealSubject 和Proxy的共用接口,這樣就在任何使用RealSubject的地方都可以使用Proxy。 RealSubject 定義Proxy所代表的實(shí)體。,07/07/13,39,3.2.4 Proxy模式的UML類圖,3.2.4 Proxy例子說明,以論壇中已注冊用戶和游客的權(quán)限不同來作為例子: 已注冊的用戶擁有發(fā)帖,修改自己的注冊信息,修改自己的帖子等功能;而游客只能看到別人發(fā)的帖子,沒有其他權(quán)限。為了簡化代碼,更好的顯示出代理模式的骨架,我們這里只實(shí)現(xiàn)發(fā)帖權(quán)限的控制。,3.2.5 Composite(組合模式),1. 意圖 將對象組合成樹形結(jié)構(gòu)以表示“部分 -整體”的層次結(jié)構(gòu)。Composite使得用戶對單個(gè)對象和組合對象的使用具有一致性。 2. 動(dòng)機(jī) 在繪圖編輯器和圖形捕捉系統(tǒng)這樣的圖形應(yīng)用程序中,用戶可以使用簡單的組件創(chuàng)建復(fù)雜的圖表。用戶可以組合多個(gè)簡單組件以形成一些較大的組件,這些組件又可以組合成更大的組件。一個(gè)簡單的實(shí)現(xiàn)方法是為 Text和Line這樣的圖元定義一些類,另外定義一些類作為這些圖元的容器類 (Container)。 然而這種方法存在一個(gè)問題:使用這些類的代碼必須區(qū)別對待圖元對象與容器對象,而實(shí)際上大多數(shù)情況下用戶認(rèn)為它們是一樣的。對這些類區(qū)別使用,使得程序更加復(fù)雜。Composite模式描述了如何使用遞歸組合,使得用戶不必對這些類進(jìn)行區(qū)別。,3.2.5 Composite:適用性與參與者,適用性: 你想表示對象的部分 -整體層次結(jié)構(gòu)。 你希望用戶忽略組合對象與單個(gè)對象的不同,用戶將統(tǒng)一地使用組合結(jié)構(gòu)中的所有對象。 參與者: Component 為組合中的對象聲明接口。 在適當(dāng)?shù)那闆r下,實(shí)現(xiàn)所有類共有接口的缺省行為。 聲明一個(gè)接口用于訪問和管理 Component的子組件。 Leaf 在組合中表示葉節(jié)點(diǎn)對象,葉節(jié)點(diǎn)沒有子節(jié)點(diǎn)。 在組合中定義圖元對象的行為。 Composite 定義有子部件的那些部件的行為。 存儲(chǔ)子部件。 在Component接口中實(shí)現(xiàn)與子部件有關(guān)的操作。 Client 通過Component接口操縱組合部件的對象。,07/07/13,43,3.2.5 Composite模式的UML類圖,3.3.1 Visitor(訪問者模式),1. 意圖 表示一個(gè)作用于某對象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。 2. 動(dòng)機(jī) 考慮一個(gè)編譯器,它將源程序表示為一個(gè)抽象語法樹。該編譯器需在抽象語法樹上實(shí)施某些操作以進(jìn)行“靜態(tài)語義”分析,例如檢查是否所有的變量都已經(jīng)被定義了。它也需要生成代碼。因此它可能要定義許多操作以進(jìn)行類型檢查、代碼優(yōu)化、流程分析,檢查變量是否在使用前被賦初值,等等。此外,還可使用抽象語法樹進(jìn)行優(yōu)美格式打印、程序重構(gòu)、code instrumentation以及對程序進(jìn)行多種度量。這些操作大多要求對不同的節(jié)點(diǎn)進(jìn)行不同的處理。例如對代表賦值語句的結(jié)點(diǎn)的處理就不同于對代表變量或算術(shù)表達(dá)式的結(jié)點(diǎn)的處理。因此有用于賦值語句的類,有用于變量訪問的類,還有用于算術(shù)表達(dá)式的類,等等。 這里的問題是,將所有這些操作分散到各種節(jié)點(diǎn)類中會(huì)導(dǎo)致整個(gè)系統(tǒng)難以理解、難以維護(hù)和修改。將類型檢查代碼與優(yōu)美格式打印代碼或流程分析代碼放在一起,將產(chǎn)生混亂。此外,增加新的操作通常需要重新編譯所有這些類。如果可以獨(dú)立地增加新的操作,并且使這些節(jié)點(diǎn)類獨(dú)立于作用于其上的操作,將會(huì)更好一些。,3.3.1 Visitor適用性與參與者,在下列情況下使用 Visitor模式: 一個(gè)對象結(jié)構(gòu)包含很多類對象,它們有不同的接口,而你想對這些對象實(shí)施一些依賴于其具體類的操作。 需要對一個(gè)對象結(jié)構(gòu)中的對象進(jìn)行很多不同的并且不相關(guān)的操作,而你想避免讓這些操作“污染”這些對象的類。 Vi s i t o r使得你可以將相關(guān)的操作集中起來定義在一個(gè)類中。當(dāng)該對象結(jié)構(gòu)被很多應(yīng)用共享時(shí),用 Visitor模式讓每個(gè)應(yīng)用僅包含需要用到的操作。 定義對象結(jié)構(gòu)的類很少改變,但經(jīng)常需要在此結(jié)構(gòu)上定義新的操作。改變對象結(jié)構(gòu)類需要重定義對所有訪問者的接口,這可能需要很大的代價(jià)。如果對象結(jié)構(gòu)類經(jīng)常改變,那么可能還是在這些類中定義這些操作較好。 參與者: Visitor(訪問者) ConcreteVisitor(具體訪問者) Element(元素) ConcreteElement(具體元素),07/07/13,46,3.3.1 Visitor模式的UML類圖,函數(shù)名可以重載: 用一樣的名稱,3.3.2 Iterator(迭代器)對象行為型模式,1. 意圖 提供一種方法順序訪問一個(gè)聚合對象中各個(gè)元素 , 而又不需暴露該對象的內(nèi)部表示。 2. 別名 游標(biāo)(Cursor)。 3. 動(dòng)機(jī) 一個(gè)聚合對象 , 如列表 (list), 應(yīng)該提供一種方法來讓別人可以訪問它的元素,而又不需暴露它的內(nèi)部結(jié)構(gòu) . 此外,針對不同的需要,可能要以不同的方式遍歷這個(gè)列表。但是即使可以預(yù)見到所需的那些遍歷操作,你可能也不希望列表的接口中充斥著各種不同遍歷的操作。有時(shí)還可能需要在同一個(gè)表列上同時(shí)進(jìn)行多個(gè)遍歷。 迭代器模式都可幫你解決所有這些問題。這一模式的關(guān)鍵思想是將對列表的訪問和遍歷從列表對象中分離出來并放入一個(gè)迭代器 (i t e r a t o r)對象中。迭代器類定義了一個(gè)訪問該列表元素的接口。迭代器對象負(fù)責(zé)跟蹤當(dāng)前的元素 ; 即, 它知道哪些元素已經(jīng)遍歷過了。,3.3.2 Iterator(迭代器):適用性與參與者,適用性: 訪問一個(gè)聚合對象的內(nèi)容而無需暴露它的內(nèi)部表示。 支持對聚合對象的多種遍歷。 為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口 (即, 支持多態(tài)迭代)。 參與者: Iterator(迭代器) 迭代器定義訪問和遍歷元素的接口。 ConcreteIterator(具體迭代器) 具體迭代器實(shí)現(xiàn)迭代器接口。 對該聚合遍歷時(shí)跟蹤當(dāng)前位置。 Aggregate(聚合) 聚合定義創(chuàng)建相應(yīng)迭代器對象的接口。 ConcreteAggregate(具體聚合) 具體聚合實(shí)現(xiàn)創(chuàng)建相應(yīng)迭代器的接口,該操作返回 ConcreteIterator的一個(gè)適當(dāng)?shù)膶?shí)例。,3.3.2 Iterator模式的UML類圖,3.3.3 Observer(觀察者)對象行為型模式,1. 意圖 定義對象間的一種一對多的依賴關(guān)系 ,當(dāng)一個(gè)對象的狀態(tài)發(fā)生改變時(shí) , 所有依賴于它的對象都得到通知并被自動(dòng)更新。 舉例:“半夜,貓大叫一聲,主人被驚醒,老鼠四散而逃。” 2. 別名 依賴(Dependents), 發(fā)布-訂閱(Publish-Subscribe) 3. 動(dòng)機(jī) 將一個(gè)系統(tǒng)分割成一系列相互協(xié)作的類有一個(gè)常見的副作用:需要維護(hù)相關(guān)對象間的一致性。我們不希望為了維持一致性而使各類緊密耦合,因?yàn)檫@樣降低了它們的可重用性。 這一模式中的關(guān)鍵對象是目標(biāo)( s u b j e c t )和觀察者( o b s e r v e -r )。一個(gè)目標(biāo)可以有任意數(shù)目的依賴它的觀察者。一旦目標(biāo)的狀態(tài)發(fā)生改變 , 所有的觀察者都得到通知。作為對這個(gè)通知的響應(yīng),每個(gè)觀察者都將查詢目標(biāo)以使其狀態(tài)與目標(biāo)的狀態(tài)同步。,3.3.3 Observer(觀察者)對象行為型模式,1. 意圖 定義對象間的一種一對多的依賴關(guān)系 ,當(dāng)一個(gè)對象的狀態(tài)發(fā)生改變時(shí) , 所有依賴于它的對象都得到通知并被自動(dòng)更新。 舉例:“半夜,貓大叫一聲,主人被驚醒,老鼠四散而逃?!?2. 別名 依賴(Dependents), 發(fā)布-訂閱(Publish-Subscribe) 3. 動(dòng)機(jī) 將一個(gè)系統(tǒng)分割成一系列相互協(xié)作的類有一個(gè)常見的副作用:需要維護(hù)相關(guān)對象間的一致性。我們不希望為了維持一致性而使各類緊密耦合,因?yàn)檫@樣降低了它們的可重用性。 這一模式中的關(guān)鍵對象是目標(biāo)( s u b j e c t )和觀察者( o b s e r v e -r )。一個(gè)目標(biāo)可以有任意數(shù)目的依賴它的觀察者。一旦目標(biāo)的狀態(tài)發(fā)生改變 , 所有的觀察者都得到通知。作為對這個(gè)通知的響應(yīng),每個(gè)觀察者都將查詢目標(biāo)以使其狀態(tài)與目標(biāo)的狀態(tài)同步。,3.3.3 Observer(觀察者):適用性與參與者,適用性: 1當(dāng)一個(gè)抽象模型有兩個(gè)方面, 其中一個(gè)方面依賴于另一方面。將這二者封裝在獨(dú)立的對象中以使它們可以各自獨(dú)立地改變和復(fù)用。 2當(dāng)對一個(gè)對象的改變需要同時(shí)改變其它對象, 而不知道具體有多少對象有待改變。 3當(dāng)一個(gè)對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不希望這些對象是緊密耦合的。 參與者: Subject(目標(biāo)) 目標(biāo)知道它的觀察者??梢杂腥我舛鄠€(gè)觀察者觀察同一個(gè)目標(biāo)。 提供注冊和刪除觀察者對象的接口。 Observer(觀察者) 為那些在目標(biāo)發(fā)生改變時(shí)需獲得通知的對象定義一個(gè)更新接口。 ConcreteSubject(具體目標(biāo)) 當(dāng)它的狀態(tài)發(fā)生改變時(shí) , 向它的各個(gè)觀察者發(fā)出通知。 ConcreteObserver(具體觀察者) 維護(hù)一個(gè)指向ConcreteSubject對象的引用。 存儲(chǔ)有關(guān)狀態(tài),這些狀態(tài)應(yīng)與目標(biāo)的狀態(tài)保持一致。 實(shí)現(xiàn)Observer的更新接口以使自身狀態(tài)與目標(biāo)的狀態(tài)保持一致。,3.3.3 Observer模式的UML類圖,3.3.4 Template method(模板方法)對象行為型模式,1. 意圖 定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中。 Te m p l a t e M e t h o d使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。 2. 動(dòng)機(jī) 考慮一個(gè)提供 A p p l i c a t i o n和D o c u m e n t類的應(yīng)用框架。 A p p l i c a t i o n類負(fù)責(zé)打開一個(gè)已有的以外部形式存儲(chǔ)的文檔,如一個(gè)文件。一旦一個(gè)文檔中的信息從該文件中讀出后,它就由一個(gè)Document對象表示。 抽象的Application類在它的OpenDocument操作中定義了打開和讀取一個(gè)文檔的每一個(gè)主要步驟。它檢查該文檔是否能被打開,創(chuàng)建與應(yīng)用相關(guān)的 D o c u m e n t對象,將它加到它入的文檔集合中,并且從一個(gè)文件中讀取該Document。我們稱O p e n D o c u m e n t為一個(gè) 模板方法(template method)。一個(gè)模板方法用一些抽象的操作定義一個(gè)算法,而子類將重定義這些操作以提供具體的行為。,3.3.4 Template method:適用性和參與者,適用性: 一次性實(shí)現(xiàn)一個(gè)算法的不變的部分,并將可變的行為留給子類來實(shí)現(xiàn)。 各子類中公共的行為應(yīng)被提取出來并集中到一個(gè)公共父類中以避免代碼重復(fù)。即 “重分解以一般化”,首先識別現(xiàn)有代碼中的不同之處,并且將不同之處分離為新的操作。最后,用一個(gè)調(diào)用這些新的操作的模板方法來替換這些不同的代碼。 控制子類擴(kuò)展。模板方法只在特定點(diǎn)調(diào)用“Hook Method(鉤子方法)”操作,這樣就只允許在這些點(diǎn)進(jìn)行擴(kuò)展。 參與者: AbstractClass(抽象類,如Application) 定義抽象的 原語操作( primitive operation),具體的子類將重定義它們以實(shí)現(xiàn)一個(gè)算法。 ConcreteClass(具體類,如MyApplication) 實(shí)現(xiàn)原語操作以完成算法中與特定子類相關(guān)的步驟。,3.3.4 Template method模式的UML類圖,3.3.5 Chain of responsibility(職責(zé)鏈)對象行為型模式,1. 意圖 使多個(gè)對象都有機(jī)會(huì)處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個(gè)對象處理它為止。 2. 動(dòng)機(jī) 考慮一個(gè)圖形用戶界面中的上下文有關(guān)的幫助機(jī)制。用戶在界面的任一部分上點(diǎn)擊就可以得到幫助信息,所提供的幫助依賴于點(diǎn)擊的是界面的哪一部分以及其上下文。例如,對話框中的按鈕的幫助信息就可能和主窗口中類似的按鈕不同。如果對那一部分界面沒有特定的幫助信息,那么幫助系統(tǒng)應(yīng)該顯示一個(gè)關(guān)于當(dāng)前上下文的較一般的幫助信息。,3.3.5 Chain of responsibility-適用性和參與者,適應(yīng)性: 有多個(gè)的對象可以處理一個(gè)請求,哪個(gè)對象處理該請求運(yùn)行時(shí)刻自動(dòng)確定; 在不明確指定接收者的情況下,向多個(gè)對象中的一個(gè)提交一個(gè)請求; 處理一個(gè)請求的對象集合應(yīng)被動(dòng)態(tài)指定。 參與者: Handler(如HelpHandler) 定義一個(gè)處理請求的接口。 (可選) 實(shí)現(xiàn)后繼鏈。 ConcreteHandler(如PrintButton和PrintDialog) 處理它所負(fù)責(zé)的請求。 可訪問它的后繼者。 如果可處理該請求,就處理之;否則將該請求轉(zhuǎn)發(fā)給它的后繼者。,3.3.5 Chain of responsibility模式的UML類圖,3.3.6 State(狀態(tài))對象行為型模式,1. 意圖 允許一個(gè)對象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為。對象看起來似乎修改了它的類。 2. 別名 狀態(tài)對象( Objects for States) 3. 動(dòng)機(jī) 考慮一個(gè)表示網(wǎng)絡(luò)連接的類 T C P C o n n e c t i o n。一個(gè) T C P C o n n e c t i o n對象的狀態(tài)處于若干不同狀態(tài)之一 : 連接已建立( E s t a b l i s h e d)、正在監(jiān)聽 ( L i s t e n i n g )、連接已關(guān)閉 ( C l o s e d )。當(dāng)一個(gè)T C P C o n n e c t i o n對象收到其他對象的請求時(shí) , 它根據(jù)自身的當(dāng)前狀態(tài)作出不同的反應(yīng)。例如,一個(gè)O p e n請求的結(jié)果依賴于該連接是處于連接已關(guān)閉狀態(tài)還是連接已建立狀態(tài)。 S t a t e模式描述了TCPConnection如何在每一種狀態(tài)下表現(xiàn)出不同的行為。,3.3.6 State(狀態(tài)):適用性和參與者,適用性: 一個(gè)對象的行為取決于它的狀態(tài) , 并且它必須在運(yùn)行時(shí)刻根據(jù)狀態(tài)改變它的行為。 一個(gè)操作中含有龐大的多分支的條件語句,且這些分支依賴于該對象的狀態(tài)。這個(gè)狀態(tài)通常用一個(gè)或多個(gè)枚舉常量表示。通常 , 有多個(gè)操作包含這一相同的條件結(jié)構(gòu)。 S t a t e模式將每一個(gè)條件分支放入一個(gè)獨(dú)立的類中。這使得你可以根據(jù)對象自身的情況將對象的狀態(tài)作為一個(gè)對象,這一對象可以不依賴于其他對象而獨(dú)立變化。 參與者: Context(環(huán)境,如TCPConnection) 定義客戶感興趣的接口。 維護(hù)一個(gè)ConcreteState子類的實(shí)例,這個(gè)實(shí)例定義
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 冷藏合同范本
- 加工車間轉(zhuǎn)租合同范本
- 不見面簽訂租賃合同范本
- 2025年合肥貨運(yùn)車從業(yè)考試題
- 個(gè)人施工承攬合同范本
- app開發(fā)合同范本模板
- 加工訂單合同范本模板
- 農(nóng)村供熱服務(wù)合同范本
- 個(gè)人股權(quán)質(zhì)押合同范本
- 光租船合同范本
- 生而為贏自燃成陽-開學(xué)第一課發(fā)言稿
- 2024年設(shè)備監(jiān)理師考試題庫及答案參考
- 公司外派學(xué)習(xí)合同范例
- 安徽省合肥市包河區(qū) 2024-2025學(xué)年九年級上學(xué)期期末道德與法治試卷(含答案)
- 2025年一次性死亡賠償協(xié)議模板(2篇)
- 廣州電視塔鋼結(jié)構(gòu)施工方案
- 2024年湖南鐵路科技職業(yè)技術(shù)學(xué)院高職單招數(shù)學(xué)歷年參考題庫含答案解析
- 《梅大高速茶陽路段“5·1”塌方災(zāi)害調(diào)查評估報(bào)告》專題警示學(xué)習(xí)
- 2024年06月江蘇昆山鹿城村鎮(zhèn)銀行校園招考筆試歷年參考題庫附帶答案詳解
- 小學(xué)二年級100以內(nèi)進(jìn)退位加減法800道題
- 3ds Max動(dòng)畫制作實(shí)戰(zhàn)訓(xùn)練(第3版)教學(xué)教案
評論
0/150
提交評論