Published on

设计模式(9)——装饰 Decorator

Authors
  • avatar
    Name
    Leon
    Twitter

九、Decorator (装饰模式,别名 Wrapper 包装器,对象结构型模式)

1. 意图:

  动态地给一个对象(而不是整个类)添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类(继承)更为灵活。

2. 功能:

  给某个对象而不是整个类添加一些功能。

3. 适用:

  1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  2. 处理那些可以撤消的职责
  3. 当不能采用生成子类的方法进行扩充时

4. 类图:

5. 相关模式:

  Adapter 模式:Decorator 模式不同于 Adapter 模式,因为装饰仅改变对象的职责而不改变它的接口;而适配器将给对象一个全新的接口。   Composite 模式:可以将装饰视为一个退化的、仅有的一个组件的组合。然而装饰仅给对象添加一些额外的职责————它的目的不在于对象聚集。   Strategy 模式:用一个装饰你可以改变对象的外表;而 Strategy 模式使得你可以改变对象的内核。这是改变对象的两种途径。

6. Decorator 特点:

  Decorator 模式除了采用组合的方式取得了比采用继承方式更好的效果,Decorator 模式还给设计带来一种“即用即付”的方式来添加职责。在OO设计和分析中经常有这样一种情况:为了多态,通过父类指针指向其具体子类,但是这就带来另外一个问题,当具体子类要添加新的职责,就必须向其父类添加一个这个职责的接口,否则通过父类指针是调用不到这个方法的。这样处于高层的父类就承载了太多的特征(方法),并且继承自这个父类的所有子类都不可避免继承了父类的这些接口,但是可能这并不是这个具体子类所需要的。而 Decorator 模式则提供了一种较好的解决方法,当需要添加一个操作的时候就可以通过 Decorator 模式来解决,你可以一步步添加新的职责。

7. C++实现:

  1. 先编写一个组件类 Component,包含一个函数 Operation()
  2. 再编写一个装饰器类 Decorator,派生自 Component,并且has-a 一个 Component,通过构造函数初始化这个 Compoent 对象
  3. 编写Decorator的子类,编写一个额外的函数 AddedBehavior() 作为添加的额外功能。
  4. 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;
}