[デザインパターン] Head First デザインパターン - デコレータパターンの C++ 実装

デザイン パターンの最大の役割は、変更と安定性の間の分離点を見つけて、それらを分離して変更を管理することです。ウサギのように小銭をケージに閉じ込め、飛び出して部屋全体を汚すことなく、ケージ内で飛び回らせます。

デザイン思考

デコレータはオブジェクトに責任を動的に付加することで、機能を拡張するための継承に代わるより柔軟な手段を提供します。

装飾クラスはスーパークラスから継承しますが、継承は正しい型を持つものであり、スーパークラスの動作を継承するものではありません。

ビジネスシーン

Michelle Ice City の販売システムを設計する必要があるとします。ファミリ内のすべての飲み物が 2 つの属性 (説明と価格) だけを持っていると仮定すると、問題を解決するために継承を使用することを考えるかもしれません。最初にミルク ティーの親クラスを抽象化し、次に各ミルク ティーが親クラスを継承して独自の表示を実装します。そしてコスト方式。

これを行うには多くの問題があることがすぐにわかります。第一に、このミルク ティー ショップにあるすべてのミルク ティーの種類の総数は数十、数百になる可能性があり、これは非常に多くのサブカテゴリがあることを意味します。第 2 に、このようなデザインが実際のビジネスシーンと一致していないように見える ミルクティーを注文するとき、いつも同じとは限らない パールが必要ないものや二倍糖が入っていないものなど、味付けや盛り付けがバラバラである結局この一杯をどう表現するかというと、ミルクティーとその値段の計算が問題になります。

コード例

#include<iostream>
#i#include<iostream>
#include<vector>
#include<algorithm>
#include <string>
#include <memory>
 
//饮料抽象类
class Beverage {
public:
	virtual ~Beverage() {};
	virtual std::string getDescription() = 0;
	virtual double cost() = 0;
protected:
	std::string description;
	
};
//调料装饰者类
class Condimentecorator :public Beverage {
public:
	virtual ~Condimentecorator() {};
	virtual std::string getDescription() = 0;
};
 
//espresso 饮料类
class Espresso :public Beverage {
public:
	Espresso() :Beverage()
	{
		description = "Espresso";
	}
	std::string getDescription() { return description; }
	double cost() 
	{
		return 1.99;
	}
};
 
//houseblend 饮料类
class HouseBlend :public Beverage {
public:
	HouseBlend() :Beverage()
	{
		description = "HouseBlend";
	}
	std::string getDescription() { return description; }
	double cost() 
	{
		return 0.89;
	}
};
 
//DarkRoast 饮料类
class DarkRoast :public Beverage {
public:
	DarkRoast() :Beverage()
	{
		description = "DarkRoast";
	}
	std::string getDescription() { return description; }
	double cost() 
	{
		return 0.99;
	}
};
 
//Decat 饮料类
class Decat :public Beverage {
public:
	Decat() :Beverage()
	{
		description = "Decat";
	}
	std::string getDescription() { return description; }
	double cost()
	{
		return 1.05;
	}
};
 
//Mocha调料装饰者
class Mocha :public Condimentecorator {
 
public:
	Mocha(std::shared_ptr<Beverage> be) :Condimentecorator(), beverage(be) {}
	std::string getDescription() 
	{
		return (beverage->getDescription() + " Mocha");
	}
	double cost()
	{
		return 0.2 + beverage->cost();
	}
 
public:
	std::shared_ptr<Beverage> beverage;
};
 
//Soy调料装饰者
class Soy :public Condimentecorator {
public:
	Soy(std::shared_ptr<Beverage> be):Condimentecorator(),beverage(be){}
	std::string getDescription()
	{
		return (beverage->getDescription() + " Soy");
	}
	double cost()
	{
		return 0.15 + beverage->cost();
	}
public:
	std::shared_ptr<Beverage> beverage;
};
 
//Whip调料装饰者
class Whip :public Condimentecorator {
public:
	Whip(std::shared_ptr<Beverage> be) :Condimentecorator(), beverage(be) {}
	std::string getDescription()
	{
		return (beverage->getDescription() + " Whip");
	}
	double cost()
	{
		return 0.10 + beverage->cost();
	}
public:
	std::shared_ptr<Beverage> beverage;
};
 
int main()
{
	std::shared_ptr<Beverage> beverage = std::make_shared<Espresso>();
	std::cout << beverage->getDescription()<<" costs: "<<beverage->cost() << std::endl;
 
	std::shared_ptr<Beverage> beverage2 = std::make_shared<DarkRoast>();
	std::cout << beverage2->getDescription() << " costs: " << beverage2->cost() << std::endl;
 
    beverage2 = std::make_shared<Mocha>(beverage2);
	std::cout << beverage2->getDescription() << " costs: " << beverage2->cost() << std::endl;
 
    beverage2 = std::make_shared<Mocha>(beverage2);
	std::cout << beverage2->getDescription() << " costs: " << beverage2->cost() << std::endl;
 
	beverage2 = std::make_shared<Whip>(beverage2);
	std::cout << beverage2->getDescription() << " costs: " << beverage2->cost() << std::endl;

	auto it = std::make_shared<Whip>(beverage2);
	std::cout << it->cost() << " " << it->getDescription() << std::endl;
	std::cout << it->beverage->cost() << " " << it->beverage->getDescription() << std::endl;

	return 0;
}

おすすめ

転載: blog.csdn.net/weixin_43717839/article/details/132541470