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

C# 設計模式精講:抽象工廠模式

     編輯:關於C#

前言

在軟體開發中,當系統需要建立一系列相關或相互依賴的物件,而不想指定它們的具體類別時,抽象工廠模式是最佳選擇。本文將透過一個網路遊戲場景,深入淺出地講解這個模式的核心概念、實作細節與適用時機。

模式意圖

提供一個介面,用於建立一系列相關或相互依賴的物件,而無需指定它們具體的類別。這讓系統能夠獨立於其產品的建立、組合和表示方式。

應用場景:FPS 遊戲場景初始化

想像我們正在開發一款類似 CS 的休閒 FPS 遊戲,支援 8-16 名玩家分組對戰。遊戲包含多張地圖,且地圖數量會持續增加。每個三維場景物體由兩個核心元素組成:模型(骨架)與紋理(表面材質)。

若在場景初始化時,程式碼直接根據地圖名稱具體化模型與紋理類別,每新增一張地圖就得修改初始化邏輯,嚴重違反開放封閉原則。這就是抽象工廠模式大展身手的時刻。

核心程式碼實作

using System;
using System.Reflection;

namespace AbstractFactoryExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Patrix patrix = new Patrix();
            patrix.LoadScene("HalfPaper");
            patrix.LoadScene("Matrix");
        }
    }

    class Patrix
    {
        private PatrixSceneFactory GetGameScene(string gameSceneName)
        {
            return (PatrixSceneFactory)Assembly.Load("AbstractFactoryExample")
                .CreateInstance("AbstractFactoryExample." + gameSceneName);
        }

        public void LoadScene(string gameSceneName)
        {
            PatrixSceneFactory psf = GetGameScene(gameSceneName);
            Texture texture = psf.CreateTexture();
            Model model = psf.CreateModel();
            model.FillTexture(texture);
        }
    }

    abstract class PatrixSceneFactory
    {
        public abstract Model CreateModel();
        public abstract Texture CreateTexture();
    }

    abstract class Model
    {
        public abstract void FillTexture(Texture texture);
    }

    abstract class Texture { }

    class HalfPaper : PatrixSceneFactory
    {
        public override Model CreateModel() => new HalfPaperModel();
        public override Texture CreateTexture() => new HalfPaperTexture();
    }

    class HalfPaperModel : Model
    {
        public HalfPaperModel() => Console.WriteLine("HalfPaper Model Created");
        public override void FillTexture(Texture texture) 
            => Console.WriteLine("HalfPaper Model is filled Texture");
    }

    class HalfPaperTexture : Texture
    {
        public HalfPaperTexture() => Console.WriteLine("HalfPaper Texture Created");
    }

    class Matrix : PatrixSceneFactory
    {
        public override Model CreateModel() => new MatrixModel();
        public override Texture CreateTexture() => new MatrixTexture();
    }

    class MatrixModel : Model
    {
        public MatrixModel() => Console.WriteLine("Matrix Model Created");
        public override void FillTexture(Texture texture) 
            => Console.WriteLine("Matrix Model is filled Texture");
    }

    class MatrixTexture : Texture
    {
        public MatrixTexture() => Console.WriteLine("Matrix Texture Created");
    }
}

程式碼角色解析

  • PatrixSceneFactory:抽象工廠,宣告建立抽象場景模型與紋理的介面。
  • Model、Texture:抽象產品,定義產品的共同介面。
  • HalfPaper、Matrix:具體工廠,負責建立特定場景的模型與紋理(實際上對應地圖名稱)。
  • HalfPaperModel 等:具體產品,實作特定場景的模型與紋理邏輯。
  • Patrix:場景載入器,透過反射動態載入具體工廠,避免硬編碼 switch-case。

關鍵設計亮點

  1. 新增地圖零修改核心碼:只需新增對應的 Model、Texture 與具體工廠類別,Patrix.LoadScene 完全不動。
  2. 反射解耦具體工廠建立:透過 Assembly.CreateInstance 依名稱實例化,消除對具體類別的編譯時依賴。
  3. 系列產品一致性保證:同一工廠建立的 Model 與 Texture 保證屬於同一地圖,避免「Matrix 模型套用 HalfPaper 紋理」的邏輯錯誤。

.NET 框架中的經典應用:ADO.NET Provider Model

ADO.NET 2.0 內建完整的抽象工廠體系:

  • DbProviderFactory:抽象工廠基類,定義 CreateConnection、CreateCommand、CreateDataAdapter 等建立方法。
  • SqlClientFactory、OleDbFactory:具體工廠,分別建立 SQL Server 與 Access/OLE DB 專用的連線、命令、適配器等物件。
  • 客戶端程式碼僅依賴 DbConnection、DbCommand 等抽象類別,切換資料庫只需更換 Provider 字串,業務邏輯完全不變。

何時採用抽象工廠

程式碼視角

  • 需要在統一位置建立一系列相互關聯的物件。
  • 客戶端程式碼應依賴抽象介面而非具體實作。

應用視角

  • 產品以「系列/套件」形式出現,且確定會持續擴展新系列(如:不同地圖、不同資料庫 Provider、不同 UI 主題套件)。
  • 系列內的產品相互依賴、必須搭配使用(模型必須搭配對應紋理)。

實作要點與注意事項

✅ 實作要點

  • 抽象工廠只宣告介面,實際建立由具體工廠負責。
  • 體現「系列產品」概念:一個工廠方法對應一種產品類型,多個方法構成完整系列。
  • 善用反射或配置檔動態載入具體工廠,將變動點隔離在工廠註冊/發現機制中。

⚠️ 注意事項

  • 擴展新產品類型困難:若未來場景需要新增「AI 機器人」物件,抽象工廠介面必須新增 CreateBot(),導致所有具體工廠都要修改。適用於「系列固定、產品族擴展」的場景。
  • 避免過度設計:若系統不會新增新系列(如地圖固定不變),直接 new 具體類別更簡單清晰。
  • 產品間強關聯:適用於產品間有邏輯綁定關係的情況(如特定模型只能用特定紋理)。

總結

抽象工廠模式是處理「多維度變化」的利器:一個維度是產品系列(地圖/資料庫類型),另一個維度是產品類型(模型/紋理/連線/命令)。它將「建立什麼」與「如何建立」分離,讓系統在新增系列時優雅擴展。掌握其精髓,關鍵在於識別出系統中真正存在的「產品族」與「系列擴展點」。

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