装饰模式
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
本文使用书中装饰衣服的例子,代码使用C++语言描述,代码存在的不足或问题有望各位指出。
(1)首先我们看一下装饰模式的代码框架
////装饰模式
#include <iostream>
using namespace std;
class Component{
public:
Component(){}
virtual ~Component(){}
virtual void Operation()=0;
};
class ConcreteComponnet : public Component
{
public:
void Operation() override
{
cout <<"具体对象的操作"<<endl;
}
};
class Decorator: public Component
{
public:
void setComponent(Component *component)
{
this->component = component;
}
void Operation() override //重写Operation(),实际执行的是Component的Operation()
{
if (component != nullptr)
component->Operation();
}
protected:
Component *component;
};
class ConcreteDecoratorA : public Decorator
{
public:
void Operation() override
{
component->Operation(); //首先运行原Component的Operation(),再执行本类的功能,
addedState = "New State"; //如addedState,相当于对原Component进行了装饰
cout<< "具体装饰对象A的操作"<<endl;
}
private:
string addedState; //本类的独有的功能,以区别于ConcreteDecoratorB
};
class ConcreteDecoratorB: public Decorator
{
public:
void Operation() override
{
component->Operation(); //首先运行原Component的Operation(),再执行本类的功能,
addedBehavior(); //如AddedBehavior(),相当于对原Component进行了装饰
cout<< "具体装饰对象B的操作"<<endl;
}
private:
void addedBehavior() //本类独有的方法
{
}
};
int main ()
{
ConcreteComponnet *c =new ConcreteComponnet();
ConcreteDecoratorA *d1 = new ConcreteDecoratorA();
ConcreteDecoratorB *d2 = new ConcreteDecoratorB();
d1->setComponent(c); //装饰的方法是:首先用ComcreteComponent实例化对象c,
d2->setComponent(d1); //然后用ConcreteDecoratorA的实例化对象d1来包装c,再用
d2->Operation(); //ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation()
delete c;
delete d1;
delete d2;
return 0;
}
Component 是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponnet是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
(2)装饰衣服的实例
////装饰模式
#include <iostream>
using namespace std;
class Component{
public:
Component(){}
virtual ~Component(){}
virtual void Operation()=0;
};
class ConcreteComponnet : public Component
{
public:
void Operation() override
{
cout <<"具体对象的操作"<<endl;
}
};
class Decorator: public Component
{
public:
void setComponent(Component *component)
{
this->component = component;
}
void Operation() override //重写Operation(),实际执行的是Component的Operation()
{
if (component != nullptr)
component->Operation();
}
protected:
Component *component;
};
class ConcreteDecoratorA : public Decorator
{
public:
void Operation() override
{
component->Operation(); //首先运行原Component的Operation(),再执行本类的功能,
addedState = "New State"; //如addedState,相当于对原Component进行了装饰
cout<< "具体装饰对象A的操作"<<endl;
}
private:
string addedState; //本类的独有的功能,以区别于ConcreteDecoratorB
};
class ConcreteDecoratorB: public Decorator
{
public:
void Operation() override
{
component->Operation(); //首先运行原Component的Operation(),再执行本类的功能,
addedBehavior(); //如AddedBehavior(),相当于对原Component进行了装饰
cout<< "具体装饰对象B的操作"<<endl;
}
private:
void addedBehavior() //本类独有的方法
{
}
};
int main ()
{
ConcreteComponnet *c =new ConcreteComponnet();
ConcreteDecoratorA *d1 = new ConcreteDecoratorA();
ConcreteDecoratorB *d2 = new ConcreteDecoratorB();
d1->setComponent(c); //装饰的方法是:首先用ComcreteComponent实例化对象c,
d2->setComponent(d1); //然后用ConcreteDecoratorA的实例化对象d1来包装c,再用
d2->Operation(); //ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation()
delete c;
delete d1;
delete d2;
return 0;
}
如果只有一个ConcreteComponent类没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类
装饰模式分析
装饰模式是为已有功能动态地添加更多功能的一种方式。当系统需要新功能的时候,是向旧的类中添加新的代码,这些新的代码通常装饰了原有类的核心职责或主要行为。装饰模式提供了一个非常好的解决方案,它把每个装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。装饰模式的优点可以总结为,把类中的装饰功能从类中搬移去除,这样可以简化原有的类。