这里要说的是这个叫做“装饰器”的设计模式的最最简单的C++实现。
装饰器模式实际上是为了解决客户程序需要新功能,但是既不能修改已有类库,又不好多改客户程序的目的提出的,它通过继承并包裹既有的类,实现对已有类的功能的扩充。可以看到,这个模式很好的体现了设计模式中对修改封闭,对扩充开放的基本原则,对于原始类B和原始客户代码都没有修改,但却通过增加新的代码直接提供了新的功能。代码如下:
#include <iostream>
using namespace std;
//基类:为了能够被装饰,这个必须是个能够被继承的类
class B
{
public:
B(char n): c(n) {}
B(): c('X') {}
~B() {}
//可以被扩充功能的方法,需要多态特性,以便子类进行扩充
//目前的功能就是显示一个字符,这个字符是用这个基类包裹的
virtual void display() { cout << c ; }
private:
char c;
};
//抽象装饰器:开始进行功能扩充的框架,继承基类并且包裹基类
class A : public B
{
public:
A(B &t): b(t) {}
~A() {}
//覆盖基类的功能,但是,呵呵,实际上只是把控制传递到被包裹的基类
//可别忘了,这时的b可是基类引用,这是有多态机制的调用
void display() { b.display(); }
private:
B &b;
};
//真正的装饰功能,扩充实际功能,多显示一个字符,就是那个n,它会重新包裹这个字符
class C : public A
{
public:
C(B &t, char n): A(t) , c(n) {};
~C(){}
void display()
{
cout << c;
//非常关键的一步,将控制转发给上一层继承的同名函数,
//因为是直接在内部发起调用,这个可没有多态
A::display();
}
private:
char c;
};
int main()
{
B *p_obj = new B('A'); //原始代码,不修改
p_obj = new C(*p_obj, 'B'); //增加的代码
p_obj = new C(*p_obj, 'C'); //增加的代码
//原本的程序功能,就是显示一个A。
//现在增加了两层包裹,就可以多显示两个字母咯
p_obj->display(); //原始代码,不修改
cout << endl;
}