设计模式学习(六) 装饰模式 Decorator

1. 装饰模式的定义与类图分析

装饰模式即把要添加的附加功能分别放在单独的类中,并让此类包含其所要装饰的类(对象);其主要用于给一个固定对象添加一些额外的职责,且该模式比生成子类的方式更为灵活。通俗点说,装饰模式类似于我们玩RPG游戏,被装饰的对象就是我们自己,而装饰对象就是游戏中的各种武器道具等等,而这些装饰对象比如武器又分为刀剑棍棒等等子系类别。其具体的类图构造如下:
装饰模式类图
首先我感觉我的类图画的一直都挺丑的,然后可以发现作为母体的抽象基类具体被继承为被装饰对象以及装饰对象基类,其中这个基类可要可不要,具体地根据设计者的需要来确定。然后装饰对象基类根据情况又可以实例化出多个具体的装饰类,从而实现对装饰类的装饰。其中值得一提的是,被装饰对象并非只能有一个,而装饰对象与装饰对象抽象基类也可以有许多个。

2.装饰模式的实现代码

以AGV小车的定位模式(地图定位和二维码定位)以及其移动方式(自动移动和手动移动)对一个普通的AGV小车进行装饰设计。

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

class AGV_Car
{
public: 
	virtual void Component() = 0;
};

class Normal_AGV_Car : public AGV_Car
{
public:
	void Component() override
	{
		cout << "I can achieve AGV_Car normal work!" << endl;
	}
};

class Location_Component4AGV_Car : public AGV_Car
{
public:
	virtual void Location_Component() = 0;
	virtual void Component() = 0;
private:
	AGV_Car* m_agvcar;
};

class Move_Component4AGV_Car : public AGV_Car
{
public:
	virtual void Move_Component() = 0;
	virtual void Component() = 0;
private:
	AGV_Car* m_agvcar;
};

class Map_Location : public Location_Component4AGV_Car
{
public:
	Map_Location(AGV_Car* agvcar)
	{
		m_agvcar = agvcar;
	}
	void Location_Component() override
	{
		cout << "New Location_Component: I can use the Map Location!" << endl;
	}
	void Component() override
	{
		m_agvcar->Component();
		Location_Component();
	}
private:
	AGV_Car* m_agvcar;
};

class QR_Location : public Location_Component4AGV_Car
{
public:
	QR_Location(AGV_Car* agvcar)
	{
		m_agvcar = agvcar;
	}
	void Location_Component() override
	{
		cout << "New Location_Component: I can use the QR Location!" << endl;
	}
	void Component() override
	{
		m_agvcar->Component();
		Location_Component();
	}
private:
	AGV_Car* m_agvcar;
};

class Auto_Move : public Move_Component4AGV_Car
{
public:
	Auto_Move(AGV_Car* agvcar)
	{
		m_agvcar = agvcar;
	}
	void Move_Component() override
	{
		cout << "New Move_Component: I can use the Auto Move!" << endl;
	}
	void Component() override
	{
		m_agvcar->Component();
		Move_Component();
	}
private:
	AGV_Car* m_agvcar;
};

class Hand_Move : public Move_Component4AGV_Car
{
public:
	Hand_Move(AGV_Car* agvcar)
	{
		m_agvcar = agvcar;
	}
	void Move_Component() override
	{
		cout << "New Move_Component: I can use the Hand Move!" << endl;
	}
	void Component() override
	{
		m_agvcar->Component();
		Move_Component();
	}
private:
	AGV_Car* m_agvcar;
};

int main()
{
	Normal_AGV_Car* agvcar = new Normal_AGV_Car;
	agvcar->Component();

	Map_Location* maploc_agvcar = new Map_Location(agvcar);        //值得一提的是,这里的Map和QR都使用的是同一个agvcar,根据其构造函数为浅拷贝,可知这里的两个函数使用的是同一个内存的变量
	maploc_agvcar->Component();

	QR_Location* qr_agvcar = new QR_Location(agvcar);
	qr_agvcar->Component();

	Auto_Move* automove_agvcar = new Auto_Move(maploc_agvcar);
	automove_agvcar->Component();

	Hand_Move* handmove_agvcar = new Hand_Move(qr_agvcar);
	handmove_agvcar->Component();
}

上面这种代码实现方式,基本实现了装饰模式的设计,但是根据其类图关系,以及抽象类的设计原则,我将两种装饰抽象类的构造函数进行了重载,并将相关的m_agvcar的成员定义在了抽象类中,其子类通过调用父类的构造函数与保护变量m_agvcar来实现装饰操作。

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

class AGV_Car
{
public: 
	virtual void Component() = 0;
};

class Normal_AGV_Car : public AGV_Car
{
public:
	void Component() override
	{
		cout << "I can achieve AGV_Car normal work!" << endl;
	}
};

class Location_Component4AGV_Car : public AGV_Car
{
public:
	Location_Component4AGV_Car(AGV_Car* agvcar)
	{
		m_agvcar = agvcar;
	}
	virtual void Location_Component() = 0;
	virtual void Component() = 0;
protected:
	AGV_Car* m_agvcar;
};

class Move_Component4AGV_Car : public AGV_Car
{
public:
	Move_Component4AGV_Car(AGV_Car* agvcar)
	{
		m_agvcar = agvcar;
	}
	virtual void Move_Component() = 0;
	virtual void Component() = 0;
protected:
	AGV_Car* m_agvcar;
};

class Map_Location : public Location_Component4AGV_Car
{
public:
	Map_Location(AGV_Car* agvcar) : Location_Component4AGV_Car(agvcar) {}
	void Location_Component() override
	{
		cout << "New Location_Component: I can use the Map Location!" << endl;
	}
	void Component() override
	{
		m_agvcar->Component();
		Location_Component();
	}
};

class QR_Location : public Location_Component4AGV_Car
{
public:
	QR_Location(AGV_Car* agvcar) : Location_Component4AGV_Car(agvcar) {}
	void Location_Component() override
	{
		cout << "New Location_Component: I can use the QR Location!" << endl;
	}
	void Component() override
	{
		m_agvcar->Component();
		Location_Component();
	}
};

class Auto_Move : public Move_Component4AGV_Car
{
public:
	Auto_Move(AGV_Car* agvcar) : Move_Component4AGV_Car(agvcar) {}
	void Move_Component() override
	{
		cout << "New Move_Component: I can use the Auto Move!" << endl;
	}
	void Component() override
	{
		m_agvcar->Component();
		Move_Component();
	}
};

class Hand_Move : public Move_Component4AGV_Car
{
public:
	Hand_Move(AGV_Car* agvcar) : Move_Component4AGV_Car(agvcar) {}
	void Move_Component() override
	{
		cout << "New Move_Component: I can use the Hand Move!" << endl;
	}
	void Component() override
	{
		m_agvcar->Component();
		Move_Component();
	}
};

int main()
{
	Normal_AGV_Car* agvcar = new Normal_AGV_Car;
	agvcar->Component();

	Map_Location* maploc_agvcar = new Map_Location(agvcar);        //值得一提的是,这里的Map和QR都使用的是同一个agvcar,根据其构造函数为浅拷贝,可知这里的两个函数使用的是同一个内存的变量
	maploc_agvcar->Component();

	QR_Location* qr_agvcar = new QR_Location(agvcar);
	qr_agvcar->Component();

	Auto_Move* automove_agvcar = new Auto_Move(maploc_agvcar);
	automove_agvcar->Component();

	Hand_Move* handmove_agvcar = new Hand_Move(qr_agvcar);
	handmove_agvcar->Component();

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方寸间沧海桑田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值