建造者模式屬於創建型模式,其核心目的是「將一個複雜對象的建構與它的表示分離,使得同樣的建構過程可以創建不同的表示」。當物件的建構過程涉及多個步驟、且需要根據不同情境產生不同內部結構時,此模式極為適用。
Operation,包含 Get/Insert 邏輯)。AbstractMessageBuilder)。SqlMessageBuilder, XmlMessageBuilder)。Message 類別)。情境:使用相同的建構流程,分別產生 SQL 與 XML 兩種資料存取方式的 Get() 與 Insert() 方法呼叫。
// 實體模型
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; }
}
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 />";
}
}
// 抽象建造者
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";
}
public class Message
{
public void Construct(AbstractMessageBuilder builder, MessageModel mm)
{
builder.BuilderInsert(mm);
builder.BuilderGet();
}
}
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