设计模式 C++装饰模式

Posted WhiteShirtI

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式 C++装饰模式相关的知识,希望对你有一定的参考价值。

买了新房(毛坯房)需要装修,对新房进行装修并没有改变房子用于居住的本质,但它让房子变得更漂亮,更加满足居家的需求。在软件设计中,我们也可以用类似的技术对原有对象(新房)的功能进行扩展(装修),以获得更加符合用户需求的对象。这种技术在设计模式中称为装饰模式

装饰模式可以在不改变一个对象本身的基础上给对象增加额外的新行为,在现实生活中,这种情况比比皆是,如一张照片,可以不改变照片本身,给它增加一个相框,使得它具有防潮的功能,而且用户可以根据需要给它增加不同类型的相框,甚至可以在一个小相框的外面再套一个大相框

使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类拥有自身方法的同时还拥有父类的方法,但是这种方法是静态的,用户不能控制增加行为的方式和时时机。例如我们要给奶茶加料,料有珍珠、椰果、葡萄干,如果使用继承我们就要把这三个类都要继承下来,此时类个数增多,且多继承本身就会存在一定的问题,使用不当会导致和预期不一样的结果

思想定义:动态地给以个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更加灵活。其别名也可以称为包装器

优点

  1. 装饰模式可以提供比继承更多的灵活性
  2. 可以通过一种动态的方式来扩展一个对象的功能
  3. 具体构建类和具体装饰类可以独立变化,在添加新的具体构建类和具体装饰类时不需要修改原有代码,符合开闭原则

缺点

  1. 使用装饰模式进行系统设计时将产生很多小对象和具体装饰类,这些小对象和装饰类的产生增加系统的复杂度,加大学习与理解的难度
  2. 装饰模式比继承更加容易出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐

适用场景

  1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  2. 需要动态地给一个对象添加功能,这些功能也可以动态地撤销

代码:给诺手添加狂徒和黑切

//抽象英雄
class AbstractHero

public:
	virtual void ShowStatus() = 0;
public:
	int mHp;//血量
	int mMp;//蓝量
	int mAt;//攻击力
	int mDf;//防御力
;

//具体英雄--诺手
class NuoShou : public AbstractHero

public:
	NuoShou()
	
		mHp = 500;
		mMp = 200;
		mAt = 100;
		mDf = 80;
	
	virtual void ShowStatus()
	
		cout << "血量:" << mHp << endl;
		cout << "蓝量:" << mMp << endl;
		cout << "攻击力:" << mAt << endl;
		cout << "防御力:" << mDf << endl;
	
;

//英雄添加装备,添加完后还是一个英雄,所以要继承 AbstractHero
class AbstractEquipment :public AbstractHero

public:
	AbstractEquipment(AbstractHero* hero)
	
		this->hero = hero;
	
	virtual void ShowStatus()
protected:
	AbstractHero* hero;
;

//狂徒装备
class KuangtuEquipment : public AbstractEquipment

public:
	KuangtuEquipment(AbstractHero* hero)
		: AbstractEquipment(hero)
	
	//增加额外的功能
	void AddKuangtu()
	
		cout << "英雄购买了狂徒之后" << endl;
		this->mHp = this->hero->mHp + 1000;
		this->mMp = this->hero->mMp;
		this->mAt = this->hero->mAt;
		this->mDf = this->hero->mDf;
	
	virtual void ShowStatus()
	
		AddKuangtu();
		cout << "血量:" << mHp << endl;
		cout << "蓝量:" << mMp << endl;
		cout << "攻击力:" << mAt << endl;
		cout << "防御力:" << mDf << endl;
	
;

//黑切
class HeiqieEquipment : public AbstractEquipment

public:
	HeiqieEquipment(AbstractHero* hero)
		: AbstractEquipment(hero)
	
	//增加额外的功能
	void AddHeiqie()
	
		cout << "英雄购买了黑切之后" << endl;
		this->mHp = this->hero->mHp;
		this->mMp = this->hero->mMp;
		this->mAt = this->hero->mAt + 55;
		this->mDf = this->hero->mDf;
	
	virtual void ShowStatus()
	
		AddHeiqie();
		cout << "血量:" << mHp << endl;
		cout << "蓝量:" << mMp << endl;
		cout << "攻击力:" << mAt << endl;
		cout << "防御力:" << mDf << endl;
	
;

测试:

void test()

	AbstractHero* hero = new NuoShou();
	cout << "英雄初始属性" << endl;
	hero->ShowStatus();
	cout << endl;

	hero = new KuangtuEquipment(hero);
	hero->ShowStatus();
	cout << endl;

	hero = new HeiqieEquipment(hero);
	hero->ShowStatus();

截图:

以上是关于设计模式 C++装饰模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式 C++装饰模式

java设计模式之装饰模式

JAVA设计模式之装饰者模式

JAVA基础——设计模式之装饰者模式

装饰者模式

设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能