程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> [C++設計模式] decorator 裝飾者模式

[C++設計模式] decorator 裝飾者模式

編輯:關於C++

《head first》中 的例子:咖啡店有各種咖啡飲料,可以往咖啡裡面加各種調料變成另一種飲料,如果使用繼承的方式來為每一種飲料設計一個類,代碼的復雜度很容易膨脹,而且會繼承父類的所有特性,由於繼承為類型引入的靜態特質,使得這種擴展方式缺乏靈活性;同時,又掉入了另一個陷阱,隨著擴展功能的增多,子類也會增多,各種子類的組合,就會導致類的膨脹,最後,就會被淹沒在類的海洋。

這時大神們就發明了裝飾者模式,在不修改現在有接口和實現類的基礎上實現功能或者狀態的添加。

decorator(裝飾者模式):動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator模式相比生成子類更為靈活。

裝飾模式能夠實現動態的為對象添加功能,是從一個對象外部來給對象添加功能。通常給對象添加功能,要麼直接修改對象添加相應的功能,要麼派生對應的子類來擴展,抑或是使用對象組合的方式。顯然,直接修改對應的類這種方式並不可取。在面向對象的設計中,而我們也應該盡量使用對象組合,而不是對象繼承來擴展和復用功能。裝飾器模式就是基於對象組合的方式,可以很靈活的給對象添加所需要的功能。裝飾器模式的本質就是動態組合。動態是手段,組合才是目的。總之,裝飾模式是通過把復雜的功能簡單化,分散化,然後再運行期間,根據需要來動態組合的這樣一個模式。它使得我們可以給某個對象而不是整個類添加一些功能。

\

Component:定義一個對象接口,可以給這些對象動態地添加職責;


ConcreteComponent:定義一個具體的Component,繼承自Component,重寫了Component類的虛函數;


Decorator:維持一個指向Component對象的指針,該指針指向需要被裝飾的對象;並定義一個與Component接口一致的接口;


ConcreteDecorator:向組件添加職責。

 

使用場景:

1,在不影響其他對象的情況下,以動態的,透明的方式給單個對象添加職責;

2,處理那些可以撤銷的職責;

3,當不能采用生成子類的方法進行擴充時。一種情況是,可能存在大量獨立的擴展,為支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用於生成子類。

示例代碼:

 

#include 
using namespace std;
class Component
{
public:
     virtual void Operation() = 0;
};
class ConcreteComponent : public Component
{
public:
     void Operation()
     {
          cout<Operation();
          }
     }
protected:
     Component *m_pComponentObj;
};
class ConcreteDecoratorA : public Decorator
{
public:
     ConcreteDecoratorA(Component *pDecorator) : Decorator(pDecorator){}
     void Operation()
     {
          AddedBehavior();
          Decorator::Operation();
     }
     void  AddedBehavior()
     {
          cout<Operation();
     cout<<=============================================<Operation();
     cout<<=============================================<Operation();
     cout<<=============================================<實現要點:

 

1,接口的一致性;裝飾對象的接口必須與它所裝飾的Component的接口是一致的,因此,所有的ConcreteDecorator類必須有一個公共的父類;這樣對於用戶來說,就是統一的接口;

2,省略抽象的Decorator類;當僅需要添加一個職責時,沒有必要定義抽象Decorator類。因為我們常常要處理,現存的類層次結構而不是設計一個新系統,這時可以把Decorator向Component轉發請求的職責合並到ConcreteDecorator中;

3,保持Component類的簡單性;為了保證接口的一致性,組件和裝飾必須要有一個公共的Component類,所以保持這個Component類的簡單性是非常重要的,所以,這個Component類應該集中於定義接口而不是存儲數據。對數據表示的定義應延遲到子類中,否則Component類會變得過於復雜和臃腫,因而難以大量使用。賦予Component類太多的功能,也使得具體的子類有一些它們它們不需要的功能大大增大;

4,Component類在Decorator模式中充當抽象接口的角色,不應該去實現具體的行為。而且Decorator類對於Component類應該透明,換言之Component類無需知道Decorator類,Decorator類是從外部來擴展Component類的功能; 5,Decorator類在接口上表現為“is-a”Component的繼承關系,即Decorator類繼承了Component類所具有的接口。但在實現上又表現為“has-a”Component的組合關系,即Decorator類又使用了另外一個Component類。我們可以使用一個或者多個Decorator對象來“裝飾”一個Component對象,且裝飾後的對象仍然是一個Component對象;,

6,Decortor模式並非解決“多子類衍生的多繼承”問題,Decorator模式的應用要點在於解決“主體類在多個方向上的擴展功能”——是為“裝飾”的含義;

7,對於Decorator模式在實際中的運用可以很靈活。如果只有一個ConcreteComponent類而沒有抽象的Component類,那麼Decorator類可以是ConcreteComponent的一個子類。如果只有一個ConcreteDecorator類,那麼就沒有必要建立一個單獨的Decorator類,而可以把Decorator和ConcreteDecorator的責任合並成一個類。

8,Decorator模式的優點是提供了比繼承更加靈活的擴展,通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合;

9,由於使用裝飾模式,可以比使用繼承關系需要較少數目的類。使用較少的類,當然使設計比較易於進行。但是,在另一方面,使用裝飾模式會產生比使用繼承關系更多的對象。更多的對象會使得查錯變得困難,特別是這些對象看上去都很相像。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved