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

C# 設計模式:建造者模式 (Builder Pattern) 完整實作指南

     編輯:關於C#

簡介

建造者模式屬於創建型模式,其核心目的是「將一個複雜對象的建構與它的表示分離,使得同樣的建構過程可以創建不同的表示」。當物件的建構過程涉及多個步驟、且需要根據不同情境產生不同內部結構時,此模式極為適用。

模式結構

  • Product (產品):最終要建構的複雜物件(本例為 Operation,包含 Get/Insert 邏輯)。
  • Builder (抽象建造者):定義建構步驟的介面(AbstractMessageBuilder)。
  • ConcreteBuilder (具體建造者):實作具體建構邏輯(SqlMessageBuilder, XmlMessageBuilder)。
  • Director (指導者):控制建構流程,調用 Builder 的步驟(Message 類別)。

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

情境:使用相同的建構流程,分別產生 SQL 與 XML 兩種資料存取方式的 Get() 與 Insert() 方法呼叫。

1. 產品與資料模型

// 實體模型
public class MessageModel
{
    public string Message { get; set; }
    public DateTime PublishTime { get; set; }
    public MessageModel(string msg, DateTime pt) { Message = msg; PublishTime = pt; }
}

// SQL 實作
public class SqlMessage
{
    public List<MessageModel> Get() => new List<MessageModel> { new MessageModel("SQL方式獲取Message", DateTime.Now) };
    public bool Insert(MessageModel mm) { /* 略 */ return true; }
}

// XML 實作
public class XmlMessage
{
    public List<MessageModel> Get() => new List<MessageModel> { new MessageModel("XML方式獲取Message", DateTime.Now) };
    public bool Insert(MessageModel mm) { /* 略 */ return true; }
}

2. 產品類別

Operation 類別封裝了透過反射動態呼叫具體類別的邏輯,模擬複雜的建構結果。

using System;
using System.Collections.Generic;
using System.Reflection;

public class Operation
{
    private readonly string _type;
    private readonly Dictionary<string, string> _dict = new Dictionary<string, string>();

    public Operation(string type) { _type = type; }

    public string this[string key]
    {
        get => _dict[key];
        set => _dict[key] = value;
    }

    public string GetResult()
    {
        var asm = Assembly.Load("Pattern.Builder");
        // 動態呼叫 Get 方法
        var getInfo = this["get"].Split('|');
        var getType = asm.GetType($"Pattern.Builder.{getInfo[0]}");
        var getMethod = getType.GetMethod(getInfo[1]);
        var getObj = getMethod.Invoke(asm.CreateInstance($"Pattern.Builder.{getInfo[0]}"), null);
        var list = (List<MessageModel>)getObj;

        // 動態呼叫 Insert 方法
        var insInfo = this["insert"].Split('|');
        var insType = asm.GetType($"Pattern.Builder.{insInfo[0]}");
        var insMethod = insType.GetMethod(insInfo[1]);
        var insObj = insMethod.Invoke(asm.CreateInstance($"Pattern.Builder.{insInfo[0]}"), new object[] { new MessageModel(insInfo[2], DateTime.Parse(insInfo[3])) });
        bool result = (bool)insObj;

        return $"類型為{_type}的執行結果:<br />{result}<br />{list[0].Message} {list[0].PublishTime}<br />";
    }
}

3. 抽象與具體建造者

// 抽象建造者
public abstract class AbstractMessageBuilder
{
    protected Operation _operation;
    public Operation Operation => _operation;

    protected AbstractMessageBuilder(string type) { _operation = new Operation(type); }

    public abstract void BuilderInsert(MessageModel mm);
    public abstract void BuilderGet();
}

// SQL 建造者
public class SqlMessageBuilder : AbstractMessageBuilder
{
    public SqlMessageBuilder() : base("sql") { }
    public override void BuilderInsert(MessageModel mm) => _operation["insert"] = $"SqlMessage|Insert|{mm.Message}|{mm.PublishTime}";
    public override void BuilderGet() => _operation["get"] = "SqlMessage|Get";
}

// XML 建造者
public class XmlMessageBuilder : AbstractMessageBuilder
{
    public XmlMessageBuilder() : base("xml") { }
    public override void BuilderInsert(MessageModel mm) => _operation["insert"] = $"XmlMessage|Insert|{mm.Message}|{mm.PublishTime}";
    public override void BuilderGet() => _operation["get"] = "XmlMessage|Get";
}

4. 指導者

public class Message
{
    public void Construct(AbstractMessageBuilder builder, MessageModel mm)
    {
        builder.BuilderInsert(mm);
        builder.BuilderGet();
    }
}

5. 客戶端使用

public partial class Builder : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var director = new Message();

        // 建構 SQL 版本
        var sqlBuilder = new SqlMessageBuilder();
        director.Construct(sqlBuilder, new MessageModel("插入", DateTime.Now));
        Response.Write(sqlBuilder.Operation.GetResult());

        // 建構 XML 版本
        var xmlBuilder = new XmlMessageBuilder();
        director.Construct(xmlBuilder, new MessageModel("插入", DateTime.Now));
        Response.Write(xmlBuilder.Operation.GetResult());
    }
}

執行結果

類型為sql的執行結果:
True
SQL方式獲取Message 2007-5-5 20:53:28

類型為xml的執行結果:
True
XML方式獲取Message 2007-5-5 20:53:28

模式優勢

  1. 封裝性:客戶端不需知道產品內部結構,只需指定建造者類型。
  2. 擴充性:新增新的資料存取方式(如 JSON、NoSQL)只需新增對應的 ConcreteBuilder,符合開放封閉原則。
  3. 流程控制:Director 統一控制建構步驟順序,避免客戶端邏輯分散。

適用場景

  • 物件建構過程複雜,包含多個步驟或條件判斷。
  • 需要將建構邏輯與表示分離,支援多種表示形式。
  • 建構過程需根據不同參數產生不同內部結構。
建造者模式類別圖

參考資料:DoFactory Builder Pattern

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