什么是装饰器模式?
- 装饰器模式是一种结构型设计模式,实现了在不改变现有对象结构的的同时又拓展了新的功能;
- 装饰器本质上是对现有对象的重新包装,同时装饰器又称为封装器;
如何理解装饰器模式
以笔记本电脑为例,当我们购买了一台新笔记本电脑,但我们发现写代码时,屏幕太小,费眼睛,这时候我们有购买了一个24寸的显示器有了显示器又觉得键盘不舒服,这时候购买了一把机械键盘,陆陆续续又购买了鼠标、USB拓展坞。
这时我们再回头看,发现笔记本电脑没有做任何的修理,但我们为笔记本拓展了显示器、键盘、鼠标等外设,这些外设不属于笔记本电脑,同时笔记本没有这些外设(一个或多个)也可以正常工作。这就是装饰器的原理
代码描述
我们这里以手机为例,手机的最初功能就是打电话,后来随着智能手机的出现,又开始有了WIFI、拍照等等的功能
class I_Phone {
public:
virtual ~I_Phone(){};
virtual void ShowFunction() = 0;
};
class XiaoMi : public I_Phone {
public:
void ShowFunction() { cout << "This is XiaoMi Moblie Phone" << endl; }
};
class ViVo : public I_Phone {
public:
void ShowFunction() { cout << "This is ViVo Moblie Phone" << endl; }
};
class Apple : public I_Phone {
public:
void ShowFunction() { cout << "This is Apple Moblie Phone" << endl; }
};
- 这时候智能机出现,手机厂商根据自身实力,去给自家手机增加某些新功能,这里随机举几个例子 5G、拍照、云服务
//5G
class Decorator_5G : public I_Phone {
public:
Decorator_5G(std::shared_ptr<I_Phone> phone) : i_phone_(phone) {}
void ShowFunction()
{
i_phone_->ShowFunction();
cout << "Function:5G" << endl;
}
private:
std::shared_ptr<I_Phone> i_phone_;
};
//拍照
class Decorator_Camera : public I_Phone {
public:
Decorator_Camera(std::shared_ptr<I_Phone> phone) : i_phone_(phone) {}
void ShowFunction()
{
i_phone_->ShowFunction();
cout << "Function:Camera" << endl;
}
private:
std::shared_ptr<I_Phone> i_phone_;
};
//云服务
class Decorator_CloudService : public I_Phone {
public:
Decorator_CloudService(std::shared_ptr<I_Phone> phone) : i_phone_(phone) {}
void ShowFunction()
{
i_phone_->ShowFunction();
cout << "Function:CloudService" << endl;
}
private:
std::shared_ptr<I_Phone> i_phone_;
};
int main()
{
//最初只有三款手机
std::shared_ptr<I_Phone> mi_ = std::make_shared<XiaoMi>();
std::shared_ptr<I_Phone> vivo_ = std::make_shared<ViVo>();
std::shared_ptr<I_Phone> apple_ = std::make_shared<Apple>();
//XiaoMi公司给手机拓展的功能
std::shared_ptr<I_Phone> mi_decorate_ = std::make_shared<Decorator_5G>(mi_);
mi_decorate_ = std::make_shared<Decorator_Camera>(mi_decorate_);
mi_decorate_->ShowFunction();
cout << endl;
//vivo公司给手机拓展的功能
std::shared_ptr<I_Phone> vivo_decorate_ = std::make_shared<Decorator_Camera>(vivo_);
vivo_decorate_->ShowFunction();
cout << endl;
//Apple公司给手机拓展的功能
std::shared_ptr<I_Phone> apple_decorate_ = std::make_shared<Decorator_Camera>(apple_);
apple_decorate_ = std::make_shared<Decorator_CloudService>(apple_decorate_);
apple_decorate_ = std::make_shared<Decorator_5G>(apple_decorate_);
apple_decorate_->ShowFunction();
cout << endl;
return 0;
}
- 最后三种手机拓展的功能结果
装饰器模式的思考
装饰器模式的优缺点
优点:
- 单一职责,每个类只负责自己的功能
- 通过装饰类拓展功能,无需创建新的子类,就实现了对原有功能的拓展
- 可以通过不同的装饰类组合拓展多个新功能
- 可以在运行时添加或删除某些装饰类的功能
缺点:
- 给原有类装饰的新功能,很难不按照装饰的顺序栈执行
- 运行时删除某些装饰类很麻烦
- 多层装饰会让代码变得难以理解
装饰器模式与其他模式的比较
- 装饰器就是对派生类写法的一种优化方向,一定程度上可以避免代码的无限膨胀。
- 和适配器模式相比,装饰器模式可以在不改变对象接口的前提下,拓展新功能,并且可以递归组合,这个是适配器无法实现的
- 装饰器模式和组合模式很像,但装饰器是给被装饰对象拓展新的功能,而组合模式则是对原有的对象不同的叶子节点进行求和。组合对象不修改原有方法调用,重点是在组织不同子对象;装饰者模式在确保只有一个子对象的同时,又对调用执行的方法进行了拓展。