- Published on
设计模式(9)——装饰 Decorator
- Authors
- Name
- Leon
九、Decorator (装饰模式,别名 Wrapper 包装器,对象结构型模式)
1. 意图:
动态地给一个对象(而不是整个类)添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类(继承)更为灵活。
2. 功能:
给某个对象而不是整个类添加一些功能。
3. 适用:
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
- 处理那些可以撤消的职责
- 当不能采用生成子类的方法进行扩充时
4. 类图:
5. 相关模式:
Adapter 模式:Decorator 模式不同于 Adapter 模式,因为装饰仅改变对象的职责而不改变它的接口;而适配器将给对象一个全新的接口。 Composite 模式:可以将装饰视为一个退化的、仅有的一个组件的组合。然而装饰仅给对象添加一些额外的职责————它的目的不在于对象聚集。 Strategy 模式:用一个装饰你可以改变对象的外表;而 Strategy 模式使得你可以改变对象的内核。这是改变对象的两种途径。
6. Decorator 特点:
Decorator 模式除了采用组合的方式取得了比采用继承方式更好的效果,Decorator 模式还给设计带来一种“即用即付”的方式来添加职责。在OO设计和分析中经常有这样一种情况:为了多态,通过父类指针指向其具体子类,但是这就带来另外一个问题,当具体子类要添加新的职责,就必须向其父类添加一个这个职责的接口,否则通过父类指针是调用不到这个方法的。这样处于高层的父类就承载了太多的特征(方法),并且继承自这个父类的所有子类都不可避免继承了父类的这些接口,但是可能这并不是这个具体子类所需要的。而 Decorator 模式则提供了一种较好的解决方法,当需要添加一个操作的时候就可以通过 Decorator 模式来解决,你可以一步步添加新的职责。
7. C++实现:
- 先编写一个组件类
Component
,包含一个函数Operation()
- 再编写一个装饰器类
Decorator
,派生自Component
,并且has-a
一个Component
,通过构造函数初始化这个 Compoent 对象 - 编写Decorator的子类,编写一个额外的函数
AddedBehavior()
作为添加的额外功能。 Decorator
的子类中的Operation()
调用AddedBehavior()
Decorator.h
// Decorator.h
#pragma once
class Component {
public:
virtual ~Component();
virtual void Operation();
protected:
Component();
private:
};
class ConcreteComponent : public Component {
public:
ConcreteComponent();
~ConcreteComponent();
void Operation();
protected:
private:
};
class Decorator : public Component {
public:
Decorator(Component* com);
virtual ~Decorator();
void Operation();
protected:
Component* _com;
private:
};
class ConcreteDecorator : public Decorator {
public:
ConcreteDecorator(Component* com);
~ConcreteDecorator();
void Operation();
void AddedBehavior();
protected:
private:
};
Decorator.cpp
// Decorator.cpp
#include "Decorator.h"
#include <iostream>
using namespace::std;
Component::Component() {}
Component::~Component() {}
void Component::Operation() {}
ConcreteComponent::ConcreteComponent() {}
ConcreteComponent::~ConcreteComponent() {}
void ConcreteComponent::Operation() {
cout << "ConcreteComponent operation..." << endl;
}
Decorator::Decorator(Component* com) {
this->_com = com;
}
Decorator::~Decorator() {
delete _com;
}
void Decorator::Operation() {}
ConcreteDecorator::ConcreteDecorator(Component* com) : Decorator(com){
}
ConcreteDecorator::~ConcreteDecorator() {}
void ConcreteDecorator::Operation() {
_com->Operation();
this->AddedBehavior();
}
void ConcreteDecorator::AddedBehavior() {
cout << "ConcreteDecorator::AddedBehavior..." << endl;
}
main.cpp
// main.cpp
#include "Decorator.h"
#include <iostream>
using namespace::std;
int main(int argc, char* argv[]) {
Component* com = new ConcreteComponent();
Decorator* dec = new ConcreteDecorator(com);
dec->Operation();
delete dec;
return 0;
}