每種設計模式的特點

設計模式:

是面向對象的軟件開發經驗的總結,其中包含了軟件設計中很多問題的解決方案和設計思路,是可直接利用的程序結構。

按照以下要點討論設計模:

l模式名稱:表達設計思想的簡單名字
l設計意圖:針對的問題和解決問題的思路
l實現效果:達到的實際效果及作用
l技術途徑:採用的技術方法和策略

設計模式分類:

構造式:涉及對象創建過程的模式
結構式:涉及對象類組合的模式
行爲式:涉及對象之間交互操作的模式

4.2構造型設計模式

構造型設計模式,提供在系統中創建獨立對象、創建組合對象,創建系列對象的基本方法。
構造型模式中,始終圍繞的問題:
Ø將結構不同、功能不同的“產品”對象,用靈活的配置方式來創建,以適應未來的變化。
Ø怎樣創建對象的問題,在何時創建?由誰來創建?

1)抽象工廠Abstract Factory模式

將系列產品的製造責任和部件封裝起來,因爲系列產品有着相同的構件部分,但每個系列產品的部件又有所不同。

應用可根據不同系列的產品需求,組織不同產品部件對象的創建,完成系列產品的製造。

利用多態性的動態綁定機制:

·用抽象類描述系列產品的製造部件;

·用繼承來描述具體產品的實現;

·在應用中利用抽象類的各種操作設計系列產品的接口函數;

·在用應用中通過接口函數實現不同產品的統一建造過程。

AbstractFactory適用的軟件問題:

希望系統可以由不確定的系列產品來配置,僅提供一個配置的框架
強調一系列相關對象的預先存在,以便進行組裝和使用
使系統能適由於對象不同、組合不同,以及表示不同的多種情況
通常是與工廠方法配合使用的

2工廠方法Factory Method模式

對相同結構的不同應用實體,需要向不同的實體發送相應的操作請求,以完成各自不同的同一形式的操作。

在抽象類中利用的工廠方法由子類具體化,以得到結構相同的不同的對象實體。這樣,可以向不同的實體發出消息,靈活地實現同類結構的不同實體的操作。

在類的內部創建並得到對象,可以將類的某些職責委託給一個獨立的類,用以擴充類的某種操作,達到平行擴展效果。

建立應用操作類與需要的對象實體類關聯,用工廠方法創建並返回實際的對象實體,然後可以利用該實體對象完成必要的操作請求。

FactoryMethod適用的軟件問題:

當一個類不確定它所必須創建的對象的類時
希望由子類來指定所創建的對象時
當希望由子類來代理完成局部功能時,將創建對象的職責委託給某個子類。

3)轉換器/生成器Converter/Builder模式

將不同對象的不同操作以同樣的過程統一起來。

引導器通過關聯Builder,完成統一的構造過程。 Builder子類中的各項操作,無論數量和內容都可能各不相同。

在應用中定義所需要的引導器,用以完成統一步驟的處理,並用關聯的構造器實例來完成相應的處理;

根據需要從構造器繼承子類來實現不同的處理方式。

Builder適用的軟件問題:

當需要將對象的某些複雜處理過程或算法,與他的創建和組裝方式相互獨立時
當構造過程必須根據被構造的對象而有所不同時

對構造的三個模式的比較:

抽象工廠模式,定義一個創建系列產品的類,可根據需要定義相同系列的具體產品類,以適應需求的變化。

生成器模式,爲解決系列產品的構造過程相同,但系列中的具體產品其部件成分可能不同。

工廠方法模式,針對產品的不可預定情況,用一個方法得到某個具體產品的實體,以完成不同產品的相同形式操作。

通常情況下,在Abstract FactoryBuilder以及Factory Method是相互結合使用的。

4.3構式設計模式

結構型設計模式,涉及如何組織對象類,成爲適用的更大結構問題。

 結構型設計模式,主要針對希望靈活地實現新的功能的方法。

 結構型設計模式有很強的相似性,應該注意區分它們的設計意圖,瞭解各自的優勢和必須付出的代價。

1)適配器Adapter模式

爲複用已有的成分,將不適應的接口轉換成應用需要的另一個接口。

Adapter與原有的不同的Adaptee協同工作

使原來的目標請求方法適配成已有的對象方法。

Adapter模式是爲解決兩個已有接口之間的不匹配問題。

當需要不加修改地利用已有類的對象協同工作時,即協同兩個不兼容的類時,可採用Adapter模式。

Adapter適用的軟件問題:

需要使用一個已經存在的類,而它的接口不符合需求
需要創建一個可複用的類,該類可以與其它不相關或不可預見的類協同工作(不相關或不可預見表明接口不兼容)
需要使用一些已經存在的子類,但不可能對其一一匹配,可以適配它們的父類接口

2)橋(Bridge)模式

未來的需求,能應對操作接口和相關實現的操作獨立演變。

分離與實現相關的部分,因爲它們雖然有相同的操作,但卻有不同的操作處理情況。用關聯及多態機制建造穩定的接口,執行多種情況的不同實現。

將與實現環境相關操作部分獨立

對外隱藏實現細節,實現應用透明訪問

目的是爲提供穩定的操作接口。將一般操作接口與實現環境相關的操作接口進行橋接,相關實現部分可能不同,替換實現而不用改變接口。當然修改操作接口也不會影響相關實現的操作部分。

Bridge適用的軟件問題:

希望在抽象類和它的實現部分之間有一個固定的綁定關係
需要抽象類和它的實現部分分別加以擴充
希望實現部分的修改對外不產生影響。即客戶代碼不必重新編譯
希望在客戶不知道的情況下,多個對象間共享實現

3)代理(Proxy)模式

當直接訪問某實體對象不合需求,又不希望對其直接修改,這樣,可以爲該實體提供一個替代者並採用相同的操作形式訪問它,已完成某些必要操作,之後再由代理向主體轉發實際的操作請求。

遠程代理:可隱藏實際主體存在的不同地址空間

虛代理:可以實現優化處理,根據要求創建對象

保護代理:在訪問實際主體時附加必要的處理。

  Proxy模式由實際主體定義關鍵的功能,而代理在完成必要的操作後,轉發實際的訪問請求,它強調這種固定的關係。

Proxy適用的軟件問題:

需要用通用或複雜的對象的引用代替簡單的引用,例如:遠程代理、虛代理、保護代理、只能引導
對指針實際對象引用的計數
當第一次引用一個持久對象時,需要將其裝入內存
在訪問一個實際對象前,檢查是否鎖定了它,以確保其它對象不能改變它

4)裝飾(Decorator)模式

將裝飾器嵌入組件,用以完成對組件的必要的多項操作,這樣可以迴避使用多重繼承解決方案帶來的複雜性。

使用組件接口,爲給定的對象類動態添加操作

通過裝飾器的關聯,使繼承的每個操作責任類能夠既執行自身的操作,又可轉接執行給定對象類的操作。

Decorator適用的軟件問題:

在不影響其它對象的情況下,以動態方式給對象添加職責
需要處理可以撤銷的職責
當不能採用生成子類方式進行系統擴充時。

兩種情況不能採用生成子類來擴充系統:

1)爲支持大量獨立擴充,而產生大量子類

2)類定義被隱藏或不能用於生成子類

4.4 行爲式設計模式

行爲型設計模式主要針對算法和對象之間的職責分配問題。
行爲型設計模式不僅描述類或對象的結構模式,還要描述類或對象之間的通信模式。
對象之間的通信聯繫方式,反映了運行時難以跟蹤的複雜的控制流。
行爲型設計模式的基本策略是封裝行爲。

1)責任鏈(Chain Responsibility)模式

使請求和接收之間形成鬆散耦合關係。對象之間連成一條鏈,使對象沿着這條鏈傳遞請求,直到有一個對象處理它。這樣,每個對象都有機會處理請求。

降低耦合。請求對象不用知道哪個對象處理請求,鏈中的對象也不用知道鏈的結構。

提高靈活性。可以方便簡單地對鏈進行動態增加或改變處理責任。

代價是效率問題,以及並不保證請求一定能被接收處理。

ChainResponsibility適用的軟件問題:

有多個對象處理一個請求,可在運行時自動確定由哪個對象來處理該請求
在不明確指定接收者的情況下,向多個對象中的某一個提交請求
可處理動態指定的一個請求的對象集合

2)觀察者Observer模式結構

針對對象之間的一對多關係,當一個對象的狀態發生變化時,所有依賴於它的對象都得到通知並被自動更新。這種模式起源於經典的MVC模式,也叫publish/subscribe發佈/訂閱模式。

當目標發生變化時,觀察者與目標的狀態產生不一致,目標需要通知各個觀察者;

當觀察者得到改變的通知後,向目標對象發出查詢信息請求,用得到的查詢信息使自己與目標對象狀態保持一致。

可獨立改變目標和觀察者,可單獨複用目標對象及觀察者對象。

支持廣播通信,目標發送通知不需要指定接收者,通知被自動廣播給所有已向目標對象登記了的觀察者,對於是否處理通知,完全取決與觀察者,觀察者的自由度很高。

如果觀察者之間存在相關性,則存在意外的、不該更新的操作,必要時需要更復雜的約束條件和協議。

Observer適用的軟件問題:

當一個抽象模型的兩個方面,一個依賴於另一個時,將二者封裝在獨立對象中,以使它們可以各自獨立改變和複用
當對一個對象的改變需要通知改變其它對象,而不知道具體有多少對象有待改變
當一個對象必須通知其它對象,而又不確定其他對象是誰,即不希望它們是緊密耦合的

3)狀態模式

將與特定狀態相關的行爲局部化,將不同的行爲分割開,每個特定狀態所相關的行爲被封裝在一個獨立的類中,這樣,可以通過定義新的子類,來增加狀態的方式轉換。
使狀態轉換顯式化,對不同的狀態設立獨立的對象,使狀態轉換明確。同時,由於狀態轉換操作的原子性,可保證狀態的一致性。

將對象的狀態作爲一個對象類,封裝狀態類的行爲,當對象的狀態改變時,行爲隨之改變。

4)循環器Iterater模式

提供順序訪問聚合Aggregate對象(如:列表對象)的循環器超類,用繼承方式封裝不同聚合對象的不同遍歷操作。每個聚合對象,都可以執行創建循環器的操作,並帶着指向自身的指針作爲操作的主體。

每個不同的具體循環器,支持以不同的方式遍歷聚合的實體羣。

循環器可簡化聚合的操作接口,因爲有了循環器的遍歷操作接口,不再需要聚合操作接口了。

可以在同一個聚合上完成多種的遍歷操作。

5)中介Mediator模式

用中介對象來封裝同僚對象之間的交互行爲,它使他們之間不需要顯式地相互引用,構成鬆散耦合,可獨立地改變它們之間的交互。

將分佈於多個對象間的行爲形成統一的行爲。

各同僚對象實現解耦,可獨立改變,並可複用ColleagueMediator

使多對多協議簡化爲一對多協議,關係易於理解和維護

交互的複雜性集中於中介者。

6)策略Strategy模式

把一系列同類的算法封裝起來,使算法獨立於應用,對同類算法的利用靈活可變。

策略Strategy類提供了可重用的算法或行爲。

將算法或行爲封裝在Strategy類中,可以獨立於Context改變它。

在三種類型的設計模式中,似乎有很多相似的模式。

瞭解模式之間的差異非常重要,因爲它們針對的是面向對象設計過程中,一些特定的、經常發生的問題,給出了相應解決問題的方法和途徑。

     模式總是相互結合使用的,當在設計中需要權衡利弊、決定取捨時,瞭解多個模式,並能準確地區分它們,可以提供更大的設計空間和更多的選擇餘地。

Adapter模式主要是爲了解決兩個已有接口之間的不匹配問題。它不去考慮接口是怎樣實現的,也不考慮重新設計某個類,只是將已有類的對象不加修改地利用起來,協同工作。

Bridge模式的主要目的是爲提供穩定的接口。對接口與對應的實現部分進行橋接。對應的實現部分可能有多個,修改實現而不用改變接口。當然修改接口也不會影響實現。

   這樣,在選擇採用模式時,當需要協同兩個不兼容的類時,採用Adapter模式;當接口和實現可能會獨立演變時,採用Bridge模式

Proxy模式的目的是,當直接訪問一個實體不方便或不合需求時,爲該實體提供一個替代者。

Proxy模式構成一個對象,併爲應用提供一致的接口,但不能動態地添加或取消某種屬性。

Proxy模式中,由實體定義關鍵的功能,而Proxy僅提供對實體的訪問,它強調一種固定的關係,因此這種關係可以靜態表達。

   行爲是程序中最有可能改變的因素。封狀行爲,爲避免對象中的不定因素成爲不可分割的部分,封裝包括兩種:

   封裝某種行爲特徵的新對象

   封裝某種行爲特徵的已有的對象

Strategy封裝算法或行爲

State封裝狀態相關的行爲

Mediator封裝對象之間的協議

Iterator封裝訪問和遍歷的聚集對象

ObserverMediator模式的區別:

Observer引入觀察者和目標的相互協助來維持約束。一個目標可以有多個觀察者,一個觀察者也能夠成爲目標被觀察。觀察者和目標創建後立即被連接起來,需要知道它們之間的連接方式。觀察者和目標是鬆散耦合。

Mediator的目標是集中維護一個整體的約束。它使信息流簡單,容易理解,不需要知道目標間的連接方式

   合作的對象之間直接引用,會使它們相互依賴。這給系統的分層和重用帶來困難。ObserverMediatorChain of Responsibility 模式,都涉及了將發送和接收解耦的問題。它們使用了不同的方式,有各自的權衡考慮。

Observer觀察者模式:通過定義一個接口來通知目標發生變化,使發送者和接收者解耦,它是爲處理變化而考慮的。

Mediator中介者模式:使對象通過中介對象間接相互引用,從而達到解耦。中介爲各Colleague對象請求提供路由,採用分發策略。它是爲不限定請求操作的數目而考慮的。

責任鏈模式:通過沿着一個潛在的接收者鏈傳遞請求,這樣,使發送者和接收者解耦。責任鏈也需要分發策略。它更多地考慮接收者和發送者的變化和擴充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章