定義:(Builder Pattern)
將一個(gè)復(fù)雜對象的構(gòu)建與它的表示分離莺褒,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示掩缓。
類圖:
啟示:
采購經(jīng)理要采購一批臺式電腦,為了節(jié)約公司成本遵岩,決定組裝你辣。但是對于怎么組裝,采購經(jīng)理不知道也不關(guān)心尘执,所以就指派裝機(jī)商組裝舍哄。第一次采購的電腦是組裝的HP的臺式機(jī),
第二次采購經(jīng)理決定換個(gè)品牌誊锭,組裝DELL的臺式機(jī)表悬。對于怎么組裝HP、DELL臺式機(jī)丧靡,采購經(jīng)理不關(guān)心蟆沫。
參與者:
Builder
為創(chuàng)建一個(gè)Product對象的各個(gè)部件指定抽象接口籽暇。
ConcreteBuilder
實(shí)現(xiàn)Builder的接口以構(gòu)造和裝配該產(chǎn)品的各個(gè)部件。
定義并明確它所創(chuàng)建的表示饭庞。
提供一個(gè)檢索產(chǎn)品的接口戒悠。
Director
構(gòu)造一個(gè)使用Builder接口的對象。
Product
表示被構(gòu)造的復(fù)雜對象但绕。ConcreteBuilder創(chuàng)建該產(chǎn)品的內(nèi)部表示并定義它的裝配過程救崔。
包含定義組成部件的類,包括將這些部件裝配成最終產(chǎn)品的接口捏顺。
代碼:
先看看產(chǎn)品Product六孵,電腦的實(shí)現(xiàn)。
/// <summary>
/// 產(chǎn)品類
/// </summary>
public class Computer
{
/// <summary>
/// 品牌
/// </summary>
public string Band { get; set; }
/// <summary>
/// 電腦組件列表
/// </summary>
private List<string> assemblyParts = new List<string>();
/// <summary>
/// 組裝部件
/// </summary>
/// <param name="partName">部件名稱</param>
public void AssemblePart(string partName)
{
this.assemblyParts.Add(partName);
}
public void ShowSteps()
{
Console.WriteLine("開始組裝『{0}』電腦:", Band);
foreach (var part in assemblyParts)
{
Console.WriteLine(string.Format("組裝『{0}』;", part));
}
Console.WriteLine("組裝『{0}』電腦完畢幅骄!", Band);
}
}
接下來看Builder角色劫窒,即電腦組裝商抽象類。
/// <summary>
/// 建造者(模擬裝機(jī)過程),也可通過接口實(shí)現(xiàn)
/// Director不關(guān)心具體組裝的細(xì)節(jié)拆座,所以將具體的組裝細(xì)節(jié)方法標(biāo)記為protected
/// </summary>
public abstract class Builder
{
/// <summary>
/// 組裝主機(jī)
/// </summary>
protected abstract void BuildMainFramePart();
/// <summary>
/// 組裝顯示器
/// </summary>
protected abstract void BuildScreenPart();
/// <summary>
/// 組裝輸入設(shè)備(鍵鼠)
/// </summary>
protected abstract void BuildInputPart();
/// <summary>
/// 獲取組裝電腦
/// 由具體的組裝類決定組裝順序
/// </summary>
/// <returns></returns>
public abstract Computer BuildComputer();
}
再看看具體的ConcreteBuilder角色主巍,HP電腦組裝商的實(shí)現(xiàn)
/// <summary>
/// 惠普電腦組裝商
/// </summary>
public class HpBulider : Builder
{
Computer hp = new Computer() { Band = "惠普" };
protected override void BuildMainFramePart()
{
hp.AssemblePart("主機(jī)");
}
protected override void BuildScreenPart()
{
hp.AssemblePart("顯示器");
}
protected override void BuildInputPart()
{
hp.AssemblePart("鍵鼠");
}
/// <summary>
/// 決定具體的組裝步驟
/// </summary>
/// <returns></returns>
public override Computer BuildComputer()
{
BuildMainFramePart();
BuildScreenPart();
BuildInputPart();
return hp;
}
}
最后只等指揮者Director一聲令下,組裝電腦挪凑≡兴鳎看看指揮者的實(shí)現(xiàn)。
/// <summary>
/// 指揮者(采購經(jīng)理)
/// </summary>
public class Director
{
public Computer Construct(Builder builder)
{
return builder.BuildComputer();
}
}
場景類
static void Main(string[] args)
{
Director director = new Director();
HpBulider hpBuilder = new HpBulider();
DellBulider dellBuilder =new DellBulider();
//組裝一批惠普電腦
Computer hp =director.Construct(hpBuilder);
hp.ShowSteps();
Console.ReadLine();
//組裝一批戴爾電腦
Computer dell = director.Construct(dellBuilder);
dell.ShowSteps();
Console.ReadLine();
}
運(yùn)行結(jié)果
優(yōu)缺點(diǎn):
建造者隱藏了具體產(chǎn)品的組裝過程躏碳,所以要改變一個(gè)產(chǎn)品的內(nèi)部表示搞旭,只需要再實(shí)現(xiàn)一個(gè)具體的建造者就可以了,從而能很好地應(yīng)對產(chǎn)品部件的需求變化菇绵。
抽象工廠模式解決了“系列產(chǎn)品”的需求變化肄渗,而建造者模式解決的是 “產(chǎn)品部分” 的需要變化。
應(yīng)用場景:
創(chuàng)建復(fù)雜對象的算法應(yīng)該獨(dú)立于該對象的組成部分以及它們的裝配方式時(shí)咬最。建造者模式關(guān)注的是零件類型和裝配工藝(順序)翎嫡。最主要的功能是基本方法的調(diào)用順序安排。