2013年11月10日 星期日

C# Design Pattern - Builder 建造者模式

開發遊戲裡,房屋的構建由許多部分組成,且各個部分各有變化。如果使用最直觀的設計方法,每一個房屋部分的變化,都會讓房屋構建的重新修正

一開始在JSON的建立一段程式碼:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="No1" value="RomanBuilder"></add>
        <add key="No2" value="ChineseBuilder"></add>
    </appSettings>

</configuration>

在軟體系統中,有時候是一個複雜物件的創建工作,由各個部分的子物件用一定演算法構成因需求的變化,會經常面臨著劇烈的變化,但是將它們組合到一起的演算法卻相對穩定
所以必須
提供一種封裝機制來隔離出複雜物件的各個部分的變化,保持系統中的穩定構建演算法,不隨需求的改變而改變。



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 FranceBuilder : Builder
{
    private House FranceHouse = new House();
    public override void BuildDoor()
    {
        Console.WriteLine("法式風格的門");
    }
    public override void BuildWall()
    {
        Console.WriteLine("法式風格的牆");
    }
    public override void BuildWindows()
    {
        Console.WriteLine("法式風格的門窗");
    }
    public override void BuildFloor()
    {
        Console.WriteLine("法式風格的地板");
    }
    public override void BuildHouseCeiling()
    {
        Console.WriteLine("法式風格的天花板");
    }
    public override House GetHouse()
    {
        return FranceHouse;
    }
}

從上面的結構,就可以依法泡製,產生各種不同的房子物件屬性,可以是中國風,羅馬風,法式風格,建構出各個不同建築物,再分別封裝。當然,建構函式,就可以隨著程式員的需求而個別變動,即便是再大的程式變動,也不會互相影響。


public class SetDesigner
{
    public void Construct(Builder builder)
    {
        builder.BuildWall();
        builder.BuildHouseCeiling();
        builder.BuildDoor();
        builder.BuildWindows();
        builder.BuildFloor();
    }
}

上面建構一個場景設計師的類別。



public class BuildingGame
{
    public static void Main(string[] args)
    {
        SetDesigner setDesigner = new SetDesigner();

        Builder instance;

        Console.WriteLine("請輸入房子編號:");

        string no = Console.ReadLine();

        string houseType = ConfigurationSettings.AppSettings["No" + no];

        instance = (Builder)Assembly.Load("House").CreateInstance("House." + houseType);

        setDesigner.Construct(instance);

        House house = instance.GetHouse();
        house.Show();

        Console.ReadLine();
    }
}

Builder主要用於「複雜的對象的逐一建構」,產生一個穩定的流程結構,而複雜物件的各個部分則經常變化,應對「物件每一個部分」的頻繁需求變動。缺點在於難以依照“逐一建構演算法”的需求變動。


在筆者一篇裡的Abstract Factory,它是解決“系列物件”的需求變化,Builder模式解決“物件部分”的需求變化,這兩者是可以搭配使用,依設計需求的解析,進而達到模組化設計的概念。

-雲遊山水為知已逍遙一生而忘齡- 電腦神手

沒有留言:

張貼留言