首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 抽象工廠模式深度解析:以快餐店生產漢堡雞腿為例

     編輯:關於C#

為什麼需要抽象工廠?

當系統需要創建一組「相關或依賴」的物件,且這組物件有多個「產品族」(如麥當勞族、肯德基族)時,若直接在業務代碼中 new 具體類,將導致:

  • 高層模組依賴低層模組,違反依賴倒置原則;
  • 新增產品族(如必勝客)需修改大量業務邏輯,違反開閉原則;
  • 客戶端代碼充斥 if/else 或 switch 判斷工廠類型,維護困難。

抽象工廠模式通過定義一個「工廠介面」,每個具體工廠實現該介面,負責創建整個產品族的所有產品,客戶端僅面向介面編程,實現「產品族」與「客戶端」的解耦。

領域建模:快餐店場景

  • 產品族:麥當勞 (MDL)、肯德基 (KDJ)、必勝客 (PizzaHut)……
  • 產品等級:漢堡、雞腿(本例固定兩種,符合「產品等級穩定、產品族擴展」的適用場景)。
  • 客戶端:消費者,只關心「我要漢堡」「我要雞腿」,不關心具體哪家店生產。

UML 結構


          +-------------------+
          |  KuaiCanFactory   |  (抽象工廠介面)
          | + eatJiTui():JiTui|
          | + eatHanBao():HanBao|
          +--------+----------+
                   ^
        +----------+----------+
        |                     |
+-------+-------+     +-------+-------+
|  MDLFactory   |     |  KDJFactory   |  (具體工廠)
| + eatJiTui()  |     | + eatJiTui()  |
| + eatHanBao() |     | + eatHanBao() |
+-------+-------+     +-------+-------+
        |                     |
        v                     v
+-------+-------+     +-------+-------+
|  MDLJiTui     |     |  KDJJiTui     |  (具體產品:雞腿)
| + getJiTui()  |     | + getJiTui()  |
+---------------+     +---------------+

+-------+-------+     +-------+-------+
|  MDLHanBao    |     |  KDJHanBao    |  (具體產品:漢堡)
| + getHanBao() |     | + getHanBao() |
+---------------+     +---------------+

核心代碼實現

1. 抽象產品與具體產品


// 抽象產品:漢堡
public abstract class HanBao {
    public abstract void GetHanBao();
}
public class MDLHanBao : HanBao {
    public override void GetHanBao() => Console.WriteLine("麥當勞漢堡");
}
public class KDJHanBao : HanBao {
    public override void GetHanBao() => Console.WriteLine("肯德基漢堡");
}

// 抽象產品:雞腿
public abstract class JiTui {
    public abstract void GetJiTui();
}
public class MDLJiTui : JiTui {
    public override void GetJiTui() => Console.WriteLine("麥當勞雞腿");
}
public class KDJJiTui : JiTui {
    public override void GetJiTui() => Console.WriteLine("肯德基雞腿");
}

2. 抽象工廠與具體工廠


public abstract class KuaiCanFactory {
    public abstract JiTui EatJiTui();
    public abstract HanBao EatHanBao();
}

public class MDLFactory : KuaiCanFactory {
    public override JiTui EatJiTui() => new MDLJiTui();
    public override HanBao EatHanBao() => new MDLHanBao();
}

public class KDJFactory : KuaiCanFactory {
    public override JiTui EatJiTui() => new KDJJiTui();
    public override HanBao EatHanBao() => new KDJHanBao();
}

3. 客戶端使用


class Program {
    static void Main() {
        // 配置決定用哪家工廠,可從配置文件、DI 容器注入
        KuaiCanFactory factory = new KDJFactory(); // 今天想吃肯德基

        JiTui jiTui = factory.EatJiTui();
        jiTui.GetJiTui(); // 輸出:肯德基雞腿

        HanBao hanBao = factory.EatHanBao();
        hanBao.GetHanBao(); // 輸出:肯德基漢堡

        // 切換工廠,客戶端代碼完全不用動
        factory = new MDLFactory();
        factory.EatJiTui().GetJiTui(); // 麥當勞雞腿
        factory.EatHanBao().GetHanBao(); // 麥當勞漢堡
    }
}

擴展新產品族:必勝客

只需新增三個類,零修改現有代碼:


public class PizzaHutJiTui : JiTui {
    public override void GetJiTui() => Console.WriteLine("必勝客雞腿");
}
public class PizzaHutHanBao : HanBao {
    public override void GetHanBao() => Console.WriteLine("必勝客漢堡");
}
public class PizzaHutFactory : KuaiCanFactory {
    public override JiTui EatJiTui() => new PizzaHutJiTui();
    public override HanBao EatHanBao() => new PizzaHutHanBao();
}

客戶端只需 `factory = new PizzaHutFactory();` 即可享用新口味。

什麼時候不適合用抽象工廠?

  • 產品等級結構不穩定:若頻繁新增產品種類(如又要加「可樂」、「薯條」、「冰淇淋」),每次都要修改抽象工廠介面及所有具體工廠,違反開閉原則。此時可考慮「建造者模式」或「簡單工廠 + 反射/配置」組合。
  • 產品族只有一個:無多族切換需求,簡單工廠或工廠方法即可。

進階:配合簡單工廠做工廠選擇


public static class FactorySelector {
    public static KuaiCanFactory Create(string brand) => brand switch {
        "MDL" => new MDLFactory(),
        "KDJ" => new KDJFactory(),
        "PizzaHut" => new PizzaHutFactory(),
        _ => throw new ArgumentException("未支援品牌")
    };
}

// 使用
var factory = FactorySelector.Create(ConfigurationManager.AppSettings["FastFoodBrand"]);

總結

抽象工廠模式的核心價值在於「封裝產品族的創建邏輯,讓客戶端免受具體工廠變更影響」。快餐店比喻生動詮釋了:

  1. 抽象工廠 = 快餐店品牌介面;
  2. 具體工廠 = 具體品牌分店;
  3. 抽象產品 = 漢堡/雞腿概念;
  4. 具體產品 = 各品牌具體口味;
  5. 客戶端 = 只點餐不關心後廚的消費者。

掌握「產品族 vs 產品等級」的變化維度,是正確選擇抽象工廠的關鍵。

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