設計模式讀書筆記(四)——生成器模式

一、Builder模式的緣起(也就是需求)

       1、假設創建遊戲中的一個房屋House設施,該房屋的構建由幾個部分組成,且各個部分要富於變化。

       2、如果使用最直觀的設計方法,每一個房屋部分的變化,都將導致房屋構建的重新修正......

二、動機

        在軟件系統中,有時候面臨着“一個複雜對象”的創建工作,其通常由各個部分的子對象用一定的算法構成,由於需要的變化,這個複雜對象的各個部分經常面臨着劇烈的變化,但是將它們組合在一起的算法卻相對穩定。

       如何應對這種變化,如何提供一種“封裝機制”來隔離出“複雜對象各個部分”的變化,從而保持系統中的“穩定構建算法”不隨着需要的變化而變化。

三、類圖

四、代碼

        1、Build.cs

namespace Builder
{
    public abstract class House
    {
 
    }

    public abstract class Door
    {

    }

    public abstract class Wall
    {

    }

    public abstract class Windows
    {

    }

    public abstract class Floor
    {

    }

    public abstract class HouseCelling
    {

    }
   
    public abstract class Builder
    {
        public abstract void BuildDoor();
        public abstract void BuildWall();
        public abstract void BuildWindows();
        public abstract void BuildFloor();
        public abstract void BuildHouseCelling();

        public abstract House GetHouse();
    }  
}

     2、RomaHouse.cs

namespace Builder
{
    public class RomaHouse:House
    {
        public RomaHouse()
        {
            Console.WriteLine("/n建設羅馬式房屋");
        }
    }
    public class RomaDoor : Door
    {
        public RomaDoor()
        {
            Console.WriteLine("/n建設羅馬式門");
        }
    }
    public class RomaWall : Wall
    {
        public RomaWall()
        {
            Console.WriteLine("/n建設羅馬式牆");
        }
    }
    public class RomaWindows : Windows
    {
        public RomaWindows()
        {
            Console.WriteLine("/n建設羅馬式窗");
        }
    }
    public class RomaFloor : Floor
    {
        public RomaFloor()
        {
            Console.WriteLine("/n建設羅馬式地板");
        }
    }
    public class RomaHouseCelling : HouseCelling
    {
        public RomaHouseCelling()
        {
            Console.WriteLine("/n建設羅馬式屋頂");
        }
    }

    public class RomaHouseBuilder : Builder
    {
        public override void BuildDoor()
        {
            Door door = new RomaDoor();
            Console.WriteLine("/n羅馬式門建成了");
        }
        public override void BuildWall()
        {
            Wall wall = new RomaWall();
            Console.WriteLine("/n羅馬式牆建成了");
        }
        public override void BuildWindows()
        {
            Windows windows = new RomaWindows();
            Console.WriteLine("/n羅馬式窗建成了");
        }
        public override void BuildFloor()
        {
            Floor floor = new RomaFloor();
            Console.WriteLine("/n羅馬式地板建成了");
        }
        public override void BuildHouseCelling()
        {
            HouseCelling housecelling = new RomaHouseCelling();
            Console.WriteLine("/n羅馬式屋頂建成了");
        }
        public override House GetHouse()
        {
            return new RomaHouse();
           
        }
    }
}

     3、GameManager.cs


namespace Builder
{
    public class GameManager
    {
        public static House CreateHouse(Builder builder)
        {
            builder.BuildDoor();

            builder.BuildWall();

            builder.BuildWindows();

            builder.BuildFloor();

            builder.BuildHouseCelling();

            return builder.GetHouse();
        }
    }
}

4、Client.cs


namespace Builder
{
    class App
    {
        public static void Main()
        {
            string builderName = ConfigurationSettings.AppSettings["BuildName"].ToString();
            string assemblyName = ConfigurationSettings.AppSettings["BuildAssembly"].ToString();
            Assembly assembly = Assembly.Load(assemblyName);

            Type t = assembly.GetType(builderName);
            Builder builder = (Builder)Activator.CreateInstance(t);
           
            House house = GameManager.CreateHouse(builder);

            Console.ReadLine();
        }
    }
}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="BuildName" value="Builder.RomaHouseBuilder"></add>
    <add key="BuildAssembly" value="Builder"></add>
  </appSettings>
</configuration>

五、代碼分析

       首先看看運行結果:

       大家看代碼之後也許會認爲,生成器模式與抽象工廠模式幾乎沒什麼區別,沒錯,確實很相似,現在我來談談不同之處。

       首先我們來從代碼談起,大家注意兩種模式最大的不同就是GameManager.cs這個類,生成器模式中的GameManager類中各個子對象都互不相干,由各個子對象來生成一個大的對象;而抽象工廠模式GameManager類中各個對象是耦合的,大家注意到Building類中building(Road road)方法沒有(也許遊戲場景中房屋下面有路)

      下面總結一下兩種模式是不同:

       生成器模式解決“對象部分”的需求變化,如例中假設房屋裏面加上一個牀,那將是相當方便的,只需要新增一個牀類,然後在GameManager中加上builder.BuildBed()就ok了。

       抽象工廠模式解決是“系列對象”的需求變化,如例中只有在道路,房屋,地道,叢林這四種均不會變化的情況下才適用,假設再加一個沙漠或者是海洋什麼的,這種模式就不適用了。

       最後說明一點,在App.config中有兩個地方可由用戶配置程序集和類名,main方法中利用反射機制根據程序集和類名實例化一個類對象,這樣就可以很方便地修改房屋的風格(比如當前是Roma風格的,您也可以新增一個China風格的)

 

 http://blog.sina.com.cn/u/495615e7010004zm

發佈了37 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章