设计模式 结构型模式 装饰器模式
装饰模式
对原有对象进行装饰(Decorate),不用创造更多的具体的子类,而是通过独立的装饰类来扩展原对象的功能.
原有对象可能是核心类,保持核心类的简单,花哨的功能通过装饰类来添加和扩充,符合开闭原则
.
核心是 Decorator 有一指向 Component 的指针.
#include <string>
#include <iostream>
class Component {
public :
Component() = default;
virtual ~Component(){}
virtual void operation(){}
};
class ConcreteComponent : public Component {
public:
void operation() { std::cout << "ConcreteComponent operation." << std::endl;}
};
class Decorator : public Component {
public:
void set_deco_obj(Component *p) {ptr_component = p;}
protected:
Component* ptr_component;
};
class ConcreteDecorator : public Decorator {
public:
ConcreteDecorator(Component * c = NULL) {
ptr_component = c;
}
void before() { std::cout << "deco before operation." << std::endl;}
void after() { std::cout << "deco after operation." << std::endl;}
void operation() {
before();
ptr_component->operation();
after();
}
};
int main(int argc, char* argv[])
{
std::cout << "Before decoration..." <<std::endl;
ConcreteComponent c;
c.operation();
std::cout << "After decoration..." <<std::endl;
//半透明模式,在具体抽象构件里,调用自己的方法,如after
ConcreteDecorator deco;
deco.set_deco_obj(&c);
deco.operation();
deco.after();
//透明装饰模式
//使用抽象构建来定义对象.只使用抽象构建里定义的方法,如operation
Component * cc = new ConcreteDecorator(&c);
cc->operation();
return 0;
}
半透明和透明装饰模式的区别
所谓透明,即客户端完全针对抽象构件(Component)定义的方法(operation)编程,而且不应该将对象申明为具体的构件 or 装饰器类型,对于客户端来讲,都是 component.operation(),看不到区别.
Component * c = new ConcreteDecorator1();
c->operation();
Component * c = new ConcreteComponent2();
c->operation();
半透明模式,用户需要单独调用新增的方法.
ConcreteDecorator1 * c = new ConcreteDecorator1();
c->operation();
//额外方法,必须指向具体对象才能使用,基类指针不行.
c->extra();
没有抽象构件类的装饰模式
此时 Decorator 可以直接作为 ConcreteComponent 的子类.