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

C# 設計模式:抽象工廠模式 (Abstract Factory Pattern) 完整解析

     編輯:關於C#

簡介

抽象工廠模式屬於創建型模式,提供「一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類」。它將具體工廠的實例化延遲到子類,客戶端只需面對抽象介面,即可創建一整族相關產品。

模式結構

  • AbstractFactory (抽象工廠):宣告創建抽象產品的介面(AbstractMessageFactory)。
  • ConcreteFactory (具體工廠):實作創建具體產品邏輯(SqlMessageFactory, XmlMessageFactory)。
  • AbstractProduct (抽象產品):定義產品介面(AbstractMessage, AbstractMessageModel)。
  • ConcreteProduct (具體產品):實作具體產品(SqlMessage, SqlMessageModel 等)。
  • Client (客戶端):透過抽象工廠創建產品族(Message 類別)。

實作範例:SQL 與 XML 訊息處理族群

情境:系統需支援 SQL Server 與 XML 兩種資料存取方式,兩者各自包含 Message (操作類) 與 MessageModel (資料實體) 兩個相關物件,必須成對使用。

1. 抽象產品層

// 抽象資料實體
public abstract class AbstractMessageModel
{
    public string Message { get; set; }
    public DateTime PublishTime { get; set; }
    public abstract string UserId { get; set; } // 強制子類實作,可加入加密/解密邏輯

    protected AbstractMessageModel() { }
    protected AbstractMessageModel(string msg, DateTime pt) { Message = msg; PublishTime = pt; }
}

// 抽象操作類
public abstract class AbstractMessage
{
    public abstract string Insert(AbstractMessageModel model);
}

2. 具體產品:SQL 族群

public class SqlMessageModel : AbstractMessageModel
{
    private string _userId;
    public override string UserId { get => _userId; set => _userId = value; }

    public SqlMessageModel() : base() { }
    public SqlMessageModel(string userId, string msg, DateTime pt) : base(msg, pt) { _userId = userId; }
}

public class SqlMessage : AbstractMessage
{
    public override string Insert(AbstractMessageModel amm)
        => $"Sql方式插入Message。帳號:{amm.UserId};內容:{amm.Message};時間:{amm.PublishTime}";
}

3. 具體產品:XML 族群

public class XmlMessageModel : AbstractMessageModel
{
    private string _userId;
    public override string UserId 
    { 
        get => _userId; // 解密後的值
        set => _userId = value; // 加密後的值
    }

    public XmlMessageModel() : base() { }
    public XmlMessageModel(string userId, string msg, DateTime pt) : base(msg, pt) { _userId = userId; }
}

public class XmlMessage : AbstractMessage
{
    public override string Insert(AbstractMessageModel amm)
        => $"Xml方式插入Message。帳號:{amm.UserId};內容:{amm.Message};時間:{amm.PublishTime}";
}

4. 抽象與具體工廠

public abstract class AbstractMessageFactory
{
    public abstract AbstractMessageModel CreateMessageModel();
    public abstract AbstractMessage CreateMessage();
}

public class SqlMessageFactory : AbstractMessageFactory
{
    public override AbstractMessageModel CreateMessageModel() => new SqlMessageModel();
    public override AbstractMessage CreateMessage() => new SqlMessage();
}

public class XmlMessageFactory : AbstractMessageFactory
{
    public override AbstractMessageModel CreateMessageModel() => new XmlMessageModel();
    public override AbstractMessage CreateMessage() => new XmlMessage();
}

5. 客戶端 Context

public class Message
{
    private readonly AbstractMessage _insertMessage;
    private readonly AbstractMessageModel _messageModel;

    public Message(AbstractMessageFactory factory)
    {
        _insertMessage = factory.CreateMessage();
        _messageModel = factory.CreateMessageModel();
    }

    public string Insert(string userId, string msg, DateTime pt)
    {
        _messageModel.UserId = userId;
        _messageModel.Message = msg;
        _messageModel.PublishTime = pt;
        return _insertMessage.Insert(_messageModel);
    }
}

6. 客戶端使用

public partial class AbstractFactory : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // 使用 SQL 族群
        AbstractMessageFactory factory = new SqlMessageFactory();
        var msg = new Message(factory);
        Response.Write(msg.Insert("admin", "Sql方式", DateTime.Now) + "<br />");

        // 切換至 XML 族群
        factory = new XmlMessageFactory();
        msg = new Message(factory);
        Response.Write(msg.Insert("user", "Xml方式", DateTime.Now));
    }
}

執行結果

Sql方式插入Message。帳號:admin;內容:Sql方式;時間:2007-5-3 22:04:56
Xml方式插入Message。帳號:user;內容:Xml方式;時間:2007-5-3 22:04:56

模式優勢

  1. 產品族一致性:確保客戶端只使用同一族群的產品(不會混用 SQL Model 與 XML Message)。
  2. 易於切換產品族:只需更換具體工廠實例,整個系統行為即切換。
  3. 符合開放封閉原則:新增新族群(如 Oracle、JSON)只需新增對應工廠與產品,不修改既有代碼。

適用場景

  • 系統需支援多個產品族,且一次只使用其中一族。
  • 產品之間有強相依關係,必須成對創建。
  • 提供產品庫給第三方使用,只想暴露介面而非實作。

與工廠方法模式差異

特性工廠方法抽象工廠
創建目標單一產品產品族 (多個相關產品)
擴充方式繼承並覆寫工廠方法實作新的具體工廠介面
客戶端依賴抽象產品 + 抽象工廠抽象產品族 + 抽象工廠
抽象工廠模式類別圖

參考資料:DoFactory Abstract Factory Pattern

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