1. 程式人生 > >設計模式之簡單工廠(披薩案例)

設計模式之簡單工廠(披薩案例)

首先看下面程式碼:

Duck duck = new MallardDuck();

分析:我們採用new來例項化具體類,用的是實現,而非介面,程式碼捆綁具體類導致程式碼脆弱,缺乏彈性。

倘若Duck種類變多時:

Duck duck;

if(picnic){
    duck = new MallardDuck();
}else if(hunting){
    duck = new DecoyDuck();
}else if(inBathTub){
    duck = new RubberDuck();
}

分析:我們發現,一旦有變化或擴充套件,就必須重新開啟這段程式碼進行檢查和修改,通常這樣修改過的程式碼將造成部分系統更難維護和更新,而且也更容易犯錯誤。

基於上述分析:我們要做到:“對擴充套件開放,對修改關閉”!

我們發現,披薩的準備,烘烤,切片,裝盒對於所有型別的披薩都是不變的,而披薩種類的選擇則是變化的部分,弄清了變化與不變化的部分,我們就要使用變化分離原則了,即我們要對變化的部分實現封裝,將不變化的部分放入基類中讓子類繼承即可。

變化的部分所在的類(披薩生產種類選擇),我們稱為(比薩生產的)工廠。
不變化的部分,我們稱為客戶。

工廠如下:(java實現)

public class SimplePizzaFactory{
public Pizza createPizza(String type){
    Pizza pizza = null
; if(type.equals("cheese")){ pizza = new CheesePizza(); }else if(type.equals("clam")){ pizza = new ClamPizza(); }else if(type.equals("veggie")){ pizza = new VeggiePizza(); } return pizza; } }

重做PizzaStore類如下:(java實現)

public class PizzaStore{
    SimplePizzaFactory factory;
public
PizzaStore(SimplePizzaFactory factory){ this.factory = factory; } public Pizza orderPizza(String type){ Pizza pizza; pizza = factory.creatPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }

簡單工廠其實並不是一個設計模式,反而比較像是一種程式設計習慣,它並沒有引出什麼新的設計原則,依然是在我們之前所說的變化分離原則,針對介面而不針對實現程式設計原則,少用繼承多用組合原則,低耦合性的條件下來實現的,基於如此,我們就不多說了,類圖也就不寫了,直接上程式碼,類圖實現過程等大家自行腦補吧,哈哈,接下來的博文我將繼續寫更加高深的工廠模式以及新的設計原則,請大家關注。

下面為披薩案例的C++實現:

#include<iostream>
using namespace std;
class Pizza
{
private:
    string m_type;
public:
    Pizza(string _m_type):m_type(_m_type) {}
    virtual ~Pizza() {}
    virtual void prepare()
    {
        cout<<"prepare "<<m_type<<endl;
    }
    virtual void bake()
    {
        cout<<"bake "<<m_type<<endl;
    }
    virtual void cut()
    {
        cout<<"cut "<<m_type<<endl;
    }
    virtual void box()
    {
        cout<<"box "<<m_type<<endl;
    }
};
class ChiChagoCheesePizza:public Pizza
{
public:
    ChiChagoCheesePizza():Pizza("chichago cheese") {}
    ~ChiChagoCheesePizza() {}
};
class ChiChagoGreekPizza : public Pizza
{
public:
    ChiChagoGreekPizza() : Pizza("chichago greek") {}
    ~ChiChagoGreekPizza() {}
};
class NYCheesePizza : public Pizza
{
public:
    NYCheesePizza() : Pizza("ny cheese") {}
    ~NYCheesePizza() {}
};
class NYGreekPizza : public Pizza
{
public:
    NYGreekPizza() : Pizza("ny greek") {}
    ~NYGreekPizza() {}
};
class SimplePizzaFactory
{
public:
    virtual Pizza *CreatePizza(const std::string &type) = 0;
};
class ChiChagoPizzaFactory : public SimplePizzaFactory
{
public:
    Pizza *CreatePizza(const std::string &type)
    {
        if ( "cheese" == type )
        {
            return new ChiChagoCheesePizza();
        }
        if ( "greek" == type )
        {
            return new ChiChagoGreekPizza();
        }
        return NULL;
    }
};
class NYPizzaFactory : public SimplePizzaFactory
{
public:
    Pizza *CreatePizza(const std::string &type)
    {
        if ( "cheese" == type )
        {
            return new NYCheesePizza();
        }
        if ( "greek" == type )
        {
            return new NYGreekPizza();
        }
        return NULL;
    }
};
class PizzaStore
{
private:
    SimplePizzaFactory &m_pizza_factory;
public:
    PizzaStore(SimplePizzaFactory &pizza_factory) : m_pizza_factory(pizza_factory) {}
    Pizza* OrderPizza(const std::string &type)
    {
        Pizza *p_pizza = m_pizza_factory.CreatePizza(type);
        if (p_pizza)
        {
            p_pizza->prepare();
            p_pizza->bake();
            p_pizza->cut();
            p_pizza->box();
        }
        return p_pizza;
    }
};
int main()
{
    NYPizzaFactory ny_pizza_factory;
    PizzaStore pizza_store(ny_pizza_factory);
    Pizza *p_pizza = pizza_store.OrderPizza("greek");
    if ( p_pizza )
    {
        delete p_pizza;
    }
    return 0;
}