设计模式(3)--装饰模式

本文详细介绍了装饰模式的概念及其三种实现版本,通过示例代码展示了如何动态地给一个对象添加职责,对比了不同版本的特点与应用场景。
//单一原则: 一个类而言,应该仅有一个引起它变化的原因。
//开放-封闭原则: 类/模块/函数等等,应该可以扩展,但是不可修改。
//依赖倒装原则: 抽象不应该依赖细节,洗劫应该依赖于抽象。换句话说是,要针对接口编程,不要对实现编程。
//A.高层模块不应该依赖低层模块。两个都应该依赖抽象。
//B.抽象不应该依赖细节。细节应该依赖抽象。
//里氏代换原则: 子类型必须能够替换掉它们的父类型。

 

//3.装饰模式
//ver1
class Person
{
private:
	string _name;
public:
	Person(string name)
	{
		_name = name;
	}
	void Show()
	{
		//...
	}
};

//服饰抽象类
class Finery
{
public:
	virtual void Show() = 0;
};

//T恤类
class TShirts : public Finery
{
public:
	virtual void Show()
	{
		//..
	}
};

//垮裤类
class BigTrouser : public Finery
{
public:
	virtual void Show()
	{
		//..
	}
};

//领带类
class Tie : public Finery
{
public:
	virtual void Show()
	{
		//..
	}
};

void main11()
{
	Person *ppc = new Person("fun");
	TShirts *pd1 = new TShirts();
	BigTrouser *pd2 = new BigTrouser();
	Tie *pd3 = new Tie();

	//装扮1
	pd1->Show();
	pd2->Show();
	ppc->Show();
	//装扮2
	pd1->Show();
	pd3->Show();
	ppc->Show();
	//缺点: 一个一个显示出来; 组装应该在内部进行; 
}

 

//装饰模式: 动态地给一个对象添加一些额外的职责,就增加功能类说,装饰模式比生成子类更为灵活;

 

//3.装饰模式
//ver2

//Component是定义一个对象接口,可以给这些对象动态地添加职责。
//ConcreteComponent是定义一个具体的对象,也可以给这个对象添加一些职责。
//Decorator抽象装饰类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,无需知道Decorator的存在;
//ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。

class Component
{
public:
	virtual void Operation() = 0; //接口
};

class ConcreteComponent : public Component
{
	virtual void Operation()
	{
		//...
	}
};

class Decorator : public Component
{
protected:
	Component *pcomponent;
public:
	void SetComponent(Component *pcom)
	{
		pcomponent = pcom;
	}
	virtual void Operation()
	{
		if (pcomponent != NULL)
		{
			pcomponent->Operation();
		}
	}
};

class ConcreteDecoratorA : public Decorator
{
private:
	string addState;
public:
	virtual void Operation()
	{
		Decorator::Operation(); //先运行Component的Operation,再执行本类的操作。
		addState = "New State";
		//...
	}
};

class ConcreteDecoratorB : public Decorator
{
private:
	void AddBehavior() //本类独有的操作;
	{
		//...
	}
public:
	virtual void Operation()
	{
		Decorator::Operation();
		AddBehavior();
	}
};

void main12()
{
	ConcreteComponent * pc = new ConcreteComponent();
	ConcreteDecoratorA * d1 = new ConcreteDecoratorA();
	ConcreteDecoratorB * d2 = new ConcreteDecoratorB();

	d1->SetComponent(pc); //先用 ConcreteDecoratorA 来包装 ConcreteComponent; 会执行 ConcreteComponent::Operation()
	d2->SetComponent(d1); //再用 ConcreteDecoratorB 来包装 ConcreteDecoratorA
	d2->Operation(); //最终执行 d2->Operation()
	//装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了。
	//每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。
}

 

//如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
//如果只有一个ConcreteDecorator类,那么久没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合成一个类.

 

 

//3.装饰模式
//ver3
class Person
{
private:
	string _name;
public:
	Person(){} //用于 TShirts 等派生类构造默认的构造函数;
	Person(string name)
	{
		_name = name;
	}
	virtual void Show()
	{

	}
};

//服饰类
class Finery : public Person
{
protected:
	Person component;

public:
	void Decorate(Person comp)
	{
		component = comp;
	}

	virtual void Show()
	{
		component.Show();
	}
};

//具体服饰类
class TShirts : public Finery
{
public:
	virtual void Show()
	{
		//do something
		Finery::Show();
	}
};

class BigTrouser : public Finery
{
public:
	virtual void Show()
	{
		//do something.
		Finery::Show();
	}
};

void main31()
{
	Person * ppc = new Person("fun");

	TShirts * pd1 = new TShirts();
	BigTrouser * pd2 = new BigTrouser();

	pd1->Decorate(*ppc);
	pd2->Decorate(*pd1);
	pd2->Show();
}

 

//装饰模式是为已有功能动态地添加更多功能的一种方式。
//装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。
//优点: 把类中的装饰功能从类中搬移去除,这样可以简化原有的类。
// 有效地把类的核心职能和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。

 

转载于:https://www.cnblogs.com/sylar-liang/p/6021587.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值