設計模式之《裝飾模式》

問:

現有類  A,如果想對類A進行功能增強,有幾種方法?

答:在C++種,常用的3種,分別是:

  1. 直接修改類A的代碼。但是不符合開閉原則
  2. 使用繼承,讓派生類B來擴充類A的功能
  3. 使用關聯/組合的方式,讓類C包含類A,然後對A進行增強(裝飾模式基於此方法)

裝飾模式:

         裝飾模式(Decorator Pattern)是動態的給一個對象添加一些額外的職責,就增加功能來說,此模式比生成子類更爲靈活。

特點:

(1) 裝飾對象和真實對象有相同的接口。這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。

(2) 裝飾對象包含一個真實對象的引用(reference)

(3) 裝飾對象接受所有來自客戶端的請求。它把這些請求轉發給真實的對象。

(4) 裝飾對象可以在轉發這些請求以前或以後增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結構就可以在外部增加附加的功能。在面向對象的設計中,通常是通過繼承來實現對給定類的功能擴展。

UML類圖:

簡單實現代碼: 

#ifndef DECORATEMODE_H
#define DECORATEMODE_H

#include <iostream>
using namespace std;

class Component
{
public:
    virtual void Operation() = 0;
};


/**
 * @brief The ConcreteComponent class
 * 真實的對象
 */
class ConcreteComponent : public Component
{
public:
    void Operation()
    {
        cout << "具體對象的操作"<<endl;
    }
};

/**
 * @brief The Decorator class
 * 裝飾的對象
 */
class Decorator : public Component
{
public:
    void setComponent( Component * component)
    {
        m_component = component;
    }

    void Operation()
    {
        cout <<"Decorator::Operation()"<<endl;

        if ( nullptr != m_component )
        {
            m_component->Operation();
        }

    }

private:
    //真實的對象
    Component *m_component;
};


class ConcreateDecoratorA : public Decorator
{
public:
    void Operation()
    {
        Decorator::Operation();
        m_addedState = "new State";
        cout<<"具體裝飾對象A的操作"<<m_addedState<<endl;
    }

private:
    string m_addedState;
};


class ConcreateDecoratorB : public  Decorator
{
public:
    void Operation()
    {
        Decorator::Operation();
        addedBehavior();
        cout<<"具體裝飾對象B的操作"<<endl;
    }

    void addedBehavior()
    {
        cout<<" ConcreateDecoratorB::addedBehavior() "<<endl;
    }


};

#endif // DECORATEMODE_H

客戶端調用代碼;


#include "decoratemode.h"


int main()
{

    ConcreteComponent *c = new ConcreteComponent;
    ConcreateDecoratorA *d1 = new ConcreateDecoratorA;
    ConcreateDecoratorB *d2 = new ConcreateDecoratorB;

    d1->setComponent(c);
    d2->setComponent(d1);
    d2->Operation();

    return 0;
}





《大話設計模式》種小菜的UML圖:

《大話設計模式》書中小菜的代碼:

#ifndef DRESSUP_H
#define DRESSUP_H

#include <iostream>
using namespace std;


/**
 * @brief The Person class
 * Person類 (ConcreateComponent)
 */

class Person
{
public:
    Person()
    {

    }

    Person(string name)
    {
        m_name = name;
    }

    virtual void show()
    {
        cout<<"裝扮的: "<<m_name<<endl;
    }

private:
    string m_name;
};

/**
 * @brief The Finery class
 * 服飾類 (Decorator)
 */
class Finery : public Person
{
public:
    void Decorate( Person *component)
    {
        m_component = component;
    }

    void show()
    {
        if( m_component != nullptr )
            m_component->show();
    }

private:
    Person *m_component;
};

/**
 * @brief The TShirts class
 * 具體的服飾類 (ConcreateDecorator)
 */
class TShirts : public Finery
{
public:
    void show()
    {
        cout <<"大T恤"<<endl;
        Finery::show();
    }

};


class BigTrouser : public Finery
{
public:
    void show()
    {
        cout <<"跨庫"<<endl;
        Finery::show();
    }

};


class Sneakers : public Finery
{
public:
    void show()
    {
        cout <<"破球鞋"<<endl;
        Finery::show();
    }

};


class Suit : public Finery
{
public:
    void show()
    {
        cout <<"西裝"<<endl;
        Finery::show();
    }

};


class Tie : public Finery
{
public:
    void show()
    {
        cout <<"領帶"<<endl;
        Finery::show();
    }

};


class LeatherShoes : public Finery
{
public:
    void show()
    {
        cout <<"皮鞋"<<endl;
        Finery::show();
    }

};


#endif // DRESSUP_H

客戶端調用代碼:


#include "dressup.h"

int main()
{

    Person *xc = new Person("小菜");
    cout<<"\n第一種裝扮"<<endl;

    Sneakers *pqx = new Sneakers;
    BigTrouser *kk = new BigTrouser;
    TShirts *dtx = new TShirts;

    pqx->Decorate(xc);
    kk->Decorate(pqx);
    dtx->Decorate(kk);
    dtx->show();

    delete dtx;
    dtx = nullptr;
    delete kk;
    kk = nullptr;
    delete pqx;
    pqx = nullptr;

    cout<<"\n第二種裝扮"<<endl;
    LeatherShoes *px = new LeatherShoes;
    Tie *ld = new Tie;
    Suit *xz = new Suit;

    px->Decorate(xc);
    ld->Decorate(px);
    xz->Decorate(ld);
    xz->show();

    delete px;
    px = nullptr;
    delete ld;
    ld = nullptr;
    delete xz;
    xz = nullptr;


    return 0;
}

 

 

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