在軟體系統中,有時候面臨著“一個複雜物件”的建立工作,其通常由各個部分的子物件用一定的演算法構成:由於需求的變化,這個複雜物件的各個部分經常面臨著劇烈的變化,但是將它們組合在一起的演算法卻相對穩定。
如何應對這種變化?如何提供一種“封裝機制”來隔離出“複雜物件的各個部分”的變化,從而保持系統中的“穩定構建演算法”不隨著需求改變而改變?
將一個複雜物件的構建與其表示相分離,使得同樣的構建過程可以建立不同的表示。
結構:
協作:
public abstract class House { }
public abstract class Door { }
public abstract class Wall { }
public abstract class Windows { }
public abstract class Floor { }
public abstract class HouseCeiling { }
public abstract class Builder
{
public abstract void BuildDoor();//門
public abstract void BuildWall();//牆
public abstract void BuildWindows();//窗戶
public abstract void BuildFloor();//地板
public abstract void BuildHouseCeiling();//屋頂
public abstract House GetHouse();//構建房子
}
public class RomainHouse : House { }
public class RomanDoor : Door { }
public class RomanWall : Wall { }
public class RomanWindows : Windows { }
public class RomanFloor : Floor { }
public class RomanHouseCeiling : HouseCeiling { }
public class RomainHouseBuilder : Builder
{
public override void BuildDoor() { }
public override void BuildWall() { }
public override void BuildWindows() { }
public override void BuildFloor() { }
public override void BuildHouseCeiling() { }
public override House GetHouse()
{
return new RomainHouse();
}
}
public class GameManager
{
public static House CreateHouse(Builder builder)
{
builder.BuildWall();//建立第一面牆
builder.BuildWall();//建立第二面牆
builder.BuildWall();//建立第三面牆
builder.BuildWall();//建立第四面牆
builder.BuildWindows();//建立第一個窗
builder.BuildWindows();//建立第二個窗
builder.BuildDoor();
builder.BuildFloor();
builder.BuildHouseCeiling();
return builder.GetHouse();
}
}
class App
{
public static void Main()
{
//House house = GameManager.CreateHouse(new RomainHouseBuilder());
string assemblyName = System.Configuration.ConfigurationSettings.AppSettings["BuilderAssembly"];
string builderName = System.Configuration.ConfigurationSettings.AppSettings["BuilderClass"];
System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(assemblyName);
Type t = assembly.GetType(builderName);
Builder builder = (Builder)Activator.CreateInstance(t);
House house = GameManager.CreateHouse(builder);
}
}
要點:
1、Builder模式主要用於“分步驟構建一個複雜的對象”。在這其中“分步驟”是一個穩定的演算法,而複雜物件的各個部分則經常變化。
2、變化點在哪裡,封裝哪裡--Builder模式主要在於應對“複雜物件各個部分”的頻繁需求變動。其缺點在於難以應付“分步驟構建演算法”的需求變動。
3、Abstract Factory模式解決“系列對象”的需求變化,Builder模式解決“對象部分”的需求變化。Builder模式通常和Composite模式組合使用。
問答:
1、Builder模式中的BuildPart方法為虛方法,Builder模式中的方法可以返回介面或者抽象類別;
2、Builder模式主要在於應對“各子物件”的需求變動,其缺點在於難以應對“分步驟構建演算法”的需求變動;