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

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

 

UML图:

设计模式 -- 装饰模式 -- c++实现_第1张图片

 

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

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

 

策略模式的实现:

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

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


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

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


代码如下:

/***************************************************** * 模式名:装饰模式 * 时间: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; // }

你可能感兴趣的:(设计模式 -- 装饰模式 -- c++实现)