工廠模式是創建型模式核心,核心意圖:封裝對象創建邏輯,解耦使用者與具體實現。按抽象程度遞增分為三類:
| 模式 | 核心角色 | 適用場景 | 開閉原則 |
|---|---|---|---|
| 簡單工廠 (Simple Factory) | 一個工廠類 + 判斷邏輯 | 產品較少、固定、客戶端只需傳參數 | 產品開放/修改關閉,工廠類違反 |
| 工廠方法 (Factory Method) | 抽象工廠接口 + 多個具體工廠 | 產品擴展頻繁、需符合開閉原則 | 完全符合 |
| 抽象工廠 (Abstract Factory) | 抽象工廠 + 多產品族 + 多產品等級 | 多產品族、系統只消費某一族產品 | 完全符合 |
if/else 或 switch// 抽象產品
public interface Car {
void drive();
}
// 具體產品
public class Benz implements Car {
public void drive() { System.out.println("駕駛奔馳..."); }
}
public class BMW implements Car {
public void drive() { System.out.println("駕駛寶馬..."); }
}
// 工廠類 (上帝類/全能類)
public class Driver {
public static Car driveCar(String type) {
if ("Benz".equalsIgnoreCase(type)) return new Benz();
else if ("BMW".equalsIgnoreCase(type)) return new BMW();
// else if ... 新增產品必須修改此處 ❌
throw new IllegalArgumentException("不支持的車型: " + type);
}
}
// 客戶端
public class Magnate {
public static void main(String[] args) {
Car car = Driver.driveCar("Benz"); // 只需知道參數
car.drive();
}
}
| 優點 | 缺點 |
|---|---|
| 客戶端極簡:只需傳參數 | 工廠類職責過重,違反單一職責 |
| 創建邏輯集中,易維護 | 新增產品需修改工廠代碼,違反開閉原則 | 靜態工廠方法調用便捷 | 產品族擴展困難,只支持單一產品等級 |
Car driveCar()// 抽象工廠
public interface Driver {
Car driveCar(); // 工廠方法
}
// 具體工廠:每個產品一個工廠類
public class BenzDriver implements Driver {
public Car driveCar() { return new Benz(); }
}
public class BMWDriver implements Driver {
public Car driveCar() { return new BMW(); }
}
// 客戶端:依賴抽象工廠
public class Magnate {
public static void main(String[] args) {
Driver driver = new BenzDriver(); // 選擇具體工廠
Car car = driver.driveCar(); // 調用工廠方法
car.drive();
}
}
當產品過多導致工廠類爆炸時,可對「同類產品」使用簡單工廠:
// 豪華車工廠 (簡單工廠內部封裝)
public class LuxuryCarDriver implements Driver {
public Car driveCar(String model) {
if ("Benz".equals(model)) return new Benz();
if ("BMW".equals(model)) return new BMW();
if ("Audi".equals(model)) return new Audi();
throw new IllegalArgumentException();
}
}
// 經濟車工廠
public class EconomyCarDriver implements Driver { ... }
產品等級結構 (垂直): 汽車 → 轎車/SUV/跑車 引擎 → 燃油/電動/混動 產品族 (橫向,功能相關): 奔馳家族:奔馳轎車 + 奔馳引擎 + 奔馳變速箱 寶馬家族:寶馬轎車 + 寶馬引擎 + 寶馬變速箱
// 抽象產品等級
interface Car { void drive(); }
interface Engine { void start(); }
// 抽象工廠:聲明創建所有等級產品的方法
interface CarFactory {
Car createCar();
Engine createEngine();
}
// 具體工廠:奔馳家族
class BenzFactory implements CarFactory {
public Car createCar() { return new BenzCar(); }
public Engine createEngine() { return new BenzEngine(); }
}
// 具體工廠:寶馬家族
class BMWFactory implements CarFactory {
public Car createCar() { return new BMWCar(); }
public Engine createEngine() { return new BMWEninge(); }
}
// 客戶端:綁定某族工廠
class Client {
private CarFactory factory;
public Client(CarFactory factory) { this.factory = factory; }
public void produce() {
Car car = factory.createCar();
Engine engine = factory.createEngine();
// 組裝...
}
}
| 維度 | 簡單工廠 | 工廠方法 | 抽象工廠 |
|---|---|---|---|
| 工廠類數量 | 1 | N (每產品一個) | M (每族一個) |
| 產品等級 | 1 | 1 | 多 |
| 產品族 | 1 | 1 | 多 |
| 開閉原則 | 工廠類違反 | 完全符合 | 完全符合 |
| 客戶端依賴 | 具體工廠類 | 抽象工廠接口 | 抽象工廠接口 |
| 擴展方式 | 修改工廠判斷邏輯 | 新增工廠+產品類 | 新增工廠+全族產品類 |
| 典型應用 | JDBC DriverManager、Calendar.getInstance() | 集合迭代器、文檔解析器 | UI皮膚、數據庫適配器、跨平台GUI |
開始 │ ├─ 只有一種產品,種類固定少? → 簡單工廠 │ ├─ 一種產品,但種類頻繁擴展? → 工廠方法 │ ├─ 多種相關產品(族),需協同使用? → 抽象工廠 │ └─ 以上都不滿足? → 考慮 Builder/Prototype/依賴注入
getBean() 是工廠方法getObject() 延遲創建複雜 Bean三大工廠模式由簡入繁,核心演進路線:集中判斷 → 延遲到子類 → 族級創建。選型原則:滿足當前需求的最簡單模式。簡單工廠適合穩定少變場景;工廠方法是最常用、平衡靈活與複雜度;抽象工廠解決多產品族協同問題。現代框架 (Spring/Guice) 通過依賴注入已內化工廠邏輯,業務代碼多直接聲明依賴,手寫工廠類場景大幅減少,但理解其原理對閱讀框架源碼、設計擴展點至關重要。