设计模式:装饰模式(C++)【小明习武闯天下】

序言

这集带来大家一起学下装饰模式装饰模式 看名字就能  猜到是干啥 就是用来 搞装修进行装饰的 嘛!没毛病,其实装饰模式 确实是用来装饰对象的 而且是为了解耦的。我们知道 类是生成对象的模板,我们如果要做得单一职责的话,那么每增加一个不一样的属性,都要添加一个新的子类,这样就会有很多种类。或许这些属性可能还不是通用的。那么怎样来解决呢?或许我们可以将那些要添加的属性或者动作 封装成 装饰器,你要啥 我就装饰啥呗。下面请看下面的装饰器的标准类图。

装饰模式标准类图


装饰模式案例

小明习武闯天下

小明同学是我们的主人公,它是我们需要修饰的对象。起初他只是一名学生普通人一个。后面 习武->六脉神剑->打狗棒->降龙18掌,各种属性值持续上升, 然后走上人生巅峰。当然我们后面添加的这些 功能 得用 装饰模式呗。用继承不合理吧。

小明习武类型图


小明习武代码实现

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;

//人物角色接口 待装饰抽象基类
class Hero
{
public:
	virtual void showStatus() = 0;
public:
	int m_ATK;//攻击力
	int m_DEF;//防御力
	int m_Power;//内功
	int m_Look;//颜值
	string m_Name;
};
//学生 具体待装饰的类
class Student :public Hero
{
public:
	Student(string name)
	{
		m_ATK = 0;
		m_DEF = 0;
		m_Power = 0;
		m_Look = 10;//学生初始有颜值
		m_Name = name;
	}
	virtual void showStatus()
	{
		cout << m_Name <<" 攻击力:" << m_ATK << " 防御力:" << m_DEF << " 内功:" << m_Power << " 颜值:" << m_Look << endl;
	}
};
//抽象技能类(装饰类的基类) ,学习武功 还是一个人,装饰类 很重要一点,有指向待装饰对象的指针 ,这样就可以 在要装饰对象 上装饰东西 或者 做一些动作
class AbstractSkillDecorator:public Hero
{
public:
	AbstractSkillDecorator(Hero* hero)
	{
		this->hero = hero;
	}
protected:
	Hero* hero;
};

//学习 六脉神剑,具体的装饰类 ,学习之后 攻击力和颜值 增加
class SexSwordDecorator :public AbstractSkillDecorator
{
public:
	SexSwordDecorator(Hero* hero):AbstractSkillDecorator(hero)
	{
		
	}
	virtual void showStatus()
	{
		addSkill();//增加技能
		cout << m_Name << " 攻击力:" << m_ATK << " 防御力:" << m_DEF << " 内功:" << m_Power << " 颜值:" << m_Look << endl;
	}
private:
	//装饰类 增加动作,修饰待装饰对象hero
	void addSkill()
	{
		this->m_ATK = hero->m_ATK + 100;
		this->m_DEF = hero->m_DEF;
		this->m_Power = hero->m_Power;
		this->m_Look = hero->m_Look + 100;
		this->m_Name = hero->m_Name;
		delete hero;
	}
};
//学习丐帮的打狗棒,学习后 防御力增加100,颜值下降200 o(╥﹏╥)o
class HitDogDecorator :public AbstractSkillDecorator
{
public:
	HitDogDecorator(Hero* hero):AbstractSkillDecorator(hero)
	{
		
	}
	virtual void showStatus() 
	{

		addSkill();
		cout << "一不小心成了:" << newId << endl;
		cout << m_Name << " 攻击力:" << m_ATK << " 防御力:" << m_DEF << " 内功:" << m_Power << " 颜值:" << m_Look << endl;
	}
private:
	//装饰类 增加动作,修饰待装饰对象hero
	void addSkill()
	{
		this->m_ATK = hero->m_ATK;
		this->m_DEF = hero->m_DEF + 100;
		this->m_Power = hero->m_Power;
		this->m_Look = hero->m_Look - 200;
		this->m_Name = hero->m_Name;
		this->newId = "丐帮帮主";
		delete hero;
	}
private:
	string newId;//装饰类增加状态,修饰hero对象
};
//学习降龙18掌,学习后 内力 暴增 + 200
class Dragon18Decorator :public AbstractSkillDecorator
{
public:
	Dragon18Decorator(Hero* hero) :AbstractSkillDecorator(hero)
	{
		
	}
	virtual void showStatus()
	{
		addSkill();
		cout << m_Name << " 攻击力:" << m_ATK << " 防御力:" << m_DEF << " 内功:" << m_Power << " 颜值:" << m_Look << endl;
	}
private:
	//装饰类 增加动作,修饰待装饰对象hero
	void addSkill()
	{
		this->m_ATK = hero->m_ATK;
		this->m_DEF = hero->m_DEF;
		this->m_Power = hero->m_Power + 200;
		this->m_Look = hero->m_Look;
		this->m_Name = hero->m_Name;
		delete hero;
	}
};

int main(int argc, char *argv[])
{
	//小明刚开始是学生,但是它有个英雄梦,从此踏入武林
	Hero* xiaoMing = new Student("小明");
	cout << "小明还是学生时----------" << endl;
	xiaoMing->showStatus();
	//被装饰类装饰后,原对象是否要进行释放 视情况而定 。
	//这里我们不再需要原对象,所有在装饰类中装饰完原对象,就将原对象释放。

	//小明学武 -> 六脉神剑->打狗棒-> 降龙18掌
	xiaoMing = new SexSwordDecorator(xiaoMing);
	cout << "学习六脉神剑后----------" << endl;
	xiaoMing->showStatus();

	xiaoMing = new HitDogDecorator(xiaoMing);
	cout << "学习打狗棒后------------" << endl;
	xiaoMing->showStatus();

	xiaoMing = new Dragon18Decorator(xiaoMing);
	cout << "学习降龙18掌后------------" << endl;
	xiaoMing->showStatus();


	return EXIT_SUCCESS;
}

运行结果




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值