close
簡單工廠模式 ( Simple Factory Pattern )
簡單的工廠模式算是最基本的工廠模式,經常使用到,也可以把這當成是一種編程習慣,這一個範例我們使用披薩店來說明。
假設,有一間披薩店在裡面賣各式各樣的Pizza,如果有人點了夏威夷口味的披薩,我們就準備夏威夷的披薩,然後送入烤箱→拿給消費者。
#include
#include
using namespace std;
class Pizza
{
public:
string m_name;
void bake(){ cout << m_name << "進行烘烤" << endl; }
void deliver(){ cout << m_name << "進行運送" << endl; }
};
class HawaiiPizza : public Pizza
{
public:
HawaiiPizza(){ m_name = "Hawaii"; }
};
class TunaPizza : public Pizza
{
public:
TunaPizza(){ m_name = "Tuna"; }
};
Pizza *orderPizza(string name)
{
/*
補充: Pizza * orderPizza 的意思是指:
返回一個Pizza的指針
*/
Pizza *ret = NULL;
if (name == "Hawaii"){
ret = new HawaiiPizza();
}
if (name == "Tuna"){
ret = new TunaPizza();
}
ret->bake();
ret->deliver();
return ret;
}
int main()
{
Pizza *myHawaiiPizza = orderPizza("Hawaii");
Pizza *myTunaPizza = orderPizza("Tuna");
delete myHawaiiPizza;
delete myTunaPizza;
return 0;
}
在上面的程式範例中,orderPizza()函式內部依參數來實體化類別,所以當增加口味更改時,修改orderPizza()函式是不可避免的,但我們已經知道會修改甚麼地方,可以將會變動的地方取出並封裝,下面使用PizzaFactory類別來處理披薩的產生,而PizzaStore類別負責披薩產生的後續處理。
#include
#include
using namespace std;
class Pizza{
public:
string m_name;
void bake(){cout << m_name << "進行烘烤" << endl;}
void delever(){cout << m_name << "進行運送" << endl;}
};
class HawaiiPizza : public Pizza{
public:
HawaiiPizza(){m_name="Hawaii pizza";}
};
class TunaPizza : public Pizza{
public:
TunaPizza(){m_name="Tuna pizza";}
};
class PizzaFactory{
public:
Pizza *createPizza(string name);
};
Pizza *PizzaFactory::createPizza(string name){
Pizza *ret;
if(name=="Hawaii"){
ret = new HawaiiPizza();
}
if(name=="Tuna"){
ret = new TunaPizza();
}
return ret;
}
class PizzaStore{
private:
PizzaFactory m_PizzaFactory;
public:
PizzaStore(PizzaFactory factory){m_PizzaFactory=factory;}
Pizza *orderPizza(string name);
};
Pizza *PizzaStore::orderPizza(string name){
Pizza *ret = m_PizzaFactory.createPizza(name);
ret->bake();
ret->deliver();
return ret;
}
int main() {
PizzaFactory myPizzaFactory;
PizzaStore myPizzaStore(myPizzaFactory);
Pizza *myHawaiiPizza = myPizzaStore.orderPizza("Hawaii");
Pizza *myTunaPizza = myPizzaStore.orderPizza("Tuna");
delete myHawaiiPizza;
delete myTunaPizza;
return 0;
}
上述例子用單一工廠,產生所有的可能類別實例,下面用類似的方式,但是讓每個產品都有各自的工廠,當產品有新增時,上述例子必須要修改工廠方法,下面方法則是增加一個新的工廠子類別,如此較符合開放封閉原則,但有會產生大量工廠子類別的缺點。
我們用HawaiiPizzaFactory和TunaPizzaFactory類別取代原本的PizzaFactory的功能,以下為程式碼。
#include
#include
using namespace std;
class Pizza{
public:
string m_name;
void bake(){cout << m_name << "進行烘烤" << endl;}
void delever(){cout << m_name << "進行運送" << endl;}
};
class HawaiiPizza : public Pizza{
public:
HawaiiPizza(){m_name="Hawaii pizza";}
};
class TunaPizza : public Pizza{
public:
TunaPizza(){m_name="Tuna pizza";}
};
class PizzaFactory{
public:
virtual Pizza *createPizza() = 0;
};
class HawaiiPizzaFactory : public PizzaFactory{
public:
Pizza *createPizza();
};
class TunaPizzaFactory : public PizzaFactory{
public:
Pizza *createPizza();
};
Pizza *HawaiiPizzaFactory::createPizza(){
Pizza *ret = new HawaiiPizza();
return ret;
}
Pizza *TunaPizzaFactory::createPizza(){
Pizza *ret = new TunaPizza();
return ret;
}
class PizzaStore{
private:
PizzaFactory *m_PizzaFactory;
public:
PizzaStore(PizzaFactory *factory){m_PizzaFactory=factory;}
void setFlavor(PizzaFactory *factory){m_PizzaFactory=factory;}
Pizza *orderPizza();
};
Pizza *PizzaStore::orderPizza(){
Pizza *ret = m_PizzaFactory->createPizza();
ret->bake();
ret->ship();
return ret;
}
int main() {
HawaiiPizzaFactory myHawaiiFactory;
PizzaStore myPizzaStore(&myHawaiiFactory);
Pizza *myHawaiiPizza = myPizzaStore.orderPizza();
TunaPizzaFactory myTunaFactory;
myPizzaStore.setFlavor(&myTunaFactory);
Pizza *myTunaPizza = myPizzaStore.orderPizza();
delete myHawaiiPizza;
delete myTunaPizza;
return 0;
}
文章標籤
全站熱搜
留言列表