設計模式之簡單工廠(披薩案例)
阿新 • • 發佈:2018-12-27
首先看下面程式碼:
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;
}