[Design Pattern] Head First Design Pattern - C++ Implementation of Decorator Pattern

The biggest role of design patterns is to find isolation points between changes and stability, and then separate them to manage changes. Lock the change in a cage like a bunny, and let it jump around in the cage without jumping out and polluting your entire room.

design thinking

By dynamically attaching responsibilities to objects, decorators provide a more flexible alternative to inheritance for extending functionality.

The decoration class inherits from the superclass, and the inheritance is to have the correct type, not to inherit the behavior of the superclass.

Business scene

Suppose you need to design a sales system for Michelle Ice City. Assuming that all the drinks in their family have only two attributes: description and price, you may think of using inheritance to solve the problem: first abstract a milk tea parent class, and then each milk tea inherits the parent class and implements its own display and cost methods.

You will soon find that there are a lot of troubles in doing this: first, the total number of all milk tea types in this milk tea shop may be dozens and hundreds, which means that you will have many, many subcategories; secondly, Such a design does not seem to be in line with the actual business scenario. When people order milk tea, it is not always the same. Some do not need pearls, some do not have double sugar, etc., and the seasonings and servings are different. So how to describe this cup in the end? Milk tea and calculating its price become a problem.

code example

#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;
}

Guess you like

Origin blog.csdn.net/weixin_43717839/article/details/132541470