Decorator模式:
Decorator模式动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
在OO设计和开发过程,可能会经常遇到以下的情况:我们需要为一个已经定义好的类添加新的职责(操作),通常的情况我们会给定义一个新类继承自定义好的类,这样会带来一个问题,新加的代码通常加入了新的字段,新的方法或新的逻辑,从而增加了类的复杂度,而些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。通过继承的方式解决这样的情况还带来了系统的复杂性,因为继承的深度会变得很深。
而Decorator提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合,它把每个要装饰的功能放在单独的类中,并让这个类包装它所需要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择、按顺序的使用装饰功能包装对象了。
Decorator模式典型的结构图为:
在结构图中,ConcreteComponent和Decorator需要有同样的接口,因此ConcreteComponent和Decorator有着一个共同的父类。这里有人会问,让Decorator直接维护一个指向ConcreteComponent引用(指针)不就可以达到同样的效果,答案是肯定并且是否定的。肯定的是你可以通过这种方式实现,否定的是你不要用这种方式实现,因为通过这种方式你就只能为这个特定的ConcreteComponent提供修饰操作了,当有了一个新的ConcreteComponent你又要去新建一个Decorator来实现。但是通过结构图中的ConcreteComponent和Decorator有一个公共基类,就可以利用OO中多态的思想来实现只要是Component型别的对象都可以提供修饰操作的类,这种情况下你就算新建了100个Component型别的类ConcreteComponent,也都可以由Decorator一个类搞定。这也正是Decorator模式的关键和威力所在了。
当然如果你只用给Component型别类添加一种修饰,则Decorator这个基类就不是很必要了。
这里引用《大话设计模式》中给人做装饰为例子实现Decorator模式,下面是Decorator模式的实现代码:
//Decorator.h
#ifndef _DECORATOR_H_
#define _DECORATOR_H_
// 人
class Person
{
public:
virtual ~Person();
virtual void Show();
protected:
Person();
private:
};
// 美眉
class Girl : public Person
{
public:
Girl();
~Girl();
void Show();
protected:
private:
};
// 装饰的基类
class Decorator : public Person
{
public:
Decorator(Person* com);
virtual ~Decorator();
void Show();
protected:
Person* _com;
private:
};
// 用T恤装饰的类
class Tshirt : public Decorator
{
public:
Tshirt(Person* com);
~Tshirt();
void Show();
void AddedBehavior();
protected:
private:
};
// 用裤子装饰的类
class Trousers : public Decorator
{
public:
Trousers(Person* com);
~Trousers();
void Show();
void AddedBehavior();
protected:
private:
};
#endif //~_DECORATOR_H_
//Decorator.cpp
#include "Decorator.h"
#include <iostream>
Person::Person()
{
}
Person::~Person()
{
}
void Person::Show()
{
}
Girl::Girl()
{
}
Girl::~Girl()
{
}
void Girl::Show()
{
std::cout<<"Girl::Show...本来面目是个灰姑娘"<<std::endl;
}
Decorator::Decorator(Person* com)
{
this->_com = com;
}
Decorator::~Decorator()
{
delete _com;
}
void Decorator::Show()
{
}
Tshirt::Tshirt(Person* com):Decorator(com)
{
}
Tshirt::~Tshirt()
{
}
void Tshirt::AddedBehavior()
{
std::cout<<"Tshirt::AddedBehavior....穿T恤装饰"<<std::endl;
}
void Tshirt::Show()
{
_com->Show();
this->AddedBehavior();
}
Trousers::Trousers(Person* com)
: Decorator(com)
{
}
Trousers::~Trousers()
{
}
void Trousers::AddedBehavior()
{
std::cout<<"Trousers::AddedBehavior....穿裤子装饰"<<std::endl;
}
void Trousers::Show()
{
_com->Show();
this->AddedBehavior();
}
//main.cpp
#include "Decorator.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
// 一个美眉
Person* com = new Girl();
// T恤装饰她
Decorator* dec1 = new Tshirt(com);
dec1->Show();
// 裤子装饰她
Decorator* dec2 = new Trousers(com);
dec2->Show();
return 0;
}