1、介绍
装饰器(Decorator)模式是一种结构型设计模式,它允许你动态地给一个对象添加额外的职责。
装饰器模式主要用于扩展对象的功能,而又不改变其原有结构。在C++中,装饰器模式主要应用于那些需要为对象动态添加功能或改变行为的场景,而这些附加行为是可以独立于基础组件的。
装饰器模式通常包含以下几个组件:
(1)组件(Component):定义一个对象接口,可以给这些对象动态地添加职责。
(2)具体组件(ConcreteComponent):实现组件接口,是被装饰器装饰的对象。
(3)装饰器(Decorator):实现与组件相同的接口,它包含一个指向组件对象的指针(或者引用),并可以在调用组件的方法之前或之后添加一些额外的功能。
(4)具体装饰器(ConcreteDecorator):实现装饰器接口,并添加一些额外的职责。
举例分析:
假设定义了animal接口类,并具体定义了三个具体的动物。
另外需要给每个动物增加三个功能——吃饭、睡觉、跑步;我们该如果设计类关系?
(1)为每个动物设计三个功能子类;
(2)使用装饰器,在animal下增加一个功能类;
2、示例
#include <iostream>
// 组件接口类
class animal
{
private:
public:
virtual void show() = 0;
};
// 具体组件,子类
class cat :public animal
{
private:
public:
void show() override
{
std::cout << "this is cat!" << std::endl;
}
};
// 具体组件,子类
class dog :public animal
{
private:
public:
void show() override
{
std::cout << "this is dog!" << std::endl;
}
};
// 具体组件,子类
class sheep :public animal
{
private:
public:
void show() override
{
std::cout << "this is sheep!" << std::endl;
}
};
// 装饰器
class animal_function :public animal {
public:
animal_function(animal* animal_ptr) :_animal_ptr(animal_ptr) {};
void show() override {
if (_animal_ptr != nullptr) {
_animal_ptr->show();
}
}
protected:
animal* _animal_ptr;
};
// 具体装饰器 eat
class eat_function : public animal_function {
public:
eat_function(animal* cc) : animal_function(cc) {}
void show() override {
std::cout << "eat_function before" << std::endl;
animal_function::show();
std::cout << "eat_function after" << std::endl;
}
};
// 具体装饰器 sleep
class sleep_function : public animal_function {
public:
sleep_function(animal* cc) : animal_function(cc) {}
void show() override {
std::cout << "sleep_function before" << std::endl;
animal_function::show();
std::cout << "sleep_function after" << std::endl;
}
};
// 具体装饰器 run
class run_function : public animal_function {
public:
run_function(animal* cc) : animal_function(cc) {}
void show() override {
std::cout << "run_function before" << std::endl;
animal_function::show();
std::cout << "run_function after" << std::endl;
}
};
int main()
{
animal* cat_0 = new eat_function(new cat());
cat_0->show();
animal* dog_0 = new sleep_function(new dog());
dog_0->show();
animal* sheep_0 = new run_function(new sheep());
sheep_0->show();
return 0;
}
结果:
eat_function before
this is cat!
eat_function after
sleep_function before
this is dog!
sleep_function after
run_function before
this is sheep!
run_function after