概念
装饰模式:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
允许向一个现有的对象添加新的功能,同时又不改变其结构
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂。
应用场景
- 在不想增加很多子类的情况下扩展类。
- 动态增加功能,动态撤销。
一般步骤
定义一个基类,并带有一个功能的函数。如:Person类里有个Show()功能;
class Person { public: Person(){}; Person(string name) { this->name = name; } ~Person() {} virtual void Show() // 展示装扮 { cout << "装扮的" << name << endl; } private: string name; };
定义一个装饰类,继承前面的基类,并且有一个装饰的函数可以装饰基类的指针,且重写基类的那个功能函数(Show),并在函数里调用基类的功能函数(Show);
这一步非常关键,是这个模式里最重要的一步
class Finery : public Person // 装饰类 { public: void Decorate(Person* person) // 装扮指定的人,在这个模式里最重要的一个函数 { boy = person; } void Show() { if (boy) { boy->Show(); } } private: Person* boy; };
定义具体的功能类,继承前面的装饰类,且重写功能函数(Show);
class TShirt : public Finery { public: void Show() { printf("Tshirt "); Finery::Show(); } }; class BigTrouser : public Finery { public: void Show() { printf("BigTrouser "); Finery::Show(); } };
完整实例
#include <cstdio> #include <iostream> #include <string> using namespace std; class Person { public: Person(){}; Person(string name) { this->name = name; } ~Person() {} virtual void Show() // 展示装扮 { cout << "装扮的" << name << endl; } private: string name; }; class Finery : public Person // 装饰类 { public: void Decorate(Person* person) // 装扮指定的人,在这个模式里最重要的一个函数 { boy = person; } void Show() { if (boy) { boy->Show(); } } private: Person* boy; }; class TShirt : public Finery { public: void Show() { printf("Tshirt "); Finery::Show(); } }; class BigTrouser : public Finery { public: void Show() { printf("BigTrouser "); Finery::Show(); } }; int main() { Person *xc = new Person("小菜"); cout << "第一钟装扮" << endl; TShirt *tshirt = new TShirt(); BigTrouser *BigTrouser = new BigTrouser(); tshirt->Decorate(xc); // 用T恤装扮小菜 BigTrouser->Decorate(tshirt); // 用裤子 装扮 "已装扮了T恤" 的小菜 BigTrouser->Show(); return 0; }
参考资料
程杰老师的《大话设计模式》