建造者模式將複雜物件的建構過程與其表示分離,使相同的建構過程可以建立不同的表示。本範例以「網頁建構」為例:相同流程(框架→表格→Span)產出不同風格(Cool/Warm/Clear)的頁面。
HomePage,內含 Hashtable parts 存放各部件 HTML 片段PageBuilder 抽象類別,定義 BuildFrame/BuildTable/BuildSpanCoolBuilder、WarmBuilder、ClearBuilder 實作具體 HTMLPageDirector 控制建構順序using System;
using System.Collections;
// 產品
class HomePage
{
private string _pageType;
private string _template = "<html><body>parttable,partspan</body></html>";
private Hashtable _parts = new Hashtable();
public HomePage(string pageType) { _pageType = pageType; }
public object this[string key]
{
get => _parts[key];
set => _parts[key] = value;
}
public void PrintHtmlCode()
{
string html = _template
.Replace("parttable", _parts["table"].ToString())
.Replace("partspan", _parts["span"].ToString());
Console.WriteLine(html);
}
}
// 指導者
class PageDirector
{
public void Construct(PageBuilder builder)
{
builder.BuildFrame();
builder.BuildTable();
builder.BuildSpan();
}
}
// 抽象建造者
abstract class PageBuilder
{
protected HomePage _homePage;
public HomePage HomePage => _homePage;
public abstract void BuildFrame();
public abstract void BuildTable();
public abstract void BuildSpan();
}
// 具體建造者
class CoolBuilder : PageBuilder
{
public override void BuildFrame() => _homePage = new HomePage("coolpage");
public override void BuildTable() => _homePage["table"] = "<table color=cool><tr><td></td></tr></table>";
public override void BuildSpan() => _homePage["span"] = "<span color=cool></span>";
}
class WarmBuilder : PageBuilder
{
public override void BuildFrame() => _homePage = new HomePage("warmpage");
public override void BuildTable() => _homePage["table"] = "<table color=warm><tr><td></td></tr></table>";
public override void BuildSpan() => _homePage["span"] = "<span color=warm></span>";
}
class ClearBuilder : PageBuilder
{
public override void BuildFrame() => _homePage = new HomePage("clearpage");
public override void BuildTable() => _homePage["table"] = "<table color=clear><tr><td></td></tr></table>";
public override void BuildSpan() => _homePage["span"] = "<span color=clear></span>";
}
// 測試
class TestApp
{
public static void Main()
{
var director = new PageDirector();
var builders = new PageBuilder[] { new CoolBuilder(), new WarmBuilder(), new ClearBuilder() };
foreach (var b in builders)
{
director.Construct(b);
b.HomePage.PrintHtmlCode();
}
}
}
<html><body><table color=cool><tr><td></td></tr></table>,<span color=cool></span></body></html>
<html><body><table color=warm><tr><td></td></tr></table>,<span color=warm></span></body></html>
<html><body><table color=clear><tr><td></td></tr></table>,<span color=clear></span></body></html>