天天看點

.NET設計模式-建造者模式(Builder Pattern)

——.NET設計模式系列之四

Terrylee,2005年12月17日

概述

在軟體系統中,有時候面臨着“一個複雜對象”的建立工作,其通常由各個部分的子對象用一定的算法構成;由于需求的變化,這個複雜對象的各個部分經常面臨着劇烈的變化,但是将它們組合在一起的算法确相對穩定。如何應對這種變化?如何提供一種“封裝機制”來隔離出“複雜對象的各個部分”的變化,進而保持系統中的“穩定建構算法”不随着需求改變而改變?這就是要說的建造者模式。

本文通過現實生活中的買KFC的例子,用圖解的方式來诠釋建造者模式。

意圖

将一個複雜的建構與其表示相分離,使得同樣的建構過程可以建立不同的表示。

模型圖

生活中的例子

生成器模式将複雜對象的建構與對象的表現分離開來,這樣使得同樣的建構過程可以建立出不同的表現。這種模式用于快餐店制作兒童餐。典型的兒童餐包括一個主食,一個輔食,一杯飲料和一個玩具(例如漢堡、炸雞、可樂和玩具車)。這些在不同的兒童餐中可以是不同的,但是組合成兒童餐的過程是相同的。無論顧客點的是漢堡,三名治還是雞肉,過程都是一樣的。櫃台的員工直接把主食,輔食和玩具放在一起。這些是放在一個袋子中的。飲料被倒入杯中,放在袋子外邊。這些過程在互相競争的餐館中是同樣的。

實作過程圖解

在這裡我們還是以去KFC店買套餐為例子,示意圖如下:

用戶端:顧客。想去買一套套餐(這裡面包括漢堡,可樂,薯條),可以有1号和2号兩種套餐供顧客選擇。

指導者角色:收銀員。知道顧客想要買什麼樣的套餐,并告訴餐館員工去準備套餐。

建造者角色:餐館員工。按照收銀員的要求去準備具體的套餐,分别放入漢堡,可樂,薯條等。

産品角色:最後的套餐,所有的東西放在同一個盤子裡面。

下面開始我們的買套餐過程。

1.客戶建立Derector對象,并用它所想要的Builder對象進行配置。顧客進入KFC店要買套餐,先找到一個收銀員,相當于建立了一個指導者對象。這位收銀員給出兩種套餐供顧客選擇:1普通套餐,2黃金套餐。完成的工作如時序圖中紅色部分所示。

程式實作:

 1

.NET設計模式-建造者模式(Builder Pattern)

using System;

 2

.NET設計模式-建造者模式(Builder Pattern)

using System.Configuration;

 3

.NET設計模式-建造者模式(Builder Pattern)

using System.Reflection;

 4

.NET設計模式-建造者模式(Builder Pattern)

 5

.NET設計模式-建造者模式(Builder Pattern)

namespace KFC

 6

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

{

 7

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    /// <summary>

 8

.NET設計模式-建造者模式(Builder Pattern)

    /// Client 類

 9

.NET設計模式-建造者模式(Builder Pattern)

    /// </summary>

10

.NET設計模式-建造者模式(Builder Pattern)

    public class Client

11

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    {

12

.NET設計模式-建造者模式(Builder Pattern)

        public static void Main(string[] args)

13

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        {

14

.NET設計模式-建造者模式(Builder Pattern)

            FoodManager foodmanager = new FoodManager();

15

.NET設計模式-建造者模式(Builder Pattern)

16

.NET設計模式-建造者模式(Builder Pattern)

            Builder instance;

17

.NET設計模式-建造者模式(Builder Pattern)

18

.NET設計模式-建造者模式(Builder Pattern)

            Console.WriteLine("Please Enter Food No:");

19

.NET設計模式-建造者模式(Builder Pattern)

20

.NET設計模式-建造者模式(Builder Pattern)

            string No = Console.ReadLine();

21

.NET設計模式-建造者模式(Builder Pattern)

22

.NET設計模式-建造者模式(Builder Pattern)

            string foodType = ConfigurationSettings.AppSettings["No"+No];

23

.NET設計模式-建造者模式(Builder Pattern)

24

.NET設計模式-建造者模式(Builder Pattern)

            instance = (Builder)Assembly.Load("KFC").CreateInstance("KFC." + foodType);

25

.NET設計模式-建造者模式(Builder Pattern)

26

.NET設計模式-建造者模式(Builder Pattern)

            foodmanager.Construct(instance);

27

.NET設計模式-建造者模式(Builder Pattern)

        }

28

.NET設計模式-建造者模式(Builder Pattern)

    }

29

.NET設計模式-建造者模式(Builder Pattern)

}

30

.NET設計模式-建造者模式(Builder Pattern)

産品(套餐)類:

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

using System.Collections;

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    /// Food類,即産品類

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    public class Food

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        Hashtable food = new Hashtable();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        /// <summary>

.NET設計模式-建造者模式(Builder Pattern)

        /// 添加食品

.NET設計模式-建造者模式(Builder Pattern)

        /// </summary>

.NET設計模式-建造者模式(Builder Pattern)

        /// <param name="strName">食品名稱</param>

.NET設計模式-建造者模式(Builder Pattern)

        /// <param name="Price">價格</param>

.NET設計模式-建造者模式(Builder Pattern)

        public void Add(string strName,string Price)

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            food.Add(strName,Price);

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        /// 顯示食品清單

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        public void Show()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            IDictionaryEnumerator myEnumerator  = food.GetEnumerator();

.NET設計模式-建造者模式(Builder Pattern)

            Console.WriteLine("Food List:");

.NET設計模式-建造者模式(Builder Pattern)

            Console.WriteLine("------------------------------");

31

.NET設計模式-建造者模式(Builder Pattern)

            string strfoodlist = "";

32

.NET設計模式-建造者模式(Builder Pattern)

            while(myEnumerator.MoveNext())

33

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            {

34

.NET設計模式-建造者模式(Builder Pattern)

                strfoodlist = strfoodlist + ""n"n" + myEnumerator.Key.ToString();

35

.NET設計模式-建造者模式(Builder Pattern)

                strfoodlist = strfoodlist + ":"t" +myEnumerator.Value.ToString();

36

.NET設計模式-建造者模式(Builder Pattern)

            }

37

.NET設計模式-建造者模式(Builder Pattern)

            Console.WriteLine(strfoodlist);

38

.NET設計模式-建造者模式(Builder Pattern)

            Console.WriteLine(""n------------------------------");

39

.NET設計模式-建造者模式(Builder Pattern)

40

.NET設計模式-建造者模式(Builder Pattern)

41

.NET設計模式-建造者模式(Builder Pattern)

42

.NET設計模式-建造者模式(Builder Pattern)

2.指導者通知建造器。收銀員(指導者)告知餐館員工準備套餐。這裡我們準備套餐的順序是:放入漢堡,可樂倒入杯中,薯條放入盒中,并把這些東西都放在盤子上。這個過程對于普通套餐和黃金套餐來說都是一樣的,不同的是它們的漢堡,可樂,薯條價格不同而已。如時序圖紅色部分所示:

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    /// FoodManager類,即指導者

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    public class FoodManager

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        public void Construct(Builder builder)

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            builder.BuildHamb();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            builder.BuildCoke();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            builder.BuildChip();

.NET設計模式-建造者模式(Builder Pattern)

        }    

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

3.建造者處理指導者的要求,并将部件添加到産品中。餐館員工(建造者)按照收銀員要求的把對應的漢堡,可樂,薯條放入盤子中。這部分是建造者模式裡面富于變化的部分,因為顧客選擇的套餐不同,套餐的組裝過程也不同,這步完成産品對象的建立工作。

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    /// Builder類,即抽象建造者類,構造套餐

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    public abstract class Builder

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    {    

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        /// 添加漢堡

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        public abstract void BuildHamb();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        /// 添加可樂

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        public abstract void BuildCoke();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        /// 添加薯條

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        public abstract void BuildChip();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        /// 傳回結果

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        /// <returns>食品對象</returns>

.NET設計模式-建造者模式(Builder Pattern)

        public abstract Food GetFood();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    /// NormalBuilder類,具體構造者,普通套餐

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    public class NormalBuilder:Builder

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        private Food NormalFood = new Food();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        public override void BuildHamb()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            NormalFood.Add("NormalHamb","¥10.50");

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        public override void BuildCoke()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            NormalFood.Add("CokeCole","¥4.50");

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        public override void BuildChip()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            NormalFood.Add("FireChips","¥2.00");

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        public override Food GetFood()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            return NormalFood;

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    /// GoldBuilder類,具體構造者,黃金套餐

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    public class GoldBuilder:Builder

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

        private Food GoldFood = new Food();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            GoldFood.Add("GoldHamb","¥13.50");

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            GoldFood.Add("CokeCole","¥4.50");

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            GoldFood.Add("FireChips","¥3.50");

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            return GoldFood;

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

4.客戶從建造者檢索産品。從餐館員工準備好套餐後,顧客再從餐館員工那兒拿回套餐。這步客戶程式要做的僅僅是取回已經生成的産品對象,如時序圖中紅色部分所示。

完整的客戶程式:

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            Food food = instance.GetFood();

.NET設計模式-建造者模式(Builder Pattern)

            food.Show();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

            Console.ReadLine();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

通過分析不難看出,在這個例子中,在準備套餐的過程是穩定的,即按照一定的步驟去做,而套餐的組成部分則是變化的,有可能是普通套餐或黃金套餐等。這個變化就是建造者模式中的“變化點“,就是我們要封裝的部分。

另外一個例子

在這裡我們再給出另外一個關于建造房子的例子。客戶程式通過調用指導者 (CDirector class)的BuildHouse()方法來建立一個房子。該方法有一個布爾型的參數blnBackyard,當blnBackyard為假時指導者将建立一個Apartment(Concrete Builder),當它為真時将建立一個Single Family Home(Concrete Builder)。這兩種房子都實作了接口Ihouse。

  1

.NET設計模式-建造者模式(Builder Pattern)

//關于建造房屋的例子

  2

.NET設計模式-建造者模式(Builder Pattern)

  3

.NET設計模式-建造者模式(Builder Pattern)

  4

.NET設計模式-建造者模式(Builder Pattern)

  5

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

/// <summary>

  6

.NET設計模式-建造者模式(Builder Pattern)

/// 抽象建造者

  7

.NET設計模式-建造者模式(Builder Pattern)

/// </summary>

  8

.NET設計模式-建造者模式(Builder Pattern)

public interface IHouse

  9

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 10

.NET設計模式-建造者模式(Builder Pattern)

    bool GetBackyard();

 11

.NET設計模式-建造者模式(Builder Pattern)

    long NoOfRooms();

 12

.NET設計模式-建造者模式(Builder Pattern)

    string  Description();

 13

.NET設計模式-建造者模式(Builder Pattern)

 14

.NET設計模式-建造者模式(Builder Pattern)

 15

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 16

.NET設計模式-建造者模式(Builder Pattern)

/// 具體建造者

 17

.NET設計模式-建造者模式(Builder Pattern)

 18

.NET設計模式-建造者模式(Builder Pattern)

public class CApt:IHouse

 19

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 20

.NET設計模式-建造者模式(Builder Pattern)

    private bool mblnBackyard;

 21

.NET設計模式-建造者模式(Builder Pattern)

    private Hashtable Rooms;

 22

.NET設計模式-建造者模式(Builder Pattern)

    public CApt()

 23

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 24

.NET設計模式-建造者模式(Builder Pattern)

        CRoom room;    

 25

.NET設計模式-建造者模式(Builder Pattern)

        Rooms = new Hashtable();

 26

.NET設計模式-建造者模式(Builder Pattern)

        room = new CRoom();

 27

.NET設計模式-建造者模式(Builder Pattern)

        room.RoomName = "Master Bedroom";

 28

.NET設計模式-建造者模式(Builder Pattern)

        Rooms.Add ("room1",room);

 29

.NET設計模式-建造者模式(Builder Pattern)

 30

.NET設計模式-建造者模式(Builder Pattern)

 31

.NET設計模式-建造者模式(Builder Pattern)

        room.RoomName = "Second Bedroom";

 32

.NET設計模式-建造者模式(Builder Pattern)

        Rooms.Add ("room2",room);

 33

.NET設計模式-建造者模式(Builder Pattern)

 34

.NET設計模式-建造者模式(Builder Pattern)

 35

.NET設計模式-建造者模式(Builder Pattern)

        room.RoomName = "Living Room";

 36

.NET設計模式-建造者模式(Builder Pattern)

        Rooms.Add ("room3",room);

 37

.NET設計模式-建造者模式(Builder Pattern)

 38

.NET設計模式-建造者模式(Builder Pattern)

        mblnBackyard = false;

 39

.NET設計模式-建造者模式(Builder Pattern)

 40

.NET設計模式-建造者模式(Builder Pattern)

 41

.NET設計模式-建造者模式(Builder Pattern)

    public bool GetBackyard()

 42

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 43

.NET設計模式-建造者模式(Builder Pattern)

        return mblnBackyard;

 44

.NET設計模式-建造者模式(Builder Pattern)

 45

.NET設計模式-建造者模式(Builder Pattern)

    public long NoOfRooms()

 46

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 47

.NET設計模式-建造者模式(Builder Pattern)

        return Rooms.Count; 

 48

.NET設計模式-建造者模式(Builder Pattern)

 49

.NET設計模式-建造者模式(Builder Pattern)

    public string  Description()

 50

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 51

.NET設計模式-建造者模式(Builder Pattern)

        IDictionaryEnumerator myEnumerator  = Rooms.GetEnumerator();

 52

.NET設計模式-建造者模式(Builder Pattern)

        string strDescription;

 53

.NET設計模式-建造者模式(Builder Pattern)

        strDescription = "This is an Apartment with " + Rooms.Count + " Rooms "n";

 54

.NET設計模式-建造者模式(Builder Pattern)

        strDescription = strDescription + "This Apartment doesn't have a backyard "n";                        

 55

.NET設計模式-建造者模式(Builder Pattern)

        while (myEnumerator.MoveNext())

 56

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 57

.NET設計模式-建造者模式(Builder Pattern)

            strDescription = strDescription + ""n" + myEnumerator.Key + ""t" + ((CRoom)myEnumerator.Value).RoomName;

 58

.NET設計模式-建造者模式(Builder Pattern)

 59

.NET設計模式-建造者模式(Builder Pattern)

        return strDescription;

 60

.NET設計模式-建造者模式(Builder Pattern)

 61

.NET設計模式-建造者模式(Builder Pattern)

 62

.NET設計模式-建造者模式(Builder Pattern)

 63

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 64

.NET設計模式-建造者模式(Builder Pattern)

 65

.NET設計模式-建造者模式(Builder Pattern)

 66

.NET設計模式-建造者模式(Builder Pattern)

public class CSFH:IHouse

 67

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 68

.NET設計模式-建造者模式(Builder Pattern)

 69

.NET設計模式-建造者模式(Builder Pattern)

 70

.NET設計模式-建造者模式(Builder Pattern)

    public CSFH()

 71

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

 72

.NET設計模式-建造者模式(Builder Pattern)

        CRoom room;

 73

.NET設計模式-建造者模式(Builder Pattern)

 74

.NET設計模式-建造者模式(Builder Pattern)

 75

.NET設計模式-建造者模式(Builder Pattern)

 76

.NET設計模式-建造者模式(Builder Pattern)

 77

.NET設計模式-建造者模式(Builder Pattern)

 78

.NET設計模式-建造者模式(Builder Pattern)

 79

.NET設計模式-建造者模式(Builder Pattern)

 80

.NET設計模式-建造者模式(Builder Pattern)

 81

.NET設計模式-建造者模式(Builder Pattern)

 82

.NET設計模式-建造者模式(Builder Pattern)

 83

.NET設計模式-建造者模式(Builder Pattern)

 84

.NET設計模式-建造者模式(Builder Pattern)

        room.RoomName = "Third Room";

 85

.NET設計模式-建造者模式(Builder Pattern)

 86

.NET設計模式-建造者模式(Builder Pattern)

 87

.NET設計模式-建造者模式(Builder Pattern)

 88

.NET設計模式-建造者模式(Builder Pattern)

 89

.NET設計模式-建造者模式(Builder Pattern)

        Rooms.Add ("room4",room);

 90

.NET設計模式-建造者模式(Builder Pattern)

 91

.NET設計模式-建造者模式(Builder Pattern)

 92

.NET設計模式-建造者模式(Builder Pattern)

        room.RoomName = "Guest Room";

 93

.NET設計模式-建造者模式(Builder Pattern)

        Rooms.Add ("room5",room);

 94

.NET設計模式-建造者模式(Builder Pattern)

 95

.NET設計模式-建造者模式(Builder Pattern)

        mblnBackyard = true;

 96

.NET設計模式-建造者模式(Builder Pattern)

 97

.NET設計模式-建造者模式(Builder Pattern)

 98

.NET設計模式-建造者模式(Builder Pattern)

 99

.NET設計模式-建造者模式(Builder Pattern)

100

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

101

.NET設計模式-建造者模式(Builder Pattern)

102

.NET設計模式-建造者模式(Builder Pattern)

103

.NET設計模式-建造者模式(Builder Pattern)

104

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

105

.NET設計模式-建造者模式(Builder Pattern)

        return Rooms.Count;

106

.NET設計模式-建造者模式(Builder Pattern)

107

.NET設計模式-建造者模式(Builder Pattern)

108

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

109

.NET設計模式-建造者模式(Builder Pattern)

110

.NET設計模式-建造者模式(Builder Pattern)

111

.NET設計模式-建造者模式(Builder Pattern)

        strDescription = "This is an Single Family Home with " + Rooms.Count + " Rooms "n";

112

.NET設計模式-建造者模式(Builder Pattern)

        strDescription = strDescription + "This house has a backyard "n"; 

113

.NET設計模式-建造者模式(Builder Pattern)

114

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

115

.NET設計模式-建造者模式(Builder Pattern)

            strDescription = strDescription + ""n" + myEnumerator.Key + ""t" + ((CRoom)myEnumerator.Value).RoomName; 

116

.NET設計模式-建造者模式(Builder Pattern)

        }      

117

.NET設計模式-建造者模式(Builder Pattern)

118

.NET設計模式-建造者模式(Builder Pattern)

119

.NET設計模式-建造者模式(Builder Pattern)

120

.NET設計模式-建造者模式(Builder Pattern)

121

.NET設計模式-建造者模式(Builder Pattern)

public interface IRoom

122

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

123

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    string RoomName{get;set;}

124

.NET設計模式-建造者模式(Builder Pattern)

125

.NET設計模式-建造者模式(Builder Pattern)

126

.NET設計模式-建造者模式(Builder Pattern)

public class CRoom:IRoom

127

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

128

.NET設計模式-建造者模式(Builder Pattern)

    private string mstrRoomName;

129

.NET設計模式-建造者模式(Builder Pattern)

    public string RoomName

130

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

131

.NET設計模式-建造者模式(Builder Pattern)

        get

132

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

133

.NET設計模式-建造者模式(Builder Pattern)

            return mstrRoomName;

134

.NET設計模式-建造者模式(Builder Pattern)

135

.NET設計模式-建造者模式(Builder Pattern)

        set 

136

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

137

.NET設計模式-建造者模式(Builder Pattern)

            mstrRoomName = value;

138

.NET設計模式-建造者模式(Builder Pattern)

139

.NET設計模式-建造者模式(Builder Pattern)

140

.NET設計模式-建造者模式(Builder Pattern)

141

.NET設計模式-建造者模式(Builder Pattern)

142

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

143

.NET設計模式-建造者模式(Builder Pattern)

/// 指導者

144

.NET設計模式-建造者模式(Builder Pattern)

145

.NET設計模式-建造者模式(Builder Pattern)

public class CDirector

146

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

147

.NET設計模式-建造者模式(Builder Pattern)

    public IHouse BuildHouse(bool blnBackyard)

148

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

149

.NET設計模式-建造者模式(Builder Pattern)

        if (blnBackyard)

150

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

151

.NET設計模式-建造者模式(Builder Pattern)

            return new CSFH();

152

.NET設計模式-建造者模式(Builder Pattern)

153

.NET設計模式-建造者模式(Builder Pattern)

        else

154

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

155

.NET設計模式-建造者模式(Builder Pattern)

            return new CApt(); 

156

.NET設計模式-建造者模式(Builder Pattern)

157

.NET設計模式-建造者模式(Builder Pattern)

158

.NET設計模式-建造者模式(Builder Pattern)

159

.NET設計模式-建造者模式(Builder Pattern)

160

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

161

.NET設計模式-建造者模式(Builder Pattern)

/// 客戶程式

162

.NET設計模式-建造者模式(Builder Pattern)

163

.NET設計模式-建造者模式(Builder Pattern)

public class Client

164

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

165

.NET設計模式-建造者模式(Builder Pattern)

    static void Main(string[] args) 

166

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

167

.NET設計模式-建造者模式(Builder Pattern)

        CDirector objDirector = new CDirector();

168

.NET設計模式-建造者模式(Builder Pattern)

        IHouse objHouse;

169

.NET設計模式-建造者模式(Builder Pattern)

170

.NET設計模式-建造者模式(Builder Pattern)

        string Input = Console.ReadLine();

171

.NET設計模式-建造者模式(Builder Pattern)

        objHouse = objDirector.BuildHouse(bool.Parse(Input));

172

.NET設計模式-建造者模式(Builder Pattern)

173

.NET設計模式-建造者模式(Builder Pattern)

        Console.WriteLine(objHouse.Description());

174

.NET設計模式-建造者模式(Builder Pattern)

        Console.ReadLine();

175

.NET設計模式-建造者模式(Builder Pattern)

176

.NET設計模式-建造者模式(Builder Pattern)

177

.NET設計模式-建造者模式(Builder Pattern)

178

.NET設計模式-建造者模式(Builder Pattern)

建造者模式的幾種演化

省略抽象建造者角色

系統中隻需要一個具體建造者,省略掉抽象建造者,結構圖如下:

指導者代碼如下:

.NET設計模式-建造者模式(Builder Pattern)

 class Director

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

  {

.NET設計模式-建造者模式(Builder Pattern)

   private ConcreteBuilder builder;

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

   public void Construct()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

     builder.BuildPartA();

.NET設計模式-建造者模式(Builder Pattern)

     builder.BuildPartB();

.NET設計模式-建造者模式(Builder Pattern)

   }

.NET設計模式-建造者模式(Builder Pattern)

 }

省略指導者角色

抽象建造者角色已經被省略掉,還可以省略掉指導者角色。讓Builder角色自己扮演指導者與建造者雙重角色。結構圖如下:

建造者角色代碼如下:

.NET設計模式-建造者模式(Builder Pattern)

 public class Builder

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

   private Product product = new Product();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

   public void BuildPartA()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

    { 

.NET設計模式-建造者模式(Builder Pattern)

     //

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

   public void BuildPartB()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

   public Product GetResult()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

     return product;

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

     BuildPartA();

.NET設計模式-建造者模式(Builder Pattern)

     BuildPartB();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

客戶程式:

.NET設計模式-建造者模式(Builder Pattern)

 public class Client

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

   private static Builder builder;

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

   public static void Main()

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

     builder = new Builder();

.NET設計模式-建造者模式(Builder Pattern)

     builder.Construct();

.NET設計模式-建造者模式(Builder Pattern)

     Product product = builder.GetResult();

.NET設計模式-建造者模式(Builder Pattern)
.NET設計模式-建造者模式(Builder Pattern)

合并建造者角色和産品角色

建造模式失去抽象建造者角色和指導者角色後,可以進一步退化,進而失去具體建造者角色,此時具體建造者角色和産品角色合并,進而使得産品自己就是自己的建造者。這樣做混淆了對象的建造者和對象本身,但是有時候一個産品對象有着固定的幾個零件,而且永遠隻有這幾個零件,此時将産品類和建造類合并,可以使系統簡單易讀。結構圖如下:

實作要點

1、建造者模式主要用于“分步驟建構一個複雜的對象”,在這其中“分步驟”是一個穩定的算法,而複雜對象的各個部分則經常變化。

2、産品不需要抽象類,特别是由于建立對象的算法複雜而導緻使用此模式的情況下或者此模式應用于産品的生成過程,其最終結果可能差異很大,不大可能提煉出一個抽象産品類。

3、建立者中的建立子部件的接口方法不是抽象方法而是空方法,不進行任何操作,具體的建立者隻需要覆寫需要的方法就可以,但是這也不是絕對的,特别是類似文本轉換這種情況下,預設的方法将輸入原封不動的輸出是合理的預設操作。

4、前面我們說過的抽象工廠模式(Abtract Factory)解決“系列對象”的需求變化,Builder模式解決“對象部分”的需求變化,建造者模式常群組合模式(Composite Pattern)結合使用。

效果

1、建造者模式的使用使得産品的内部表象可以獨立的變化。使用建造者模式可以使用戶端不必知道産品内部組成的細節。

2、每一個Builder都相對獨立,而與其它的Builder無關。

3、可使對構造過程更加精細控制。

4、将建構代碼和表示代碼分開。

5、建造者模式的缺點在于難于應付“分步驟建構算法”的需求變動。

适用性

以下情況應當使用建造者模式:

1、需要生成的産品對象有複雜的内部結構。

2、需要生成的産品對象的屬性互相依賴,建造者模式可以強迫生成順序。

3、 在對象建立過程中會使用到系統中的一些其它對象,這些對象在産品對象的建立過程中不易得到。

應用場景

1、   RTF文檔交換格式閱讀器。

2、   .NET環境下的字元串處理StringBuilder,這是一種簡化了的建造者模式。

3、   ……

總結

建造者模式的實質是解耦組裝過程和建立具體部件,使得我們不用去關心每個部件是如何組裝的。

繼續閱讀