简介
装饰者模式(decorator pattern)是在不改变原来类的成员变量和成员函数,以及其使用的继承关系的情况下,动态的扩展一个对象的功能。也是通过构建个一个包装类,来装饰指定的类,从而实现新的功能。
- Component: 定义一个抽象接口。
- ConcreteComponent: 定义一个具体的接口,继承于Component抽象接口。
- Decorator: 拥有一个抽象接口(Component)对象的实例,并实现一个和抽象接口一致的接口。
- ConcreteDecoratorA/B: 为持有的实例,增加新的功能。
代码
// decorator_pattern.h
class Component {
public:
virtual void Operation() = 0;
}; // Component
class ConcreteComponent: public Component{
public:
void Operation() override;
}; // ConcreateComponent
class Decorator: public Component{
public:
virtual ~Decorator() = default;
void Operation() override;
void setComponent(std::shared_ptr<Component>& component);
protected:
std::shared_ptr<Component> component_;
}; // Decorator
class ConcreteDecoratorA: public Decorator{
public:
ConcreteDecoratorA(std::string name);
std::string get_name();
private:
std::string name_;
}; // ConcreateDecorator
class ConcreteDecoratorB: public Decorator{
public:
void add_behavior();
}; // ConcreateDecorator
// decorator_pattern.cpp
void ConcreteComponent::Operation() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void Decorator::Operation() {
this->component_->Operation();
}
void Decorator::setComponent(std::shared_ptr<patterns::Component> &component) {
this->component_ = component;
}
ConcreteDecoratorA::ConcreteDecoratorA(std::string name) {
this->name_ = name;
}
std::string ConcreteDecoratorA::get_name() {
return this->name_;
}
void ConcreteDecoratorB::add_behavior() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main(){
std::shared_ptr<Component> component = std::make_shared<ConcreteComponent>();
std::shared_ptr<ConcreteDecoratorA> decorator_a = std::make_shared<ConcreteDecoratorA>("aiden");
decorator_a->setComponent(component);
decorator_a->Operation();
std::cout << decorator_a->get_name() << std::endl;
std::cout << "--------------------------------------------------" << std::endl;
std::shared_ptr<ConcreteDecoratorB> decorator = std::make_shared<ConcreteDecoratorB>();
decorator->setComponent(component);
decorator->Operation();
decorator->add_behavior();
return 0;
}
// output
// virtual void patterns::ConcreteComponent::Operation()
// aiden
// --------------------------------------------------
// virtual void patterns::ConcreteComponent::Operation()
// void patterns::ConcreteDecoratorB::add_behavior()