设计模式之《装饰模式》

问:

现有类  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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liu-Eleven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值