七、外觀模式(Facade)
1、定義
為子系統的一組介面提供一個一致的介面,定義了一個高層介面,這個介面使得這一子系統更容易使用。
2、類圖
3、呼叫順序
4、程式碼示例
5、何時選用外觀模式
1、如果你希望為一個複雜的子系統提供一個簡單介面的時候
2、如果想要讓客戶程式和抽象類的實現部分鬆散耦合
3、如果構建多層結構的系統
八、介面卡(Adapter)
1、定義
將一個類的介面轉換成 客戶希望的另外一個介面。使得原本由於介面不相容的類可以一起工作。
2、類圖
Client:客戶端,呼叫自己需要的領域介面Target。Target:定義客戶端需要的跟特定領域相關的介面。
Adaptee:已經存在的介面,通常能滿足客戶端的功能要求,但是介面與客戶端要求的特定領域介面不一致,需要被適配。
Adapter:介面卡,把Adaptee適配成為Client需要的Target。
3、程式碼示例
4、何時選用介面卡模式
1、如果你想要使用一個已經存在的類,但是它的介面不符合你的需求
2、如果你想建立一個可以複用的類,這個類可能和一些不相容的類一起工作
3、如果你想使用一些已經存在的子類,但是不可能對每一個子類都進行適配
九、橋接模式(Bridge)
1、定義
將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
2、類圖
Abstraction:抽象部分的介面。通常在這個物件裡面,要維護一個實現部分的物件引用,在抽象物件裡面的方法,需要呼叫實現部分的物件來完成。這個物件裡面的方法,通常都是跟具體的業務相關的方法。RefinedAbstraction:擴充套件抽象部分的介面,通常在這些物件裡面,定義跟實際業務相關的方法,這些方法的實現通常會使用Abstraction中定義的方法,也可能需要呼叫實現部分的物件來完成。
Implementor:定義實現部分的介面,這個介面不用和Abstraction裡面的方法一致,通常是由Implementor介面提供基本的操作,而Abstraction裡面定義的是基於這些基本操作的業務方法,也就是說Abstraction定義了基於這些基本操作的較高層次的操作。
ConcreteImplementor:真正實現Implementor介面的物件。
3、呼叫順序
4、示例程式碼
5、何時選用橋接模式
1、如果你不希望在抽象和實現部分採用固定的繫結關係,可以採用橋接模式,來把抽象和實現部分分開,然後在程式執行期間來動態的設定抽象部分需要用到的具體的實現,還可以動態切換具體的實現。
2、如果出現抽象部分和實現部分都應該可以擴充套件的情況,可以採用橋接模式,讓抽象部分和實現部分可以獨立的變化,從而可以靈活的進行單獨擴充套件,而不是攪在一起,擴充套件一邊會影響到另一邊。
3、如果希望實現部分的修改,不會對客戶產生影響,可以採用橋接模式,客戶是面向抽象的介面在執行,實現部分的修改,可以獨立於抽象部分,也就不會對客戶產生影響了,也可以說對客戶是透明的。
4、如果採用繼承的實現方案,會導致產生很多子類,對於這種情況,可以考慮採用橋接模式,分析功能變化的原因,看看是否能分離成不同的緯度,然後通過橋接模式來分離它們,從而減少子類的數目。
十、組合模式(Composite)
1、定義
將物件組合成屬性結構以表示“部分-整體”的層次結構,組合模式使得使用者對單個物件和組合對用的使用具有一致性。
2、類圖
Component:抽象的元件物件,為組合中的物件宣告介面,讓客戶端可以通過這個介面來訪問和管理整個物件結構,可以在裡面為定義的功能提供預設的實現。Leaf:葉子節點物件,定義和實現葉子物件的行為,不再包含其它的子節點物件。
Composite:組合物件,通常會儲存子元件,定義包含子元件的那些元件的行為,並實現在元件介面中定義的與子元件有關的操作。
Client:客戶端,通過元件介面來操作組合結構裡面的元件物件。
3、示例程式碼
4、何時選用組合模式
1、如果你想表示物件的部分-整體層次結構,可以選用組合模式,把整體和部分的操作統一起來,使得層次結構實現更簡單,從外部來使用這個層次結構也簡單;
2、如果你希望統一的使用組合結構中的所有物件,可以選用組合模式,這正是組合模式提供的主要功能;
十一裝飾者(Decorator)
1、定義
動態的給一個物件新增一些額外的職責。就增加功能來說,裝飾模式比生成子類更靈活。
2、類圖
Component:元件物件的介面,可以給這些物件動態的新增職責。 ConcreteComponent:具體的元件物件,實現元件物件介面,通常就是被裝飾器裝飾的原始物件,也就是可以給這個物件新增職責。Decorator:所有裝飾器的抽象父類,需要定義一個與元件介面一致的介面,並持有一個Component物件,其實就是持有一個被裝飾的物件。注意,這個被裝飾的物件不一定是最原始的那個物件了,也可能是被其它裝飾器裝飾過後的物件,反正都是實現的同一個介面,也就是同一型別。
ConcreteDecorator:實際的裝飾器物件,實現具體要向被裝飾物件新增的功能。
3、示例程式碼
4、何時選用裝飾模式
1、如果需要在不影響其它物件的情況下,以動態、透明的方式給物件新增職責
2、如果不合適使用子類來進行擴充套件的時候
十二、享元模式(Flyweight)
1、定義
運用共享技術有效地支援大量細粒度的物件。
2、類圖
Flyweight:享元介面,通過這個介面flyweight可以接受並作用於外部狀態。通過這個介面傳入外部的狀態,在享元物件的方法處理中可能會使用這些外部的資料。ConcreteFlyweight:具體的享元實現物件,必須是可共享的,需要封裝flyweight的內部狀態。
UnsharedConcreteFlyweight:非共享的享元實現物件,並不是所有的Flyweight實現物件都需要共享。非共享的享元實現物件通常是對共享享元物件的組合物件。
FlyweightFactory:享元工廠,主要用來建立並管理共享的享元物件,並對外提供訪問共享享元的介面。
Client:享元客戶端,主要的工作是維持一個對flyweight的引用,計算或儲存享元物件的外部狀態,當然這裡可以訪問共享和不共享的flyweight物件。
3、呼叫順序
4、示例程式碼
5、何時選用享元模式
1、如果一個應用程式使用了大量的細粒度物件,可以使用享元模式來減少物件數量;
2、如果由於使用大量的物件,造成很大的儲存開銷,可以使用享元模式來減少物件數量,並節約記憶體;
如果物件的大多數狀態都可以轉變為外部狀態,比如通過計算得到,或是從外部傳入等,可以使用享元模式來實現內部狀態和外部狀態的分離; 如果不考慮物件的外部狀態,可以用相對較少的共享物件取代很多組合物件,可以使用享元模式來共享物件,然後組合物件來使用這些共享物件;
十三、代理模式(Proxy)
1、定義
為其他物件提供一種代理以控制對這個物件的訪問。
2、類圖
Proxy:代理物件,通常具有如下功能:-
實現與具體的目標物件一樣的介面,這樣就可以使用代理來代替具體的目標物件
-
儲存一個指向具體目標物件的引用,可以在需要的時候呼叫具體的目標物件,可以控制對具體目標物件的訪問,並可能負責建立和刪除它
Subject:目標介面,定義代理和具體目標物件的介面,這樣就可以在任何使用具體目標物件的地方使用代理物件
RealSubject:具體的目標物件,真正實現目標介面要求的功能。
3、呼叫順序
4、示例程式碼
5、何時選用代理模式
需要為一個物件在不同的地址空間提供區域性代表的時候,可以使用遠端代理;
需要按照需要建立開銷很大的物件的時候,可以使用虛代理;
需要控制對原始物件的訪問的時候,可以使用保護代理;
需要在訪問物件的時候執行一些附加操作的時候,可以使用智慧指引代理;