装饰器模式:可以动态地给对象添加一下额外的职责或者功能。
张三要出去见女朋友,但是身上的衣服比较破旧,这怎么能去见自己心爱的女朋友呢?俗话说:人靠衣装。要给女朋友展示最好的形象包括自己的穿着。
首先定义一个展示基类;
#pragma once
class IShow {
public:
IShow();
~IShow();
virtual void show();
};
#include "IShow.h"
IShow::IShow() {
}
IShow::~IShow() {
}
void IShow::show() {
}
然后定义人的类,继承自IShow
class Person : public IShow {
public:
Person(std::string name);
~Person();
void show()override;
private:
std::string _name;
};
#include "Person.h"
#include <stdio.h>
Person::Person(std::string name) {
_name = name;
}
Person::~Person() {
}
void Person::show() {
printf("我叫:%s\n", _name.c_str());
}
如果直接运行的话,
int main() {
IShow* per = new Person("张三");
per->show();
return 0;
}
运行结果:
回见女朋友怎么能只报姓名呢?难道没有准备一身好看的衣服。
如何给张三穿上好看的衣服呢?首先大家想到的就是通过继承关系可以给张三添加新的功能,但是有没有更好的解决方案呢?如下:
定义衣服基类
class IClothes :public IShow {
public:
IClothes(IShow* show);
~IClothes();
virtual void show()override;
protected:
IShow* _show;
};
class IClothes :public IShow {
public:
IClothes(IShow* show);
~IClothes();
virtual void show()override;
protected:
IShow* _show;
};
定义上衣类
class TShirt :public IClothes {
public:
TShirt(IShow* show);
void show()override;
};
TShirt::TShirt(IShow* show)
:IClothes(show) {
}
void TShirt::show() {
_show->show();
printf("穿上了漂亮的T恤,使我更精神!\n");
}
定义裤子类
class Trousers :public IClothes {
public:
Trousers(IShow* show);
void show()override;
};
Trousers::Trousers(IShow* show)
:IClothes(show) {
}
void Trousers::show() {
_show->show();
printf("穿上了修长的裤子,使我腿更长!\n");
}
给张三要穿的衣服已经定义完成了。
修改一下场景:
int main() {
IShow* per = new Person("张三");
per = new TShirt(per);
per = new Trousers(per);
per->show();
return 0;
}
上面我们并没有修改Person这个类但是,我们也是给张三扩展了一些功能,非常的方便。只要是定义的接口类不变那么可以很方便的实现对原有对象的一些功能扩展。
装饰器模式的优点:
1.装饰的对象和被装饰的对象可以独立,互相不耦合;
2.替代了继承;
3.可以很方便的扩展一个类的功能。