装饰模式

首先来看一个场景,你今天和一个爱登山的MM约会了,你需穿一套登山装,明天你和一个爱运动的妹妹约会,你需要穿一套运动服,后天你和一个比较喜欢绅士的妹纸约会,你就需要西装革履,但是无论你穿什么,你还是你,唯一的你只是传了不同的衣服而已,仅仅是在装饰自己。

装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。


Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的,至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
装饰模式是为已有功能动态的添加更多新的功能的一种方式。
应用场景:当系统需要需要新的功能的时候,是向就得类中添加新的代码,比如你又买了一件衣服,就可以重新添加一个衣服的类。这些新添加的代码通常装饰了原有类的核心职责或主要行为,如果在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂性,而这些新添加的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要,而装饰模式却提供了一个非常好的解决方案,把每个要装饰的功能放在单独的类中,并让这个类包装所要修饰的对象,因此,当需要执行特殊任务时,客户代码就可以在运行时根据需要有选择的,按顺序的装饰功能包装对象(注意,顺序不唯一)。
优点:把类中装饰功能从类中搬移出去,这样就可以简化原有的类,吧类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。
区别:这个模式和建造者模式似乎有点相似,但是注意,建造者模式过程可以固定的,如果是建造者模式,穿衣服这个过程视为一个抽象基类,里面有两步,穿上衣穿下衣,然后穿运动服和西装是两个具体建造实例,不会出现程序里那种自由组合的现象,出现了穿T恤和西裤这种尴尬的组合。


#include <string>
#include <iostream>
using namespace std;
class Person//被装饰的对象的基类
{
public:
	virtual void show() = 0;//核心职责,当然是展示自己
};
class ChinaPerson : public Person
{
private:
	string name;
public:
	ChinaPerson(string _name) :name(_name)
	{}
	void show()
	{
		cout << "装饰的是" << name << endl;
	}
};
class Finery : public Person//服饰类,来装饰Person,共有继承总感觉怪怪的
{
protected:
	Person* component;//需要被装饰的人
public:
	void Decorate(Person* component)
	{
		this->component = component;
	}
	void show()
	{
		if (component != nullptr)
		{
			component->show();//装饰Perosn
		}
	}
};
class TShirts : public Finery//具体服饰类,穿T恤
{
public:
	void show()
	{
		Finery::show();
		cout << "大T恤" << endl;
	}
};
class BigTrouser : public Finery//具体服饰类,穿垮裤
{
public:
	void show()
	{
		Finery::show();
		cout << "垮裤" << endl;
	}
};
class  ManSuit : public Finery
{
public:
	void show()
	{
		Finery::show();
		cout << "穿西服" << endl;
	}
};
class  WestTrouser : public Finery
{
public:
	void show()
	{
		Finery::show();
		cout << "穿西裤" << endl;
	}
};
int main()
{
	Person* p = new ChinaPerson("小李");
	TShirts* ts = new TShirts();
	BigTrouser* bt = new BigTrouser();
	ManSuit* ms = new ManSuit();
	WestTrouser* wt = new WestTrouser();
	ts->Decorate(p);
	bt->Decorate(p);
	ms->Decorate(p);
	wt->Decorate(p);
	cout << "第一种装扮" << endl;
	ts->show();
	bt->show();
	cout << "第二种装扮" << endl;
	ms->show();
	wt->show();
	cout << "第三种装扮" << endl;
	ts->show();
	wt->show();
	delete p;
	delete ts;
	delete bt;
	delete ms;
	delete wt;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值