设计模式之装饰模式

来源:互联网 发布:mac怎么关闭窗口 编辑:程序博客网 时间:2024/06/10 08:10
定义:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活

举个例子来讲,假如我们要装扮我们自己,我们可以通过穿不同的衣服来装饰我们自己,例如我们可以:西装,领带,皮鞋。我们仍然可以格子衫,牛仔裤,布鞋,这样来装扮自己,或者T恤,短裤,拖鞋这样,第一种一看就是个成功人士,第二个就是一个程序员的装扮,第三个就是屌丝装扮吧!

我们人刚生下来什么衣服都没有(一个对象),慢慢的给我们自己添加一些衣服来装扮自己(额外的职责),但是我们装扮自己的时候也要按照一定的顺序来,我们总不能先穿皮鞋,再穿西装,最后打个领带吧!这样显然是不符合常理的

所以我们要按照一定的顺序来,我们需要把所需的功能按正确的顺序串联起来进行控制

下来我们可以写一写这个例子的代码

#include<iostream>#include<string>using namespace std;//我们具体要装饰的对象class Person{private:string name;public:void setName(string name){this->name = name;}string getName(){return name;}virtual void show(){cout << name << "的装扮:";}};//服饰类,因为服饰是给人装扮,所以它要知道我们是给谁装扮class Finery:public Person{private:Person* person;public:void Decorator(Person* person){this->person = person;}void show(){if (person != NULL){person->show();}}};//西装class Suit:public Finery{public:void show(){Finery::show();cout << "西装  " ;}};class Necktie :public Finery{void show(){Finery::show();cout << "领带  " ;}};class Leather:public Finery{public:void show(){//每次展示之前都会先展示之前的Finery::show();cout << "皮鞋  " ;}};int main(void){//Person* person = new Person();person->setName("成功人士");Finery* xifu = new Suit();Finery* pixie = new Leather();Finery* lingdai = new Necktie();//先带领带,在这个人什么都没有的基础上lingdai->Decorator(person);//在穿西服,在他打了领带的基础上xifu->Decorator(lingdai);//最后皮鞋,在他穿了西服的基础上pixie->Decorator(xifu);//然后展示pixie->show();cout << endl;return 0;}
看到这里应该对于这个装饰模式有了一定的了解了,下来我们看一看装饰模式的代码吧

//定义一个对象接口,可以给这些类动态的添加一些职责class Component{public:virtual void Operation() = 0;};//具体的对象class ConcreteComponent :public Component{public:void Operation(){cout << "具体对象的操作" << endl;}};class Decorator :public Component{private:Component* component;public:void setComponent(Component* component){this->component = component;}void Operation(){if (component != NULL){component->Operation();}}};class DecoratorA :public Decorator{public:void Operation(){Decorator::Operation();cout << "具体装饰对象A的操作" << endl;}};class DecoratorB :public Decorator{public:void Operation(){Decorator::Operation();cout << "具体装饰对象B的操作" << endl;}};int main(void){Component* compont = new ConcreteComponent();Decorator* deca = new DecoratorA();Decorator* decb = new DecoratorB();deca->setComponent(compont);decb->setComponent(deca);decb->Operation();return 0;}
适用情况:
1、当需要以不影响其它对象为前提,实现动态,透明的给单个对象添加职责
2、当需要将对象的某些职责撤销时
3、当不能用生成子类的方法对当前对象进行扩充时

优点:
1、把类中的装饰功能从类中搬出去,这样可以简化原有的类
2、有效地把类的核心职责和装饰功能区分开,而且可以去除相关类中重复的装饰逻辑

不符合的情况
1、如果一个类反复多次的被装饰模式增加功能,那就不合理了
2、如果通过装饰模式增加的功能比类本身功能还多,那么不合理