工廠方法模式(Factory Pattern) 【轉載】

定義

工廠方法模式定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個,工廠方法讓類把實例化推遲到子類。

 

場景

接簡單工廠模式。現在我們紐約的披薩工廠已經轉入正軌,我們打算再芝加哥再開一家披薩商店,但是兩個地區的人們對於披薩要求的口味各不相同,所以我們需要依據各地的顧客的口味添加不同的原料來製作當地人民喜歡喫的披薩。所以我們用芝加哥商店和紐約商店分別製造屬於當地口味的披薩。

 

類圖

 

c++代碼如下

 
#include <iostream>
#include <vector>
using namespace std;

class PizzaType
{
public:
    enum EPizzaType {cheese,veggie,clam,pepperoni};
    enum EPizzaStyle {NY,Chicago};
};

class Pizza 
{
public:
    virtual ~Pizza() {};
    void prepare();
    virtual void bake();
    virtual void cut();
    virtual void box();
    string getName();
protected:
    string m_sName;
    string m_sDough;
    string m_sSauce;
    vector<string> m_vToppings;
};

class NYStyleCheesePizza : public Pizza 
{
public:
    NYStyleCheesePizza();
};

class NYStyleClamPizza : public Pizza
{
public:
    NYStyleClamPizza();
};

class NYStylePepperoniPizza : public Pizza 
{
public:
    NYStylePepperoniPizza();
};

class NYStyleVeggiePizza : public Pizza
{
public:
    NYStyleVeggiePizza();
};

class ChicagoStyleCheesePizza : public Pizza
{
public: 
    ChicagoStyleCheesePizza();
    void cut();
};

class ChicagoStyleClamPizza : public Pizza
{
public:
    ChicagoStyleClamPizza();
    void cut();
};

class ChicagoStylePepperoniPizza : public Pizza
{
public:
    ChicagoStylePepperoniPizza();    
    void cut();
};

class ChicagoStyleVeggiePizza : public Pizza
{
public:
    ChicagoStyleVeggiePizza();
    void cut();
};

class PizzaStore 
{
public:
    virtual Pizza* createPizza(PizzaType::EPizzaType type) = 0;
    Pizza* orderPizza(PizzaType::EPizzaType type);
};

class NYPizzaStore : public PizzaStore
{
public:
    Pizza* createPizza(PizzaType::EPizzaType type);
};

class ChicagoPizzaStore : public PizzaStore
{
public:
    Pizza* createPizza(PizzaType::EPizzaType type);
};

class DependentPizzaStore
{
public:
    Pizza* createPizza(PizzaType::EPizzaStyle style, PizzaType::EPizzaType type);
};

void Pizza::prepare() 
{
    printf("Preparing %s\n",m_sName.c_str());
    printf("Tossing dough %s\n",m_sDough.c_str());
    printf("Adding sauce %s\n",m_sSauce.c_str());
    printf("Adding toppings: ");
    for (unsigned int i=0; i<m_vToppings.size(); ++i) {
        printf("   %s",m_vToppings.at(i).c_str());
    }
    printf("\n");
}

void Pizza::bake() 
{
    printf("Bake for 25 minutes at 350\n");
}

void Pizza::cut() 
{
    printf("Cutting the pizza into diagonal slices\n");
}

void Pizza::box() 
{
    printf("Place pizza in official PizzaStore box\n");
}

string Pizza::getName() 
{
    return m_sName;
}

NYStyleCheesePizza::NYStyleCheesePizza()
{ 
    m_sName = "NY Style Sauce and Cheese Pizza";
    m_sDough = "Thin Crust Dough";
    m_sSauce = "Marinara Sauce";
    m_vToppings.push_back("Grated Reggiano Cheese");
}

NYStyleClamPizza::NYStyleClamPizza()
{
    m_sName = "NY Style Clam Pizza";
    m_sDough = "Thin Crust Dough";
    m_sSauce = "Marinara Sauce";
    m_vToppings.push_back("Grated Reggiano Cheese");
    m_vToppings.push_back("Fresh Clams from Long Island Sound");
}

NYStylePepperoniPizza::NYStylePepperoniPizza()
{
    m_sName = "NY Style Pepperoni Pizza";
    m_sDough = "Thin Crust Dough";
    m_sSauce = "Marinara Sauce";
    m_vToppings.push_back("Grated Reggiano Cheese");
    m_vToppings.push_back("Sliced Pepperoni");
    m_vToppings.push_back("Garlic");
    m_vToppings.push_back("Onion");
    m_vToppings.push_back("Mushrooms");
    m_vToppings.push_back("Red Pepper");
}

NYStyleVeggiePizza::NYStyleVeggiePizza()
{
    m_sName = "NY Style Veggie Pizza";
    m_sDough = "Thin Crust Dough";
    m_sSauce = "Marinara Sauce";
    m_vToppings.push_back("Grated Reggiano Cheese");
    m_vToppings.push_back("Garlic");
    m_vToppings.push_back("Onion");
    m_vToppings.push_back("Mushrooms");
    m_vToppings.push_back("Red Pepper");
}

ChicagoStyleCheesePizza::ChicagoStyleCheesePizza()
{ 
    m_sName = "Chicago Style Deep Dish Cheese Pizza";
    m_sDough = "Extra Thick Crust Dough";
    m_sSauce = "Plum Tomato Sauce";
    m_vToppings.push_back("Shredded Mozzarella Cheese");
}
void ChicagoStyleCheesePizza::cut()
{
    printf("Cutting the pizza into square slices\n");
}

ChicagoStyleClamPizza::ChicagoStyleClamPizza()
{
    m_sName = "Chicago Style Clam Pizza";
    m_sDough = "Extra Thick Crust Dough";
    m_sSauce = "Plum Tomato Sauce";
    m_vToppings.push_back("Shredded Mozzarella Cheese");
    m_vToppings.push_back("Frozen Clams from Chesapeake Bay");
}
void ChicagoStyleClamPizza::cut()
{
    printf("Cutting the pizza into square slices\n");
}

ChicagoStylePepperoniPizza::ChicagoStylePepperoniPizza()
{
    m_sName = "Chicago Style Pepperoni Pizza";
    m_sDough = "Extra Thick Crust Dough";
    m_sSauce = "Plum Tomato Sauce";
    m_vToppings.push_back("Shredded Mozzarella Cheese");
    m_vToppings.push_back("Black Olives");
    m_vToppings.push_back("Spinach");
    m_vToppings.push_back("Eggplant");
    m_vToppings.push_back("Sliced Pepperoni");
}    
void ChicagoStylePepperoniPizza::cut()
{
    printf("Cutting the pizza into square slices\n");
}

ChicagoStyleVeggiePizza::ChicagoStyleVeggiePizza()
{
    m_sName = "Chicago Deep Dish Veggie Pizza";
    m_sDough = "Extra Thick Crust Dough";
    m_sSauce = "Plum Tomato Sauce";
    m_vToppings.push_back("Shredded Mozzarella Cheese");
    m_vToppings.push_back("Black Olives");
    m_vToppings.push_back("Spinach");
    m_vToppings.push_back("Eggplant");
}
void ChicagoStyleVeggiePizza::cut()
{
    printf("Cutting the pizza into square slices\n");
}

Pizza* PizzaStore::orderPizza(PizzaType::EPizzaType type)
{
    Pizza* pizza = createPizza(type);
    printf("--- Making a %s ---\n" ,pizza->getName().c_str());
    pizza->prepare();
    pizza->bake();
    pizza->cut();
    pizza->box();
    return pizza;
}

Pizza* NYPizzaStore::createPizza(PizzaType::EPizzaType type)
{
    if (PizzaType::cheese == type)
    {
        return new NYStyleCheesePizza();
    }
    else if (PizzaType::veggie == type)
    {
        return new NYStyleVeggiePizza();
    }
    else if (PizzaType::clam == type)
    {
        return new NYStyleClamPizza();
    }
    else if (PizzaType::pepperoni == type)
    {
        return new NYStylePepperoniPizza();
    }
    return NULL;
}

Pizza* ChicagoPizzaStore::createPizza(PizzaType::EPizzaType type)
{
    if (PizzaType::cheese == type)
    {
        return new ChicagoStyleCheesePizza();
    }
    else if (PizzaType::veggie == type)
    {
        return new ChicagoStyleVeggiePizza();
    }
    else if (PizzaType::clam == type)
    {
        return new ChicagoStyleClamPizza();
    }
    else if (PizzaType::pepperoni == type)
    {
        return new ChicagoStylePepperoniPizza();
    }
    return NULL;
}

Pizza* DependentPizzaStore::createPizza(PizzaType::EPizzaStyle style, PizzaType::EPizzaType type)
{
    Pizza* pizza = NULL;
    if (PizzaType::NY == style)
    {
        if (PizzaType::cheese == type)
        {
            pizza = new NYStyleCheesePizza();
        }
        else if (PizzaType::veggie == type)
        {
            pizza = new NYStyleVeggiePizza();
        }
        else if (PizzaType::clam == type)
        {
            pizza = new NYStyleClamPizza();
        }
        else if (PizzaType::pepperoni == type)
        {
            pizza = new NYStylePepperoniPizza();
        }
    } 
    else if (PizzaType::Chicago == style)
    {
        if (PizzaType::cheese == type)
        {
            pizza = new ChicagoStyleCheesePizza();
        }
        else if (PizzaType::veggie == type)
        {
            pizza = new ChicagoStyleVeggiePizza();
        }
        else if (PizzaType::clam == type)
        {
            pizza = new ChicagoStyleClamPizza();
        }
        else if (PizzaType::pepperoni == type)
        {
            pizza = new ChicagoStylePepperoniPizza();
        }
    }
    pizza->prepare();
    pizza->bake();
    pizza->cut();
    pizza->box();
    return pizza;
}

int main()
{
    NYPizzaStore nyStore;
    ChicagoPizzaStore chicagoStore;
    Pizza* pizza = NULL;

    pizza = nyStore.orderPizza(PizzaType::cheese);
    printf("Ethan ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = chicagoStore.orderPizza(PizzaType::cheese);
    printf("Joel ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = nyStore.orderPizza(PizzaType::clam);
    printf("Ethan ordered a %s\n", pizza->getName().c_str());
    delete pizza;

    pizza = chicagoStore.orderPizza(PizzaType::clam);
    printf("Joel ordered a %s\n", pizza->getName().c_str());
    delete pizza;

    pizza = nyStore.orderPizza(PizzaType::pepperoni);
    printf("Ethan ordered a %s\n", pizza->getName().c_str());
    delete pizza;

    pizza = chicagoStore.orderPizza(PizzaType::pepperoni);
    printf("Joel ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = nyStore.orderPizza(PizzaType::veggie);
    printf("Ethan ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = chicagoStore.orderPizza(PizzaType::veggie);
    printf("Joel ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    return 0;
}

 

 

運行結果如下:

--- Making a NY Style Sauce and Cheese Pizza ---
Preparing NY Style Sauce and Cheese Pizza
Tossing dough Thin Crust Dough
Adding sauce Marinara Sauce
Adding toppings: Grated Reggiano Cheese
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a NY Style Sauce and Cheese Pizza
--- Making a Chicago Style Deep Dish Cheese Pizza ---
Preparing Chicago Style Deep Dish Cheese Pizza
Tossing dough Extra Thick Crust Dough
Adding sauce Plum Tomato Sauce
Adding toppings: Shredded Mozzarella Cheese
Bake for 25 minutes at 350
Cutting the pizza into square slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Deep Dish Cheese Pizza
--- Making a NY Style Clam Pizza ---
Preparing NY Style Clam Pizza
Tossing dough Thin Crust Dough
Adding sauce Marinara Sauce
Adding toppings: Grated Reggiano Cheese Fresh Clams from Long Island Sound
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a NY Style Clam Pizza
--- Making a Chicago Style Clam Pizza ---
Preparing Chicago Style Clam Pizza
Tossing dough Extra Thick Crust Dough
Adding sauce Plum Tomato Sauce
Adding toppings: Shredded Mozzarella Cheese Frozen Clams from Chesapeake Ba
y
Bake for 25 minutes at 350
Cutting the pizza into square slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Clam Pizza
--- Making a NY Style Pepperoni Pizza ---
Preparing NY Style Pepperoni Pizza
Tossing dough Thin Crust Dough
Adding sauce Marinara Sauce
Adding toppings: Grated Reggiano Cheese Sliced Pepperoni Garlic Onion
Mushrooms Red Pepper
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a NY Style Pepperoni Pizza
--- Making a Chicago Style Pepperoni Pizza ---
Preparing Chicago Style Pepperoni Pizza
Tossing dough Extra Thick Crust Dough
Adding sauce Plum Tomato Sauce
Adding toppings: Shredded Mozzarella Cheese Black Olives Spinach Eggpla
nt Sliced Pepperoni
Bake for 25 minutes at 350
Cutting the pizza into square slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Pepperoni Pizza
--- Making a NY Style Veggie Pizza ---
Preparing NY Style Veggie Pizza
Tossing dough Thin Crust Dough
Adding sauce Marinara Sauce
Adding toppings: Grated Reggiano Cheese Garlic Onion Mushrooms Red Pe
pper
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a NY Style Veggie Pizza
--- Making a Chicago Deep Dish Veggie Pizza ---
Preparing Chicago Deep Dish Veggie Pizza
Tossing dough Extra Thick Crust Dough
Adding sauce Plum Tomato Sauce
Adding toppings: Shredded Mozzarella Cheese Black Olives Spinach Eggpla
nt
Bake for 25 minutes at 350
Cutting the pizza into square slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Deep Dish Veggie Pizza

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章