设计模式 -- 装饰模式 -- c++实现

注:本文主要代码基于大话设计模式里的C#代码(第6章)。

 

UML图:

 

我知道装饰模式的实现不好理解,所以我尽量在代码里加了详尽的注释

在我理解,理解装饰模式的重点在于-->理解其使用了链表形式将各装饰对象链成一条装饰链。

 

策略模式的实现:

由组件类派生出装饰类,由装饰类再派生出具体的装饰类,每个装饰类再添加自己的附加功能

组装的时候要一层一层地往上装饰,调用装饰链顶层对象的操作时,就会连带实现了装饰链所链的所有对象的操作


下面代码展示的是使用不同服装(装饰类)对人物(组件类,被装饰类)进行装饰。

最终效果是人物穿的服装的数量、类型、顺序均可以由用户自己自由组装。


代码如下:

/*****************************************************
* 模式名:装饰模式
* 时间:2010.6.3
*                                       -by gouki04
*****************************************************/

#pragma once

#include <string>

//
class cPerson;      // 人物类(Component类)
class cFinery;      // 服装类(Decorator类)
class TShirt;       // T-Shirt类 (具体的装饰类)
class BigTrouser;   // 裤子类(具体的装饰类)
class Sneaker;      // 球鞋类(具体的装饰类)
class LeatherShoes; // 皮鞋类(具体的装饰类)
class Tie;          // 领带类(具体的装饰类)
class Suit;         // 西装类(具体的装饰类)
//

// 人物类
// Component类,所有类的基类
// 同时是添加职责或功能的对象
// 定义虚函数Show,执行最基本的操作
// 注意:Component类完全不知道Decorator类的存在,即其完全不依赖于Decorator类
class cPerson
{
private:
    std::string m_name; // 人名

public:
    cPerson() {} // 必须带默认构造器,因为本类要用做多态,而其他装饰类并不需实际创建cPerson对象
    cPerson(const std::string& name) : m_name(name) {}
    virtual ~cPerson() {}

    // 返回装饰后的字符串
    virtual std::string Show() { return std::string("装扮的" + m_name); }
};

// 服装类
// Decorator类,所有装饰类的父类
// 定义函数Decorate,连接到下一个装饰对象,用于生成一条装饰链
// 成员m_pComponent指向装饰链的下一个装饰对象,装饰链最终终止于Component类,即人物类
class cFinery : public cPerson
{
protected:
    // 用cPerson不用cFinery,是因为装饰链是终止于cPerson的,所以必须要用cPerson
    // 这也解释了为什么cFinery要从cPerson继承的原因,就是要实现这种多态
    // 而实际上cFinery和cPerson之间并无意义上的继承关系
    cPerson* m_pComponent;

public:
    cFinery() : m_pComponent(NULL) {}
    virtual ~cFinery() {}

    // 装饰函数,生成一条装饰链
    // 返回this是为了可以如下使用:a.Decorate(b.Decorate(c));
    cPerson* Decorate(cPerson* component) { m_pComponent = component; return this; }

    // 返回装饰链所装饰的整个字符串
    std::string Show()
    {
        if (m_pComponent)
            return m_pComponent->Show();

        return std::string("");
    }
};

// T-Shirt类 (具体的装饰类)
class TShirt : public cFinery
{
public:
    // 这里要连带调用父类的Show,相当于调用装饰链后面对象的Show
    // 即相当于语句m_pComponent->Show();
    std::string Show() { return std::string("大T恤 ") + cFinery::Show(); }
};

// 裤子类 (具体的装饰类)
class BigTrouser : public cFinery
{
public:
    std::string Show() { return std::string("垮裤 ") + cFinery::Show(); }
};

// 球鞋类 (具体的装饰类)
class Sneaker : public cFinery
{
public:
    std::string Show() { return std::string("破球鞋 ") + cFinery::Show(); }
};

// 皮鞋类 (具体的装饰类)
class LeatherShoes : public cFinery
{
public:
    std::string Show() { return std::string("皮鞋 ") + cFinery::Show(); }
};

// 领带类 (具体的装饰类)
class Tie : public cFinery
{
public:
    std::string Show() { return std::string("领带 ") + cFinery::Show(); }
};

// 西装类 (具体的装饰类)
class Suit : public cFinery
{
public:
    std::string Show() { return std::string("西装 ") + cFinery::Show(); }
};

// 测试的main函数
//int main()
//{
//    using namespace std;
//
//    cPerson xc(string("小菜"));
//
//    Sneaker pqx;
//    BigTrouser kk;
//    TShirt dtx;
//
//    dtx.Decorate(kk.Decorate(pqx.Decorate(&xc)));
//    cout << endl << "第一种装扮:" << dtx.Show() << endl;
//
//    LeatherShoes px;
//    Tie ld;
//    Suit xz;
//
//    xz.Decorate(ld.Decorate(px.Decorate(&xc)));
//    cout << endl << "第二种装扮:" << xz.Show() << endl;
//
//    Sneaker pqx2;
//    LeatherShoes px2;
//    BigTrouser kk2;
//    Tie ld2;
//    ld2.Decorate(kk2.Decorate(px2.Decorate(pqx2.Decorate(&xc))));
//    cout << endl << "第三种装扮:" << ld2.Show() << endl;
//
//    return 0;
//}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值