首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 設計模式精講:工廠模式三部曲——簡單工廠、工廠方法、抽象工廠全解析

     編輯:Java 綜合教學

引言:從「磚瓦廠」到「汽車裝配線」的演進

工廠模式是創建型模式中最基礎、應用最廣的模式之一。本文通過「手機生產」與「手機組件組裝」兩條主線,層層遞進講解 簡單工廠、工廠方法、抽象工廠 三種模式的結構、代碼實現、優缺點對比及選型指南。

一、簡單工廠模式:一個「萬能車間」

1. 核心思想

一個工廠類根據傳入參數決定創建哪種具體產品。產品種類固定,新增產品必須修改工廠源碼,違反「開閉原則」。

2. 代碼實現

// 產品接口
public interface Cellphone { void call(); }

// 具體產品
public class IPhone implements Cellphone { public void call() { System.out.println("iPhone 通話"); } }
public class Samsung implements Cellphone { public void call() { System.out.println("Samsung 通話"); } }

// 簡單工廠(靜態工廠方法)
public class SimplePhoneFactory {
    public static Cellphone getCellphone(String type) {
        if ("iPhone".equalsIgnoreCase(type)) return new IPhone();
        else if ("Samsung".equalsIgnoreCase(type)) return new Samsung();
        else throw new RuntimeException("不支援的手機類型: " + type);
    }
}

// 客戶端
Cellphone phone = SimplePhoneFactory.getCellphone("iPhone");
phone.call();

3. 優缺點

  • ✅ 結構簡單,客戶端無需知道具體類名
  • ❌ 新增產品需修改工廠類,違反開閉原則
  • ❌ 工廠類職責過重,維護困難

二、工廠方法模式:專業化的「專屬車間」

1. 核心思想

定義一個創建對象的接口,由子類決定實例化哪個類。每個產品對應一個具體工廠,新增產品只需新增工廠類,符合開閉原則。

2. 代碼實現

// 抽象工廠接口
public interface PhoneFactory {
    Cellphone getPhone();
}

// 具體工廠
public class IPhoneFactory implements PhoneFactory {
    public Cellphone getPhone() { return new IPhone(); }
}
public class SamsungFactory implements PhoneFactory {
    public Cellphone getPhone() { return new Samsung(); }
}
// 新增小米只需加 MIPhoneFactory,無需動原有代碼

// 客戶端
PhoneFactory factory = new IPhoneFactory(); // 或通過配置/反射獲取
Cellphone phone = factory.getPhone();

3. 優缺點

  • ✅ 符合開閉原則,擴展性強
  • ✅ 結構清晰,職責分離
  • ❌ 類數量激增(每個產品一個工廠),結構相對複雜
  • ❌ 客戶端需知道具體工廠類

三、抽象工廠模式:組裝「產品族」的「總裝車間」

1. 核心思想

針對產品族(多個相關/依賴的產品等級結構),提供一個接口創建一系列相關對象,無需指定具體類。解決「單一產品」模式無法解決的「組合型產品」創建問題。

2. 代碼實現:手機 = CPU + 相機 + 內存

// === 抽象產品 ====================================================
public interface CPU { void run(); void start(); }
public interface Camera { void take(); }
public interface Memory { void work(); }

// === 具體產品(高端/低端兩個產品族) =============================
class GoodCPU implements CPU { ... }
class BadCPU implements CPU { ... }
class GoodCamera implements Camera { ... }
class BadCamera implements Camera { ... }
class GoodMemory implements Memory { ... }
class BadMemory implements Memory { ... }

// === 抽象工廠 ====================================================
public interface AbPhoneFactory {
    CPU getCPU();
    Camera getCamera();
    Memory getMemory();
}

// === 具體工廠(組裝產品族) ======================================
public class GoodPhoneFactory implements AbPhoneFactory {
    public CPU getCPU() { return new GoodCPU(); }
    public Camera getCamera() { return new GoodCamera(); }
    public Memory getMemory() { return new GoodMemory(); }
}
public class BadPhoneFactory implements AbPhoneFactory {
    public CPU getCPU() { return new BadCPU(); }
    public Camera getCamera() { return new BadCamera(); }
    public Memory getMemory() { return new BadMemory(); }
}
// 中端組合只需新增 MidPhoneFactory

// 客戶端
AbPhoneFactory factory = new GoodPhoneFactory(); // 高端旗艦機
CPU cpu = factory.getCPU();
Camera cam = factory.getCamera();
Memory mem = factory.getMemory();
// 組裝手機...

3. 關鍵點

  • 抽象工廠定義多個創建方法,每個方法對應一個抽象產品
  • 具體工廠實現完整產品族的創建邏輯
  • 客戶端面向抽象工廠編程,運行時決定使用哪個具體工廠(高端/低端/中端)

四、三大模式深度對比與選型指南

維度簡單工廠工廠方法抽象工廠
解決問題單一產品創建單一產品創建(可擴展)產品族創建(多等級結構)
結構複雜度⭐ 低⭐⭐ 中⭐⭐⭐ 高
代碼複雜度低中高
客戶端編程難度低(只知參數)中(知具體工廠)中(知抽象工廠)
管理難度低(一個類)中(多工廠類)高(多產品+多工廠)
開閉原則❌ 違反✅ 符合✅ 符合(增加產品族)
適用場景產品少、固定、不常擴展單一產品、頻繁擴展多相關產品、需保證族內一致性

五、實戰選型建議

  1. 產品種類固定、極少變動:果斷用 簡單工廠,不要過度設計。
  2. 單一產品但需頻繁擴展新類型:工廠方法是標準選擇,符合開閉原則。
  3. 涉及多個相關產品(如 UI 皮膚:按鈕+輸入框+彈窗,或手機:CPU+屏+電池):必須用抽象工廠,其他兩種模式無法優雅解決「族內一致性」問題。
  4. 實際項目中:簡單工廠因極簡易用,使用率反而最高;抽象工廠常見於框架底層(如 JDBC 的 DriverManager、MyBatis 的 Environment 構建)。

六、完整代碼倉庫

GitHub 完整項目:https://github.com/LiuJishuai/designPatterns

結語

工廠模式三部曲體現了軟件設計從「簡單直接」到「解耦擴展」再到「族級協作」的演進邏輯。沒有銀彈,只有在具體業務場景下最合適的選擇。理解三者本質區別——創建什麼(單一 vs 族)、誰負責創建(集中 vs 分散)、如何擴展(修改 vs 新增),才能在實戰中游刃有餘。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved