C++设计模式之装饰模式

主要解决

在某些情况下我们可能会“过度地使用继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性,并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。
  如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?

适用场景

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。有时我们希望给某个对象而不是整个类添加一些功能。穿衣服是使用装饰的一个例子。 觉得冷时, 你可以穿一件毛衣。 如果穿毛衣还觉得冷, 你可以再套上一件夹克。 如果遇到下雨, 你还可以再穿一件雨衣。 所有这些衣物都 “扩展” 了你的基本行为, 但它们并不是你的一部分, 如果你不再需要某件衣物, 可以方便地随时脱掉。

关键代码

  • 案例一
    有一个手机,允许你为手机添加特性,比如增加挂件、屏幕贴膜等。一种灵活的设计方式是,将手机嵌入到另一对象中,由这个对象完成特性的添加,我们称这个嵌入的对象为装饰。

在这里插入图片描述

#include <iostream>
#include <string>
using namespace std;
//公共抽象类  
class Phone
{
public:
	Phone() {}
	virtual ~Phone() {}
	virtual void ShowDecorate() {}
};

//具体的手机类  
class iPhone : public Phone
{
private:
	string m_name; //手机名称  
public:
	iPhone(string name) : m_name(name) {}
	~iPhone() {}
	void ShowDecorate() { cout << m_name << "的装饰" << endl; }
};
//具体的手机类  
class NokiaPhone : public Phone
{
private:
	string m_name;
public:
	NokiaPhone(string name) : m_name(name) {}
	~NokiaPhone() {}
	void ShowDecorate() { 
		cout << m_name << "的装饰" << endl; }
};

//装饰类  
class DecoratorPhone : public Phone
{
private:
	Phone* m_phone;  //要装饰的手机  
public:
	DecoratorPhone(Phone* phone) : m_phone(phone) {}
	virtual void ShowDecorate() { m_phone->ShowDecorate(); }
};
//具体的装饰类  
class DecoratorPhoneA : public DecoratorPhone
{
public:
	DecoratorPhoneA(Phone* phone) : DecoratorPhone(phone) {}
	void ShowDecorate() { 
		DecoratorPhone::ShowDecorate(); //通过双引号访问基类中的方法
		AddDecorate(); 
	}
private:
	void AddDecorate() { cout << "增加挂件" << endl; } //增加的装饰  
};
//具体的装饰类  
class DecoratorPhoneB : public DecoratorPhone
{
public:
	DecoratorPhoneB(Phone* phone) : DecoratorPhone(phone) {}
	void ShowDecorate() { 
		DecoratorPhone::ShowDecorate();  //通过双引号访问基类中的方法
		AddDecorate(); 
	}
private:
	void AddDecorate() { cout << "屏幕贴膜" << endl; } //增加的装饰  
};
int main()
{
	Phone* iphone = new NokiaPhone("6300");
	Phone* dpa = new DecoratorPhoneA(iphone); //装饰,增加挂件  
	Phone* dpb = new DecoratorPhoneB(dpa);    //装饰,屏幕贴膜  
	dpb->ShowDecorate();
	delete dpa;
	delete dpb;
	delete iphone;
	return 0;
}
//执行结果:
//6300的装饰
//增加挂件
//屏幕贴膜

案例二:
消息提醒类的动态组合功能
https://blog.csdn.net/qq_30457077/article/details/128981604

参考

https://blog.csdn.net/u012011079/article/details/125829389
https://zhuanlan.zhihu.com/p/431714886

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值