工廠模式是創建型模式中最常用、最實用的一族,核心思想是將對象創建邏輯封裝、延遲、多態化,實現「依賴倒轉」與「開閉原則」。本文以「四則運算」為主線,層層遞進講解三種工廠形態,並以「股票行情數據訪問」為例展示抽象工廠實戰,附完整代碼與優缺點對比表。
結構:一個工廠類 + 多個產品子類,工廠內部 switch/type 判斷創建具體產品。
class Operation { /* 運算基類 */ virtual double getResult() = 0; };
class AddOp : public Operation { double getResult() { return A+B; } };
/* SubOp, MulOp, DivOp 同理 */
class OperFactory {
public:
static Operation* createOperation(char op) {
switch(op) {
case '+': return new AddOp;
case '-': return new SubOp;
case '*': return new MulOp;
case '/': return new DivOp;
}
return nullptr;
}
};
客戶端:Operation* op = OperFactory::createOperation('+');
| 優點 | 缺點 |
|---|---|
| 客戶端無需知道具體類名,只需類型標識 | 新增產品需修改工廠類(違反開閉原則) |
| 邏輯集中,易維護(產品較少時) | 工廠類職責過重,單點故障 |
適用:產品種類固定、較少、客戶端多處使用同一產品類型。
結構:抽象工廠介面 + 每個產品對應一個具體工廠,創建邏輯下沉到具體工廠。
class IFactory { public: virtual Operation* createOperation() = 0; };
class AddFactory : public IFactory { Operation* createOperation() { return new AddOp; } };
class SubFactory : public IFactory { Operation* createOperation() { return new SubOp; } };
/* MulFactory, DivFactory 同理 */
客戶端:Operation* op = MulFactory::createOperation();
| 優點 | 缺點 |
|---|---|
| 新增產品只需新增「產品類+工廠類」,不動現有代碼(符合開閉) | 類爆炸:N 個產品需 2N 個類 |
| 客戶端依賴抽象工廠介面 | 客戶端仍需知曉具體工廠類名(選擇邏輯外移) |
本質:將簡單工廠的 switch 判斷「外移」到客戶端,由客戶端決定用哪個工廠。
場景:產品族(多個相關產品維度),如「滬深板塊」×「代碼/指數」兩個維度。


// 抽象產品
class ICode { virtual void GetCode()=0; virtual void SetCode()=0; };
class IIndex { virtual void GetIndex()=0; virtual void SetIndex()=0; };
// 具體產品(滬市/深市)
class ShenACode : public ICode { /* 實現 */ };
class ShangACode : public ICode { /* 實現 */ };
class ShenAIndex : public IIndex { /* 實現 */ };
class ShangAIndex : public IIndex { /* 實現 */ };
// 抽象工廠:定義創建「產品族」介面
class IFactory {
public:
virtual ICode* CreateCode() = 0;
virtual IIndex* CreateIndex() = 0;
};
// 具體工廠:每個工廠產出一族相關產品
class ShenAFactory : public IFactory {
ICode* CreateCode() { return new ShenACode; }
IIndex* CreateIndex() { return new ShenAIndex; }
};
class ShangAFactory : public IFactory {
ICode* CreateCode() { return new ShangACode; }
IIndex* CreateIndex() { return new ShangAIndex; }
};
客戶端:
IFactory* factory = new ShangAFactory(); // 或 ShenAFactory ICode* code = factory->CreateCode(); IIndex* idx = factory->CreateIndex(); code->GetCode(); idx->GetIndex();
進階:配置驅動工廠(文中 DataShangA 示例)
class DataShangA {
static string market; // "ShangA" / "ShenA"
public:
static ICode* CreateCode() {
return (market=="ShangA") ? new ShangACode : new ShenACode;
}
static IIndex* CreateIndex() {
return (market=="ShangA") ? new ShangAIndex : new ShenAIndex;
}
};
string DataShangA::market = "ShenA";
此模式將「選擇哪族產品」外部化為配置,客戶端完全不依賴具體工廠類。
| 維度 | 簡單工廠 | 工廠方法 | 抽象工廠 |
|---|---|---|---|
| 核心目的 | 集中創建邏輯 | 延遲創建到子類 | 創建相關產品族 |
| 工廠數量 | 1 | N (每產品一個) | M (每產品族一個) |
| 產品維度 | 單一 | 單一 | 多維度(族) |
| 開閉原則 | 違反(修改工廠) | 符合(新增類) | 符合(新增族) |
| 客戶端依賴 | 工廠類+類型標識 | 具體工廠類 | 抽象工廠介面 |
| 典型場景 | 運算符、日誌器 | 文檔導出器、連接器 | 跨平台GUI、多数據源 |
工廠模式不只是「new 的封裝」,更是「創建邏輯的策略化與多態化」。正確選型能讓系統在擴展中保持穩健、清晰。