设计模式之装饰者模式(Decorator Pattern)

今天就让我们来了解一下装饰者模式吧~~~

首先何为装饰呢?装饰的解释:特定的建筑物或室内按照一定的思路和风格进行美化的一种活动。就是对对对象进行包装啦~~比如有一天你带着女朋友逛街,女朋友说“我要喝HouseBlend!!”虽然有点贵但是没办法啊!! 这时女朋友说“啧!! 太难喝了!!,我要加Milk(牛奶)”。喝了一口。“好像还不合胃口哦~~,我要加这个,我还要加个” (哎~~ 幸亏我没有女朋友哦  哈哈)。咳咳!!我们言归正传。此例子中,被装饰者是HouseBlend,装饰者是 Milk,Mocha,Soy,Whip。大家发现没?不管是HouseBlend还是Milk,Mocha,Soy,Whip,它们都是饮料啊。所以装饰者与被装饰者的类型是一样的,也就是它们有共同的父类。

首先我们应该知道,利用继设计子类的行为,是在编译时期静态决定的,而且所有的子类都会继承相同的行为(is_a关系)。使用继承无法动态的进行装饰,也不具有扩展性和弹性,而且有时候会导致类爆炸!!所以这种设计模式死板的,还有如果基类进行改变的话,其所有的子类都必须改变。因此,我们可以使用组合对象动态的达到继承的效果

装饰者模式的核心思想:动态的将责任附加到对象上。

class CondimentDecorator :public Beverage {  //装饰者的行为基类
public:
	CondimentDecorator(std::shared_ptr<Beverage> _bp):ptr(_bp),condimentdecoratorname(std::make_unique<std::string>("CondimentDecorator")) {};
public:
	void GetDescription()const override;
protected:
	std::shared_ptr<Beverage>ptr; //将装饰者与被被装饰者进行组合,可以加入新的装饰对象。
private:
	std::shared_ptr<std::string>condimentdecoratorname;
};
void CondimentDecorator::GetDescription()const {
	std::cout << condimentdecoratorname->c_str() << std::endl;
}

其原理视图:

 完整代码如下:

#include<iostream>
#include<memory>
typedef double PRICE;
class Beverage {   //构建装饰者与被装饰者的同一接口(装饰者与被装饰者的父类型相同)
public:
	virtual PRICE cost() = 0;
	virtual void GetDescription()const = 0;
};

class HouseBlend :public Beverage {
public:
	HouseBlend() :houseblend(std::make_unique<std::string>("HouseBlend")) {};
	~HouseBlend() {};
public:
	PRICE cost()override;
	void GetDescription()const override;
private:
	std::shared_ptr<std::string>houseblend;
};   
PRICE HouseBlend::cost() {
	return 1.0;
}
void HouseBlend::GetDescription()const {
	std::cout << houseblend->c_str() << "  ";
}


class DarkRoast :public Beverage {
public:
	DarkRoast() :darkroastname(std::make_unique<std::string>("DarkRoast")) {};
	~DarkRoast() {};
public:
	PRICE cost()override;
	void GetDescription()const override;
private:
	std::shared_ptr<std::string>darkroastname;
};
PRICE DarkRoast::cost() {
	return 2.0;
}
void DarkRoast::GetDescription()const {
	std::cout << darkroastname->c_str() << std::endl;
}


class Espresso :public Beverage {
public:
	Espresso() :espressoname(std::make_unique<std::string>("Espresso")) {};
	~Espresso() {};
public:
	PRICE cost()override;
	void GetDescription()const override;
private:
	std::shared_ptr<std::string>espressoname;
};
PRICE Espresso::cost(){
	return 3.0;
}
void Espresso::GetDescription()const {
	std::cout << espressoname->c_str() << std::endl;
}


class Decaf :public Beverage {
public:
	Decaf() :decafname(std::make_unique<std::string>("Decaf")) {};
	~Decaf() {};
public:
	PRICE cost()override;
	void GetDescription()const override;
private:
	std::shared_ptr<std::string>decafname;
}; 
PRICE Decaf::cost() {
	return 4.0;
}
void Decaf::GetDescription()const {
	std::cout << decafname->c_str() << std::endl;
}


class CondimentDecorator :public Beverage {  //装饰者的行为基类
public:
	CondimentDecorator(std::shared_ptr<Beverage> _bp):ptr(_bp),condimentdecoratorname(std::make_unique<std::string>("CondimentDecorator")) {};
public:
	void GetDescription()const override;
protected:
	std::shared_ptr<Beverage>ptr;  
private:
	std::shared_ptr<std::string>condimentdecoratorname;
};
void CondimentDecorator::GetDescription()const {
	std::cout << condimentdecoratorname->c_str() << std::endl;
}


class Milk :public CondimentDecorator {
public:
	Milk(std::shared_ptr<Beverage> _bp) :CondimentDecorator(_bp), milkname(std::make_shared<std::string>("Milk")) {};
	~Milk() {};
public:
	PRICE cost()override;
	void GetDescription()const override;
public:
	std::shared_ptr<std::string>milkname;
};
PRICE Milk::cost(){
	return 5.0 + ptr->cost();
}
void Milk::GetDescription()const {
	std::cout << milkname->c_str() << "  ";
}


class Mocha :public CondimentDecorator {
public:
	Mocha(std::shared_ptr<Beverage> _bp) :CondimentDecorator(_bp), mochaname(std::make_unique<std::string>("Mocha")) {};
	~Mocha() {};
public:
	PRICE cost()override;
	void GetDescription()const override;
private:
	std::shared_ptr<std::string>mochaname;
};
PRICE Mocha::cost() {
	return 6.0 + ptr->cost();
}
void Mocha::GetDescription()const {
	std::cout << mochaname->c_str() << "  ";
}



class Soy :public CondimentDecorator {
public:
	Soy(std::shared_ptr<Beverage>_sp) :CondimentDecorator(_sp), soyname(std::make_unique<std::string>("Soy")) {};
	~Soy() {};
public:
	PRICE cost()override;
	void GetDescription()const override;
private:
	std::shared_ptr<std::string>soyname;
};
PRICE Soy::cost() {;
	return 7.0 + ptr->cost();
}
void Soy::GetDescription()const {
	std::cout << soyname->c_str() << "  ";
}


class Whip :public CondimentDecorator {
public:
	Whip(std::shared_ptr<Beverage>_wp) :CondimentDecorator(_wp), whipname(std::make_unique<std::string>("Whip")) {};
	~Whip() {};
public:
	PRICE cost()override;
	void GetDescription()const override;
private:
	std::shared_ptr<std::string>whipname;
};
PRICE Whip::cost() {
	return 8.0 + ptr->cost();
}
void Whip::GetDescription()const {
	std::cout << whipname->c_str() << "  ";
}

int main(void)
{
	std::shared_ptr<HouseBlend>houseblend(std::make_shared<HouseBlend>());  //我要喝HouseBlend(被装饰者)
	houseblend->GetDescription();
	std::cout << "houseblend price: " << houseblend->cost() << std::endl;
	std::cout << std::endl;

	std::shared_ptr<Milk>milk(std::make_shared<Milk>(houseblend)); // 加入milk(装饰者)
	milk->GetDescription();
	std::cout << "add milk price: " << milk->cost() << std::endl;
	std::cout << std::endl;

	std::shared_ptr<Mocha>mocha(std::make_shared<Mocha>(milk));  //加入mocha(装饰者)
	mocha->GetDescription();
	std::cout << "add mocha price: " << mocha->cost() << std::endl;
	std::cout << std::endl;

	std::shared_ptr<Soy>soy(std::make_shared<Soy>(mocha)); //加入soy(装饰者)
	soy->GetDescription();
	std::cout << "add soy price: " << soy->cost() << std::endl;
	std::cout << std::endl;

	std::shared_ptr<Whip>whip(std::make_shared<Whip>(soy));  //加入whip(装饰者)
	whip->GetDescription();
	std::cout << "add whip price: " << whip->cost() << std::endl;
	std::cout << std::endl;

	auto price = whip->cost();
	std::cout << "All Price: " << price << std::endl;

	system("pause");
	return 0;
}

发布了50 篇原创文章 · 获赞 11 · 访问量 4081

猜你喜欢

转载自blog.csdn.net/qq_43145594/article/details/103634121