1. 程式人生 > >C++ 學習筆記(22)Builder Pattern

C++ 學習筆記(22)Builder Pattern

Builder Pattern

建造者模式。

#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include <assert.h>
#include <map>

namespace Restaurant {

	// 產品類, 此景中為 套餐(set menu)
	class setMenu {
	private:
		std::vector<std::string> mealOrder;  // 點的菜名
		static std::map<const std::string, double> priceList;

	public:
		void addMeal(const std::string name) {
			// find 檢驗菜名是否存在
			mealOrder.emplace_back(name);
		}
		void payBill() {
			auto comsumption = 0.00;
			for(const auto &it : mealOrder) {
				comsumption += priceList[it];
				std::cout << priceList[it] << "  RMB   ------   " << it << "\n";
			}
			std::cout << "\n本次套餐消費總共  " << comsumption << "  RMB\n\n";
		}
	};
	std::map<const std::string, double> setMenu::priceList = {
		// 主食價格
		{ "rice", 3.00 },
		{ "dongBei rice", 5.00 },
		{ "Thai rice", 7.00 },
		// 熱菜價格
		{ "drumSticks", 4.00 },
		{ "pizza", 20.00 },
		{ "beef", 25.00 },
		{ "seaWeed", 6.00}, 
		{ "salted Duck", 100.00 },
		// 飲料價格
		{ "soya-bean milk", 2.00 },
		{ "orange juice", 3.00 },
		{ "coconut milk", 5.00}
	};

	// 建造者模型, 提供介面, 情景含義————製作套餐
	class Builder {
	public:
		virtual ~Builder() = default;

		virtual void addRice() = 0;
		virtual void addDish() = 0;
		virtual void addDrinks() = 0;
		virtual std::shared_ptr<setMenu> getMeal() = 0;
	} ;

	// 製造套餐 A
	class Builder_A : public Builder {
	public:
		void addRice() override {
			ptr->addMeal("rice");
		}
		void addDish() override {
			ptr->addMeal("pizza");
			ptr->addMeal("drumSticks");
		}
		void addDrinks() override {
			ptr->addMeal("orange juice");
		}
		std::shared_ptr<setMenu> getMeal() {
			return ptr;
		}
	private:
		std::shared_ptr<setMenu> ptr = std::make_shared<setMenu>();
	} ;

	// 製造套餐 B
	class Builder_B : public Builder {
	public:
		void addRice() override {
			ptr->addMeal("dongBei rice");
		}
		void addDish() override {
			ptr->addMeal("salted Duck");
		}
		void addDrinks() override {
			ptr->addMeal("soya-bean milk");
		}
		std::shared_ptr<setMenu> getMeal() {
			return ptr;
		}
	private:
		std::shared_ptr<setMenu> ptr = std::make_shared<setMenu>();
	} ;

	// // 製造套餐 C
	class Builder_C : public Builder {
	public:
		void addRice() override {
			ptr->addMeal("Thai rice");
		}
		void addDish() override {
			ptr->addMeal("pizza");
			ptr->addMeal("beef");
		}
		void addDrinks() override {
			ptr->addMeal("coconut milk");
		}
		std::shared_ptr<setMenu> getMeal() {
			return ptr;
		}
	private:
		std::shared_ptr<setMenu> ptr = std::make_shared<setMenu>();
	} ;

	class packMeal {
	public:
		void makePack(const std::shared_ptr<Builder> style) {
			style->addRice();
			style->addDish();
			style->addDrinks();
		}
	} ;
}

int main() {
	using namespace Restaurant;
	std::shared_ptr<packMeal> courier = std::make_shared<packMeal>();

	std::cout << "\n------------- 小芳點套餐 A -------------\n\n";
	std::shared_ptr<Builder> styleA = std::make_shared<Builder_A>();
	courier->makePack(styleA);
	std::shared_ptr<setMenu> XiaoFang = styleA->getMeal();
	XiaoFang->payBill();

	std::cout << "\n------------- 小明點套餐 B -------------\n\n";
	std::shared_ptr<Builder> styleB = std::make_shared<Builder_B>();
	courier->makePack(styleB);
	std::shared_ptr<setMenu> XiaoMing = styleB->getMeal();
	XiaoMing->payBill();

	std::cout << "\n------------- 小楊點套餐 C -------------\n\n";
	std::shared_ptr<Builder> styleC = std::make_shared<Builder_C>();
	courier->makePack(styleC);
	std::shared_ptr<setMenu> XiaoYang = styleC->getMeal();
	XiaoYang->payBill();

	std::cout << "\n------------- 小暢點套餐 C -------------\n\n";
	std::shared_ptr<setMenu> XiaoChang = styleC->getMeal();
	XiaoChang->payBill();

	return 0;
}

執行結果:

------------- 小芳點套餐 A -------------

3  RMB   ------   rice 20  RMB   ------   pizza 4  RMB   ------   drumSticks 3  RMB   ------   orange juice

本次套餐消費總共  30  RMB

------------- 小明點套餐 B -------------

5  RMB   ------   dongBei rice 100  RMB   ------   salted Duck 2  RMB   ------   soya-bean milk

本次套餐消費總共  107  RMB

------------- 小楊點套餐 C -------------

7  RMB   ------   Thai rice 20  RMB   ------   pizza 25  RMB   ------   beef 5  RMB   ------   coconut milk

本次套餐消費總共  57  RMB

------------- 小暢點套餐 C -------------

7  RMB   ------   Thai rice 20  RMB   ------   pizza 25  RMB   ------   beef 5  RMB   ------   coconut milk

本次套餐消費總共  57  RMB