《Head First 設計模式》 學習筆記,碼雲同步更新中
如有錯誤或不足之處,請一定指出,謝謝~
往期回顧
工廠方法模式(Factory Method Pattern)
- 定義:
- 工廠方法模式定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。
工廠方法讓類把實例化推遲到子類。
- 工廠方法模式定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。
- 結構:
- Factory:抽象工廠
- ConcreteFactory:具體工廠
- Product:抽象產品
- ConcreteProduct:具體產品
- 對比簡單工廠:
- 簡單工廠將對象的創建邏輯寫在工廠類裏,那麼當我們有新的對象加入時,
就需要修改工廠類的代碼。這不符合開閉原則。那如果我們定義一個抽象工廠類,
然後將具體的對象創建過程交給子類去做,當我們引進新的產品時,
只需要增加一個新的工廠類即可。顯然這是要優於簡單工廠模式的,
這就是我們所說的工廠方法模式。
- 簡單工廠將對象的創建邏輯寫在工廠類裏,那麼當我們有新的對象加入時,
- 優點:
- 隱藏產品具體實現,用戶只關心工廠,無需關心細節。
- 有新產品加入時,無需修改其他工廠和產品,只需添加新的工廠和產品。擴展性良好,完全符合“開閉原則”。
- 可結合配置文件實現對象實例化時的動態指定。
- 缺點:
- 會給系統帶來更多的類,增加複雜度和額外開銷。
- 案例:
- 先看上一節的簡單工廠:顧客點單時,需要根據菜名創建出各種不同種類的披薩。
這些披薩都源自同一個披薩基類,不過各自有自己的口味實現。
而我們創建具體的披薩對象時,只需要提供名字,不需要知道它們是如何創建的。
這時就可以用到簡單工廠,傳遞一個參數給工廠類,返回一個相應的披薩對象。 - 這時我們披薩店要擴張了,但在各個省可能會有不同的製作方法。
我們希望披薩在披薩口味上加盟店有自己的決定權。
但在製作流程上要受到總店的控制,
比如必須使用我們品牌的盒子來裝披薩等等。
- 先看上一節的簡單工廠:顧客點單時,需要根據菜名創建出各種不同種類的披薩。
- 代碼:
/**
* 披薩店超類
**/
public abstract class PizzaStore {
public Pizza orderPizza(String type) {
// 把創建披薩方法從簡單工廠拿回來
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
/**
* 將實例化披薩的責任移到抽象方法中,這個方法就等同於一個工廠
* 子類通過這個方法來執行對象實例化邏輯,達到超類和子類解耦的目的
*/
abstract Pizza createPizza(String type);
}
/**
* 上海加盟店
**/
public class SHPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
if (type.equals("cheese")) {
return new SHCheesePizza();
} else if (type.equals("veggie")) {
return new SHVeggiePizza();
}
return null;
}
}
// 其他加盟店略
/**
* 披薩超類
**/
public interface Pizza {
/**
* 準備
*/
void prepare();
/**
* 烘焙
*/
void bake();
/**
* 切片
*/
void cut();
/**
* 裝盒
*/
void box();
}
/**
* 上海芝士披薩
**/
public class SHCheesePizza implements Pizza{
@Override
public void prepare() {
}
@Override
public void bake() {
}
@Override
public void cut() {
}
@Override
public void box() {
System.out.println("上海風味芝士披薩完成...");
}
}
// 其他種類披薩略
/**
* 測試類
**/
public class Test {
public static void main(String[] args) {
// 首先需要一個上海披薩店
SHPizzaStore shPizzaStore = new SHPizzaStore();
// 然後點單
Pizza pizza = shPizzaStore.orderPizza("cheese");
}
}
結果:
上海風味芝士披薩完成...