HeadFirst设计模式C++实现-AbstractFactory模式

定义:

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不是要明确指定具体类。

作用:

抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际产出的具体产品是什么。这样一来,客户就从具体的产品被解耦。

UML图:

注:此处只给出部分图

HeadFirst设计模式C++实现-AbstractFactory模式

代码实现:

/************************************************************************/ /* PizzaIngredient.h */ /************************************************************************/ /** * @file PizzaIngredient.h * @brief AbstractFactory模式的实现代码 * @author [email protected] * http://blog.****.net/rabbit729 * @version 1.0 * @date 2009-02-16 */ #ifndef PIZZAINGREDIENT_H_ #define PIZZAINGREDIENT_H_ #include <vector> #include <string> #include <iostream> using namespace std; class ICheese { public: virtual string toString() = 0; }; class IClams { public: virtual string toString() = 0; }; class IDough { public: virtual string toString() = 0; }; class IPepperoni { public: virtual string toString() = 0; }; class ISauce { public: virtual string toString() = 0; }; class IVeggies { public: virtual string toString() = 0; }; class IPizzaIngredientFactory { public: virtual IDough* CreateDough() = 0; virtual ISauce* CreateSauce() = 0; virtual ICheese* CreateCheese() = 0; virtual IPepperoni* CreatePepporoni() = 0; virtual IClams* CreateClam() = 0; virtual vector<IVeggies*> CreateVeggies() = 0; }; class FreshClams : public IClams { public: string toString(); }; class FrozenClams : public IClams { public: string toString(); }; class MarinarSauce : public ISauce { public: string toString(); }; class PlumTomatoSauce : public ISauce { public: string toString(); }; class ThickCrustDough : public IDough { public: string toString(); }; class ThinCrustDough : public IDough { public: string toString(); }; class ReggianoCheese : public ICheese { public: string toString(); }; class Mozzerella : public ICheese { public: string toString(); }; class SlicedPepperoni : public IPepperoni { public: string toString(); }; class BlackOlives : public IVeggies { public: string toString(); }; class EggPlant : public IVeggies { public: string toString(); }; class Garlic : public IVeggies { public: string toString(); }; class Mushroom : public IVeggies { public: string toString(); }; class Onion : public IVeggies { public: string toString(); }; class RedPepper : public IVeggies { public: string toString(); }; class Spinach : public IVeggies { public: string toString(); }; class NYPizzaIngredientFactory : public IPizzaIngredientFactory { public: IDough* CreateDough(); ISauce* CreateSauce(); ICheese* CreateCheese(); vector<IVeggies*> CreateVeggies(); IPepperoni* CreatePepporoni(); IClams* CreateClam(); }; class ChicagoPizzaIngredientFactory : public IPizzaIngredientFactory { public: IDough* CreateDough(); ISauce* CreateSauce(); ICheese* CreateCheese(); vector<IVeggies*> CreateVeggies(); IPepperoni* CreatePepporoni(); IClams* CreateClam(); }; #endif /************************************************************************/ /* Pizza.h */ /************************************************************************/ /** * @file Pizza.h * @brief AbstractFactory模式的实现代码 * @author [email protected] * http://blog.****.net/rabbit729 * @version 1.0 * @date 2009-02-16 */ #ifndef PIZZA_H_ #define PIZZA_H_ #include "PizzaIngredient.h" class Pizza { public: virtual string Prepare() = 0; virtual string Bake(); virtual string Cut(); virtual string Box(); string GetName(); void SetName(string name); protected: IDough* dough; ISauce* sauce; vector<IVeggies*> veggies; ICheese* cheese; IPepperoni* pepperoni; IClams* clam; string name; }; class CheesePizza : public Pizza { public: CheesePizza(IPizzaIngredientFactory* ingredientFactory); string Prepare(); private: IPizzaIngredientFactory* ingredientFactory; }; class ClamPizza : public Pizza { public: ClamPizza(IPizzaIngredientFactory* ingredientFactory); string Prepare(); private: IPizzaIngredientFactory* ingredientFactory; }; class PepperoniPizza : public Pizza { public: PepperoniPizza(IPizzaIngredientFactory* ingredientFactory); string Prepare(); private: IPizzaIngredientFactory* ingredientFactory; }; #endif /************************************************************************/ /* PizzaStore.h */ /************************************************************************/ /** * @file PizzaStore.h * @brief AbstractFactory模式的实现代码 * @author [email protected] * http://blog.****.net/rabbit729 * @version 1.0 * @date 2009-02-16 */ #ifndef PIZZASTORE_H_ #define PIZZASTORE_H_ #include "Pizza.h" class PizzaStore { public: PizzaStore(); ~PizzaStore(); public: Pizza* OrderPizza(string type); protected: virtual Pizza* CreatePizza(string type) = 0; }; class NYPizzaStore : public PizzaStore { public: Pizza* CreatePizza(string type); }; class ChicagoPizzaStore : public PizzaStore { public: Pizza* CreatePizza(string type); }; #endif /************************************************************************/ /* PizzaIngredient.cpp */ /************************************************************************/ #include "PizzaIngredient.h" string FreshClams::toString() { cout<<"Fresh Clams"<<endl; return "Fresh Clams"; } string FrozenClams::toString() { cout<<"Frozen Clams"<<endl; return "Frozen Clams"; } string MarinarSauce::toString() { cout<<"Marinara Sauce"<<endl; return "Marinara Sauce"; } string PlumTomatoSauce::toString() { cout<<"Plum Tomato Sauce"<<endl; return "Plum Tomato Sauce"; } string ThickCrustDough::toString() { cout<<"Thick Crust Dough"<<endl; return "Thick Crust Dough"; } string ThinCrustDough::toString() { cout<<"Thin Crust Dough"<<endl; return "Thin Crust Dough"; } string ReggianoCheese::toString() { cout<<"Reggiano Cheese"<<endl; return "Reggiano Cheese"; } string Mozzerella::toString() { cout<<"Mozzerella Cheese"<<endl; return "Mozzerella Cheese"; } string SlicedPepperoni::toString() { cout<<"Sliced Pepperoni"<<endl; return "Sliced Pepperoni"; } string BlackOlives::toString() { cout<<"Black Olives"<<endl; return "Black Olives"; } string EggPlant::toString() { cout<<"Egg Plant"<<endl; return "Egg Plant"; } string Garlic::toString() { cout<<"Garlic"<<endl; return "Garlic"; } string Mushroom::toString() { cout<<"Mushroom"<<endl; return "Mushroom"; } string Onion::toString() { cout<<"Onion"<<endl; return "Onion"; } string RedPepper::toString() { cout<<"Red Pepper"<<endl; return "Red Pepper"; } string Spinach::toString() { cout<<"Spinach"<<endl; return "Spinach"; } IDough* NYPizzaIngredientFactory::CreateDough() { return new ThinCrustDough(); } ISauce* NYPizzaIngredientFactory::CreateSauce() { return new MarinarSauce(); } ICheese* NYPizzaIngredientFactory::CreateCheese() { return new ReggianoCheese(); } vector<IVeggies*> NYPizzaIngredientFactory::CreateVeggies() { vector<IVeggies*> tempVeggies; IVeggies* tempVeggie = NULL; tempVeggie = new Garlic(); tempVeggies.push_back(tempVeggie); tempVeggie = new Onion(); tempVeggies.push_back(tempVeggie); tempVeggie = new Mushroom(); tempVeggies.push_back(tempVeggie); tempVeggie = new RedPepper(); tempVeggies.push_back(tempVeggie); return tempVeggies; } IPepperoni* NYPizzaIngredientFactory::CreatePepporoni() { return new SlicedPepperoni(); } IClams* NYPizzaIngredientFactory::CreateClam() { return new FreshClams(); } IDough* ChicagoPizzaIngredientFactory::CreateDough() { return new ThickCrustDough(); } ISauce* ChicagoPizzaIngredientFactory::CreateSauce() { return new PlumTomatoSauce(); } ICheese* ChicagoPizzaIngredientFactory::CreateCheese() { return new Mozzerella(); } vector<IVeggies*> ChicagoPizzaIngredientFactory::CreateVeggies() { vector<IVeggies*> tempVeggies; IVeggies* tempVeggie = NULL; tempVeggie = new BlackOlives(); tempVeggies.push_back(tempVeggie); tempVeggie = new Spinach(); tempVeggies.push_back(tempVeggie); tempVeggie = new EggPlant(); tempVeggies.push_back(tempVeggie); return tempVeggies; } IPepperoni* ChicagoPizzaIngredientFactory::CreatePepporoni() { return new SlicedPepperoni(); } IClams* ChicagoPizzaIngredientFactory::CreateClam() { return new FrozenClams(); } /************************************************************************/ /* Pizza.cpp */ /************************************************************************/ #include "Pizza.h" string Pizza::Bake() { cout<<"Bake for 25 minutes at 350 "<<endl; return "Bake for 25 minutes at 350 /n"; } string Pizza::Cut() { cout<<"Cutting the pizza into diagonal slices "<<endl; return "Cutting the pizza into diagonal slices /n"; } string Pizza::Box() { cout<<"Place pizza in official PizzaStore box "<<endl; return "Place pizza in official PizzaStore box /n"; } string Pizza::GetName() { return name; } void Pizza::SetName(string name) { this->name = name; } CheesePizza::CheesePizza(IPizzaIngredientFactory* ingredientFactory) { this->ingredientFactory = ingredientFactory; } string CheesePizza::Prepare() { dough = ingredientFactory->CreateDough(); sauce = ingredientFactory->CreateSauce(); cheese = ingredientFactory->CreateCheese(); string sb; sb.append("Preparing " + name + "/n"); sb.append(dough->toString() + "/n"); sb.append(sauce->toString() + "/n"); sb.append(cheese->toString()); cout<<sb<<endl; return sb; } ClamPizza::ClamPizza(IPizzaIngredientFactory* ingredientFactory) { this->ingredientFactory = ingredientFactory; } string ClamPizza::Prepare() { dough = ingredientFactory->CreateDough(); sauce = ingredientFactory->CreateSauce(); cheese = ingredientFactory->CreateCheese(); string sb; sb.append("Preparing " + name + "/n"); sb.append(dough->toString() + "/n"); sb.append(sauce->toString() + "/n"); sb.append(cheese->toString()); cout<<sb<<endl; return sb; } PepperoniPizza::PepperoniPizza(IPizzaIngredientFactory* ingredientFactory) { this->ingredientFactory = ingredientFactory; } string PepperoniPizza::Prepare() { dough = ingredientFactory->CreateDough(); sauce = ingredientFactory->CreateSauce(); cheese = ingredientFactory->CreateCheese(); string sb; sb.append("Preparing " + name + "/n"); sb.append(dough->toString() + "/n"); sb.append(sauce->toString() + "/n"); sb.append(cheese->toString()); cout<<sb<<endl; return sb; } /************************************************************************/ /* PizzaStore.cpp */ /************************************************************************/ #include "PizzaStore.h" PizzaStore::PizzaStore() { } PizzaStore::~PizzaStore() { } Pizza* PizzaStore::OrderPizza(string type) { Pizza* pizza; pizza = CreatePizza(type); pizza->Prepare(); pizza->Bake(); pizza->Cut(); pizza->Box(); return pizza; } Pizza* NYPizzaStore::CreatePizza(string type) { Pizza* pizza = NULL; IPizzaIngredientFactory* ingredientFactory = new NYPizzaIngredientFactory(); if (!type.compare("cheese")) { pizza = new CheesePizza(ingredientFactory); pizza->SetName("New York Style Cheese Pizza"); } else if (!type.compare("clam")) { pizza = new ClamPizza(ingredientFactory); pizza->SetName("New York Style Clam Pizza"); } else if (!type.compare("pepperoni")) { pizza = new PepperoniPizza(ingredientFactory); pizza->SetName("New York Style Pepperoni Pizza"); } return pizza; } Pizza* ChicagoPizzaStore::CreatePizza(string type) { Pizza* pizza = NULL; IPizzaIngredientFactory* ingredientFactory = new ChicagoPizzaIngredientFactory(); if (!type.compare("cheese")) { pizza = new CheesePizza(ingredientFactory); pizza->SetName("Chicago Style Cheese Pizza"); } else if (!type.compare("clam")) { pizza = new ClamPizza(ingredientFactory); pizza->SetName("Chicago Style Clam Pizza"); } else if (!type.compare("pepperoni")) { pizza = new PepperoniPizza(ingredientFactory); pizza->SetName("Chicago Style Pepperoni Pizza"); } return pizza; } /************************************************************************/ /* test.cpp */ /************************************************************************/ #include "PizzaStore.h" void main(void) { PizzaStore* nyStore = new NYPizzaStore(); PizzaStore* chicagoStore = new ChicagoPizzaStore(); Pizza* pizza = nyStore->OrderPizza("cheese"); cout<<"Ethan ordered a " + pizza->GetName()<<endl; cout<<endl; pizza = chicagoStore->OrderPizza("clam"); cout<<"Joel ordered a " + pizza->GetName()<<endl; }

程序输出:

Thin Crust Dough
Marinara Sauce
Reggiano Cheese
Preparing New York Style Cheese Pizza
Thin Crust Dough
Marinara Sauce
Reggiano Cheese
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a New York Style Cheese Pizza

Thick Crust Dough
Plum Tomato Sauce
Mozzerella Cheese
Preparing Chicago Style Clam Pizza
Thick Crust Dough
Plum Tomato Sauce
Mozzerella Cheese
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Clam Pizza
请按任意键继续. . .