抽象工廠模式是工廠家族中最抽象、最具廣泛性的形態。它解決的核心問題是:系統需要建立多個相互關聯、相互依賴的產品族,且客戶端不應依賴具體產品的建立細節。本文系統講解抽象工廠的三維結構定義、適用場景判斷、小花果園雙園區案例、微型電腦生產系統案例,並深度剖析單例工廠、原型模式協作、動態工廠方法等進階實現變體。

關鍵洞察:當產品族維度 = 1時,第三維坍縮,抽象工廠退化為工廠方法。

// 抽象工廠介面
public interface Gardener {
VeggieIF createVeggie(String name);
FruitIF createFruit(String name);
}
// 北方具體工廠
public class NorthernGardener implements Gardener {
public VeggieIF createVeggie(String name) { return new NorthernVeggie(name); }
public FruitIF createFruit(String name) { return new NorthernFruit(name); }
}
// 南方具體工廠
public class TropicalGardener implements Gardener {
public VeggieIF createVeggie(String name) { return new TropicalVeggie(name); }
public FruitIF createFruit(String name) { return new TropicalFruit(name); }
}
// 抽象產品介面
public interface VeggieIF {}
public interface FruitIF {}
// 具體產品(簡化屬性)
public class NorthernVeggie implements VeggieIF { private String name; ... }
public class TropicalVeggie implements VeggieIF { private String name; ... }
// NorthernFruit, TropicalFruit 類似...
Gardener gardener = isNorthern ? new NorthernGardener() : new TropicalGardener();
VeggieIF veggie = gardener.createVeggie("cabbage");
FruitIF fruit = gardener.createFruit("apple");
// 客戶端完全不依賴具體產品類

系統通常只需一個 NorthernGardener、一個 TropicalGardener 實例。
public class NorthernGardener implements Gardener {
private static final NorthernGardener INSTANCE = new NorthernGardener();
private NorthernGardener() {}
public static NorthernGardener getInstance() { return INSTANCE; }
// ... 工廠方法
}
參考:單例模式三大實現
問題:多個具體工廠結構高度相似(皆有 createCPU、createRAM...)。
解決:使用原型模式克隆基礎工廠,再微調差異部分。
問題:新增產品類型(如硬碟)需修改介面、所有工廠類、所有產品類。
方案:合併為單一方法:
public interface ComputerFactory {
Part createPart(String type); // type: "CPU", "RAM", "HD"
}
public interface Part {
String getType(); // 返回 "CPU"/"RAM"/"HD"
}
代價:型別安全性降低,客戶端拿到的永遠是 Part 介面,需自行轉型檢查。
方案 A:單一方法按參數返回具體工廠
public abstract class ComputerFactory {
public static ComputerFactory getFactory(String which) {
if (which.equalsIgnoreCase("PC")) return new PCFactory();
else if (which.equalsIgnoreCase("Mac")) return new MacFactory();
throw new IllegalArgumentException();
}
}
方案 B:每個具體工廠對應一個靜態方法
public abstract class ComputerFactory {
public static PCFactory getPCFactory() { return PCFactory.getInstance(); }
public static MacFactory getMacFactory() { return MacFactory.getInstance(); }
}

public abstract class ComputerProducer {
public static ComputerProducer getProducer(String which) {
if (which.equalsIgnoreCase("PC")) return new PCProducer();
else if (which.equalsIgnoreCase("Mac")) return new MacProducer();
throw new IllegalArgumentException();
}
public abstract CPU createCPU();
public abstract RAM createRAM();
}

public abstract class ComputerProducer {
public static ComputerProducer getProducer(String which) {
if (which.equalsIgnoreCase("PC")) return PCProducer.getInstance();
else if (which.equalsIgnoreCase("Mac")) return MacProducer.getInstance();
throw new IllegalArgumentException();
}
}
public class PCProducer extends ComputerProducer {
private PCProducer() {}
private static final PCProducer INSTANCE = new PCProducer();
public static PCProducer getInstance() { return INSTANCE; }
public CPU createCPU() { return new PCCPU(); }
public RAM createRAM() { return new PCRAM(); }
}
// MacProducer 類似...
| 模式 | 核心結構 | 適用場景 | 擴展方式 |
|---|---|---|---|
| 簡單工廠 | 單一具體工廠類 + if-else | 單一產品族、類型固定、變化少 | 修改工廠類(違反 OCP) |
| 工廠方法 | 抽象工廠 + 多個具體工廠子類 | 多產品族、單維度產品變化 | 新增具體工廠子類(符合 OCP) |
| 抽象工廠 | 抽象工廠 + 多具體工廠 + 多產品族介面 | 多產品族、族內產品強協同、跨族不可混用 | 新增具體工廠 + 全族產品(符合 OCP) |
架構師心法:不要為了用模式而用模式。從簡單工廠開始,當產品維度增加、變化頻率上升、跨族協同約束出現時,自然演進至工廠方法、抽象工廠。模式是對變化維度的回應,而非代碼裝飾品。