裝飾模式(Decorator)C++實現


裝飾模式

       層層包裝,增強功能。這就是裝飾模式的要旨!裝飾器模式就是基於對象組合的方式,可以很靈活的給對象添加所需要的功能。它把需要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的對象。

意圖:

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

 

適用性:

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

       2、處理那些可以撤銷的職責。

       3、希望為某個對象而不是一整個類添加一些功能時。

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

 

效果:

       1、比靜態繼承更為靈活。繼承機制會產生許多新類,增加了系統的復雜度。而裝飾可以使你對一些職責進行混合和匹配。

       2、避免在層次結構高層的類有太多的特征。擴展一個復雜類的時候,很可能會暴露出與添加職責無關的細節。你可以定義一個簡單的類,並且用裝飾逐漸的添加功能。

       3、會產生許多小對象

       4、Decorator與Component不一樣,Decorator是一個透明的包裝。如果我們從對象標識的觀點出發,一個被裝飾了的組件與這個組件是有差別的,因此,使用裝飾時不應該依賴對象標識。

 

注意:

       1、接口的一致性。裝飾對象的接口必須與它所裝飾的Component的接口是一致的。

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

       3、保持Component類的簡單性。為了保證接口的一致性,組件和裝飾必須有一個共同的Component父類。因此保持這個類的簡單些是很重要的。

      

 

 

參與者:

Component

——定義一個對象接口,可以給這些對象動態的添加職責。

ConcreteComponent

——定義一個對象,可以給這個對象添加一些職責。

Decorator

——維持一個指向Component對象的指針,並定義一個與Component接口一致的接口。

ConcreteDecorator

——向組件添加職責。

 

UML:

 

 

代碼實現:在控制台打印如下表格,基本的姓名、年齡、學歷、性別必須擁有,其它如英語等級等屬性自由添加。

 

打印一行表格代碼:

void print(char* str)
{
    cout<<"├───────────────────────────────"<<endl
        <<""<<str<<":"<<endl;
}

定義一個抽象基類absTable(Component)

class absTable
{
public:
virtual void putTable() = 0;
};

定義具體的表格absTable(ConcreteComponent)

class BaseTable:public absTable
{
public:
    virtual void putTable()
    {
        print("姓名");
        print("性別");
        print("學歷");
        print("年齡");
        cout<<"└───────────────────────────────"<<endl;
    }
};

定義抽象Decorator

class Decorator:public absTable
{
public:
    Decorator(absTable* concrateTb):mpAbsTable(concrateTb){}

    virtual void putTable()
    {
        mpAbsTable->putTable();
    }
private:
    absTable* mpAbsTable;
};

定義具體的裝飾EnglishDcrt、CurWage、Experience(ConcreteDecoratorA、B、C)

class EnglishDcrt:public Decorator
{
public:
    EnglishDcrt(absTable* pTb):Decorator(pTb){}

    virtual void putTable()
    {
        print("英語等級");
        Decorator::putTable();
    }
};
class CurWage:public Decorator
{
public:
    CurWage(absTable* pTb):Decorator(pTb){}

    virtual void putTable()
    {
        print("當前薪水");
        Decorator::putTable();
    }
};
class Experience:public Decorator
{
public:
    Experience(absTable* pTb):Decorator(pTb){}

    virtual void putTable()
    {
        print("項目經驗");
        Decorator::putTable();
    }
};

客戶端代碼:

#include <iostream>
#include "Decorator.h"

using namespace std;

//動態的給一個對象添加一些額外的職責!
//層層包裝,增強功能。這就是裝飾模式的要旨!
//接口穩定不變!

void main()
{
    BaseTable pro1;
    cout<<"初始表格:"<<endl<<endl;
    pro1.putTable();

    cout<<"新表格1:"<<endl<<endl;
    EnglishDcrt eng(&pro1);
    eng.putTable();

    cout<<"新表格2:"<<endl<<endl;
    CurWage wg(&eng);
    wg.putTable();

    cout<<"新表格3:"<<endl<<endl;
    Experience ex(&wg);
    ex.putTable();
}

部分結果:

 

這樣我們實現了項目經驗、當前薪水、英語等級的自由組合,當然還可以添加更多的屬性。

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM