一、簡單工廠模式
1、原理
創(chuàng)建一個(gè)工廠類,提供一個(gè)創(chuàng)建對象方法,根據(jù)傳參判斷返回哪一個(gè)產(chǎn)品,各種產(chǎn)品應(yīng)屬于同一類,實(shí)現(xiàn)或繼承自同一個(gè)接口或抽象類。
2、UML類圖

3、示例代碼
public class SimplePizzaFactory {
private static Pizza mPizza;
public static Pizza createPizza(String type){
switch (type){
case "cheese":
mPizza = new CheesePizza();
break;
case "greak":
mPizza = new GreakPizza();
break;
}
mPizza.make();
return mPizza;
}
}
4、特點(diǎn)
- 外部調(diào)用相關(guān)方法,根據(jù)不同類別返回不同實(shí)例,外部調(diào)用者不需要去做區(qū)分,降低了客戶端和創(chuàng)建過程中其他類的耦合,符合迪米特原則;
- 工廠類違反開閉原則,當(dāng)系統(tǒng)需要拓展第三種口味的Pizza時(shí),需要對工廠類做出修改,隨著項(xiàng)目拓展,工廠類變得臃腫,不便于后期維護(hù)。
二、工廠方法模式
1、原理
因?yàn)楹唵喂S模式中違反了開閉原則,所以工廠方法模式中對工廠類進(jìn)行抽象化,不同工廠子類生產(chǎn)對應(yīng)的產(chǎn)品,當(dāng)系統(tǒng)拓展的時(shí)候新增相應(yīng)的產(chǎn)品工廠,不需要再去對已有的工廠類進(jìn)行修改,使系統(tǒng)滿足了開閉原則。
2、UML類圖

3、示例代碼
public class CheesePizzaFactory extends PizzaFactory{
@Override
protected Pizza createPizza() {
CheesePizza pizza = new CheesePizza();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
public class GreakPizzaFactory extends PizzaFactory{
@Override
protected Pizza createPizza() {
GreakPizza pizza = new GreakPizza();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
4、特點(diǎn)
- 將簡單工廠模式中工廠類抽象化,定義一個(gè)抽象工廠基類,工廠子類具體實(shí)現(xiàn)產(chǎn)品對象的創(chuàng)建細(xì)節(jié),當(dāng)有新的產(chǎn)品需要?jiǎng)?chuàng)建時(shí),新建其對應(yīng)的工廠類即可。
- 每個(gè)工廠子類只能生產(chǎn)一種產(chǎn)品,當(dāng)產(chǎn)品過多時(shí),工廠類也會(huì)增多,且工廠類實(shí)現(xiàn)都差不多,系統(tǒng)復(fù)雜度也上升。
三、抽象工廠模式
1、原理
為解決工廠方法模式中一個(gè)工廠類只能生產(chǎn)一種產(chǎn)品導(dǎo)致的類數(shù)量增多,系統(tǒng)復(fù)雜度提升問題,抽象工廠模式是一個(gè)工廠類可以生產(chǎn)多種產(chǎn)品。
2、UML類圖

3、代碼實(shí)例
public class BJPizzaFactory extends AbstractPizzaFactory{
@Override
protected AbstractPizza createCheesePizza() {
BJCheesePizza cheesePizza = new BJCheesePizza();
cheesePizza.bake();
cheesePizza.cut();
cheesePizza.box();
return cheesePizza;
}
@Override
protected AbstractPizza createGreakPizza() {
BJGreakPizza cheesePizza = new BJGreakPizza();
cheesePizza.bake();
cheesePizza.cut();
cheesePizza.box();
return cheesePizza;
}
}
public class SHPizzaFactory extends AbstractPizzaFactory{
@Override
protected AbstractPizza createCheesePizza() {
SHCheesePizza cheesePizza = new SHCheesePizza();
cheesePizza.bake();
cheesePizza.cut();
cheesePizza.box();
return cheesePizza;
}
@Override
protected AbstractPizza createGreakPizza() {
SHGreakPizza cheesePizza = new SHGreakPizza();
cheesePizza.bake();
cheesePizza.cut();
cheesePizza.box();
return cheesePizza;
}
}
4、特點(diǎn)
一個(gè)工廠子類可以生產(chǎn)多種同類商品,系統(tǒng)在工廠級別上能很好的拓展,新建工廠子類繼承基類即可,但當(dāng)在產(chǎn)品級別上需要拓展時(shí),需要去更改整個(gè)系統(tǒng),包括基類中定義相關(guān)的創(chuàng)建方法返回新的產(chǎn)品類型對象,此時(shí)來看,不符合開閉原則,所以當(dāng)一個(gè)系統(tǒng)中產(chǎn)品比較穩(wěn)定的時(shí)候用這種方法比較好。
總結(jié)
簡單工廠模式->工廠方法模式->抽象工廠模式依次改進(jìn)得到,為了解決簡單工廠模式中工廠類違反開閉原則的問題,工廠方法模式抽象化工廠類,使得不同的產(chǎn)品由不同的工廠類生產(chǎn),這樣當(dāng)系統(tǒng)需要拓展新的產(chǎn)品時(shí)新建相關(guān)的工廠類即可,但解決了開閉原則問題的同時(shí)又衍生出新的問題,工廠方法模式中每個(gè)工廠類只能生產(chǎn)一種產(chǎn)品,當(dāng)系統(tǒng)中產(chǎn)品很多時(shí),工廠類也相應(yīng)增加,系統(tǒng)復(fù)雜度提升,為了解決這一問題,抽象工廠模式通過一個(gè)工廠類生產(chǎn)多種產(chǎn)品的模式去實(shí)現(xiàn),這樣要求在定義工廠基類時(shí)就需要定義好創(chuàng)建相關(guān)產(chǎn)品的方法,即工廠能生產(chǎn)哪些產(chǎn)品在一開始就定義好了,工廠子類只是去實(shí)現(xiàn)具體細(xì)節(jié),這樣導(dǎo)致了在工廠層面上能夠很好拓展,在產(chǎn)品層面上還是違反了開閉原則,新的產(chǎn)品來臨時(shí),需要在基類中去定義創(chuàng)建產(chǎn)品的方法,從上到下整個(gè)系統(tǒng)都得修改,所以對產(chǎn)品層面的拓展不友好,一般當(dāng)系統(tǒng)產(chǎn)品穩(wěn)定的情況推薦使用抽象工廠模式。