#include "stdafx.h" #include <iostream> #include <boost/any.hpp> #include <boost/bind.hpp> #include <algorithm> #include <vector> #include <functional> #include <boost/shared_ptr.hpp> using namespace std; using namespace boost; /** * @brief Builder模式将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 * 客户端:顾客。想去买一套套餐(这里面包括汉堡,可乐,薯条),可以有1号和2号两种套餐供顾客选择。 * 指导者角色:收银员。知道顾客想要买什么样的套餐,并告诉餐馆员工去准备套餐。 * 建造者角色:餐馆员工。按照收银员的要求去准备具体的套餐,分别放入汉堡,可乐,薯条等。 * 产品角色:最后的套餐,所有的东西放在同一个盘子里面。 */ /** @brief 产品类(相当于套餐) */ void ShowAny(const any& value) { cout << any_cast<string>(value).c_str() << endl; } class Food { public: /** 添加食品 */ void Add(const string& strName) { m_vecAny.push_back(strName); } /** 打印所有食品 */ void Show() { for_each(m_vecAny.begin(),m_vecAny.end(),ShowAny); } private: vector<any> m_vecAny; ///< 存储食物 }; /** @brief 抽象建造者类、构造套餐 */ class Builder { public: virtual void BuildHamb() = 0; ///< 添加汉堡 virtual void BuildCoke() = 0; ///< 添加可乐 virtual void BuildChip() = 0; ///< 添加薯条 shared_ptr<Food> GetFood() { return m_pFood; } protected: Builder(void) { m_pFood = shared_ptr<Food>(new Food()); } protected: shared_ptr<Food> m_pFood; }; class NormalBuilder : public Builder { public: virtual void BuildHamb() { m_pFood->Add("NormalHamb"); } virtual void BuildCoke() { m_pFood->Add("CokeCole"); } virtual void BuildChip() { m_pFood->Add("FireChips"); } }; class GoldBuilder : public Builder { public: virtual void BuildHamb() { m_pFood->Add("GoldHamb"); } virtual void BuildCoke() { m_pFood->Add("CokeCole"); } virtual void BuildChip() { m_pFood->Add("FireChips"); } }; /** @brief 指导者类(相当于收银员) */ class FoodManager { public: shared_ptr<Food> Construct(Builder& build) { build.BuildHamb(); build.BuildCoke(); build.BuildChip(); return build.GetFood(); } }; int _tmain(int argc, _TCHAR* argv[]) { shared_ptr<FoodManager> pFoodManager(new FoodManager()); GoldBuilder goldBuilder; Builder& builder = goldBuilder; cout << "Please Enter Food No:"; int nNumber; cin >> nNumber; cout << "Food No: " << nNumber << endl; shared_ptr<Food> pFood; pFood = pFoodManager->Construct(builder); pFood->Show(); system("pause"); return 0; }