適用問題:
試想我們要依使用者需求來實體化物件,可能會需要寫像下面這樣的code:
Pizza orderPizza(string type){
Pizza pizza;
if (type=="cheese"){
pizza = new CheesePizza();
}else if (type=="greek")
pizza = new GreekPizza();
}else if (type=="pepperoni"){
pizza = new PepperoniPizza();
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
基於type的輸入來決定要實體化哪種類別,但這樣的寫法在增減類別時,顯然不太符合 "closed for modification",我們要加上新口味的比薩時,又要修改此段程式增加新的if。比較好的寫法是我們應該要將這段實體化類別程式另外作包裝,而這也正是工廠模式的作法。
工廠模式可以分作三種:
1. 簡單工廠模式 Simple Factory Pattern
2. 工廠方法模式 Factory Method Pattern
3. 抽象工廠模式 Abstract Factory Pattern
下面我們將依序介紹。
簡單工廠模式例子:
承接上面比薩的例子,我們將實體化類別的部分另外包裝成一個SimplePizzaFactory類別,裡面有createPizza()這個函式。
PizzaSore code:比薩店實體化時要指定使用哪個SimplePizzaFactory
public class PizzaStore{
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory){
this.factory = factory;
}
public Pizza orderPizza(String type){
Pizza pizza;
pizza = factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
// other methods here
}
public class SimplePizzaFactory{
public Pizza createPizza(String type){
Pizza pizza = null;
if (type=="cheese"){
pizza = new CheesePizza();
}else if (type=="greek")
pizza = new GreekPizza();
}else if (type=="pepperoni"){
pizza = new PepperoniPizza();
}
return pizza
}
}
P.S. <<Head First Design Patterns>>這本書認為簡單工廠並非Design Pattern而是一種寫程式的風格(programming idiom)。
若我們現在想有不一樣的比薩配方呢?即我們的店有自己特色,賣的比薩有不一樣的口味。
工廠方法模式定義:
"The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclass." (定義一個用於建立物件的介面,讓子類決定實體化哪個類別,工廠方法使一個類別的實例化延遲到其子類別)
工廠方法模式UML:
工廠方法模式例子:
建立PizzaStore再由繼承其的子類來實現factoryMethod(),如此我們要增加不同口味的比薩時就不需要修改原本的類別,只要新增類別就可。
public abstract class PizzaStore{
public Pizza orderPizza(string type){
Pizza pizza;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
protected abstract createPizza(string type);
}
public class NYPizzaStore: public PizzaStore{
Pizza createPizza(string item){
if (type=="cheese"){
return new NYStyleCheesePizza();
}else if (type=="greek")
return new NYStyleGreekPizza();
}else if (type=="pepperoni"){
return new NYStylePepperoniPizza();
}else{
return null;
}
}
}
抽象工廠模式定義:
"The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes" (抽象工廠模式提供一個建立一系列相關或相互依賴物件的介面,而無須指定他們具體的類別)
抽象工廠模式UML:
參考資料:
1. Head First Design Patterns
沒有留言:
張貼留言