.NET设计模式(4):建造者模式(Builder Pattern)
建造者模式(Builder Pattern)
——.NET设计模式系列之四
Terrylee,2005年12月17日
概述
在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法确相对稳定。如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?这就是要说的建造者模式。
本文通过现实生活中的买KFC的例子,用图解的方式来诠释建造者模式。
意图
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
模型图

生活中的例子
生成器模式将复杂对象的构建与对象的表现分离开来,这样使得同样的构建过程可以创建出不同的表现。这种模式用于快餐店制作儿童餐。典型的儿童餐包括一个主食,一个辅食,一杯饮料和一个玩具(例如汉堡、炸鸡、可乐和玩具车)。这些在不同的儿童餐中可以是不同的,但是组合成儿童餐的过程是相同的。无论顾客点的是汉堡,三名治还是鸡肉,过程都是一样的。柜台的员工直接把主食,辅食和玩具放在一起。这些是放在一个袋子中的。饮料被倒入杯中,放在袋子外边。这些过程在相互竞争的餐馆中是同样的。

实现过程图解
在这里我们还是以去KFC店买套餐为例子,示意图如下:

客户端:顾客。想去买一套套餐(这里面包括汉堡,可乐,薯条),可以有1号和2号两种套餐供顾客选择。
指导者角色:收银员。知道顾客想要买什么样的套餐,并告诉餐馆员工去准备套餐。
建造者角色:餐馆员工。按照收银员的要求去准备具体的套餐,分别放入汉堡,可乐,薯条等。
产品角色:最后的套餐,所有的东西放在同一个盘子里面。
下面开始我们的买套餐过程。
1.客户创建Derector对象,并用它所想要的Builder对象进行配置。顾客进入KFC店要买套餐,先找到一个收银员,相当于创建了一个指导者对象。这位收银员给出两种套餐供顾客选择:1普通套餐,2黄金套餐。完成的工作如时序图中红色部分所示。

程序实现:
 using System;
using System;2
 using System.Configuration;
using System.Configuration;3
 using System.Reflection;
using System.Reflection;4

5
 namespace KFC
namespace KFC6
 {
{7
 /// <summary>
    /// <summary>8
 /// Client 类
    /// Client 类9
 /// </summary>
    /// </summary>10
 public class Client
    public class Client11
 {
    {12
 public static void Main(string[] args)
        public static void Main(string[] args)13
 {
        {14
 FoodManager foodmanager = new FoodManager();
            FoodManager foodmanager = new FoodManager();15

16
 Builder instance;
            Builder instance;17

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

20
 string No = Console.ReadLine();
            string No = Console.ReadLine();21

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

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

26
 foodmanager.Construct(instance);
            foodmanager.Construct(instance);27
 }
        }28
 }
    }29
 }
}30

产品(套餐)类:
 using System;
using System;2
 using System.Collections;
using System.Collections;3

4
 namespace KFC
namespace KFC5
 {
{6
 /// <summary>
    /// <summary>7
 /// Food类,即产品类
    /// Food类,即产品类8
 /// </summary>
    /// </summary>9
 public class Food
    public class Food10
 {
    {11
 Hashtable food = new Hashtable();
        Hashtable food = new Hashtable();12
 
        13
 /// <summary>
        /// <summary>14
 /// 添加食品
        /// 添加食品15
 /// </summary>
        /// </summary>16
 /// <param name="strName">食品名称</param>
        /// <param name="strName">食品名称</param>17
 /// <param name="Price">价格</param>
        /// <param name="Price">价格</param>18
 public void Add(string strName,string Price)
        public void Add(string strName,string Price)19
 {
        {20
 food.Add(strName,Price);
            food.Add(strName,Price);21
 }
        }22
 
        23
 /// <summary>
        /// <summary>24
 /// 显示食品清单
        /// 显示食品清单25
 /// </summary>
        /// </summary>26
 public void Show()
        public void Show()27
 {
        {28
 IDictionaryEnumerator myEnumerator  = food.GetEnumerator();
            IDictionaryEnumerator myEnumerator  = food.GetEnumerator();29
 Console.WriteLine("Food List:");
            Console.WriteLine("Food List:");30
 Console.WriteLine("------------------------------");
            Console.WriteLine("------------------------------");31
 string strfoodlist = "";
            string strfoodlist = "";32
 while(myEnumerator.MoveNext())
            while(myEnumerator.MoveNext())33
 {
            {34
 strfoodlist = strfoodlist + "\n\n" + myEnumerator.Key.ToString();
                strfoodlist = strfoodlist + "\n\n" + myEnumerator.Key.ToString();35
 strfoodlist = strfoodlist + ":\t" +myEnumerator.Value.ToString();
                strfoodlist = strfoodlist + ":\t" +myEnumerator.Value.ToString();36
 }
            }37
 Console.WriteLine(strfoodlist);
            Console.WriteLine(strfoodlist);38
 Console.WriteLine("\n------------------------------");
            Console.WriteLine("\n------------------------------");39
 }
        }40
 }
    }41
 }
}42

2.指导者通知建造器。收银员(指导者)告知餐馆员工准备套餐。这里我们准备套餐的顺序是:放入汉堡,可乐倒入杯中,薯条放入盒中,并把这些东西都放在盘子上。这个过程对于普通套餐和黄金套餐来说都是一样的,不同的是它们的汉堡,可乐,薯条价格不同而已。如时序图红色部分所示:

程序实现:
 using System;
using System;2

3
 namespace KFC
namespace KFC4
 {
{5
 /// <summary>
    /// <summary>6
 /// FoodManager类,即指导者
    /// FoodManager类,即指导者7
 /// </summary>
    /// </summary>8
 public class FoodManager
    public class FoodManager9
 {
    {10
 public void Construct(Builder builder)
        public void Construct(Builder builder)11
 {
        {12
 builder.BuildHamb();
            builder.BuildHamb();13

14
 builder.BuildCoke();
            builder.BuildCoke();15

16
 builder.BuildChip();
            builder.BuildChip();17
 }
        }    18
 }
    }19
 }
}20

3.建造者处理指导者的要求,并将部件添加到产品中。餐馆员工(建造者)按照收银员要求的把对应的汉堡,可乐,薯条放入盘子中。这部分是建造者模式里面富于变化的部分,因为顾客选择的套餐不同,套餐的组装过程也不同,这步完成产品对象的创建工作。
程序实现:
 using System;
using System;2

3
 namespace KFC
namespace KFC4
 {
{5
 /// <summary>
    /// <summary>6
 /// Builder类,即抽象建造者类,构造套餐
    /// Builder类,即抽象建造者类,构造套餐7
 /// </summary>
    /// </summary>8
 public abstract class Builder
    public abstract class Builder9
 {
    {    10
 /// <summary>
        /// <summary>11
 /// 添加汉堡
        /// 添加汉堡12
 /// </summary>
        /// </summary>13
 public abstract void BuildHamb();
        public abstract void BuildHamb();14
 
        15
 /// <summary>
        /// <summary>16
 /// 添加可乐
        /// 添加可乐17
 /// </summary>
        /// </summary>18
 public abstract void BuildCoke();
        public abstract void BuildCoke();19
 
        20
 /// <summary>
        /// <summary>21
 /// 添加薯条
        /// 添加薯条22
 /// </summary>
        /// </summary>23
 public abstract void BuildChip();
        public abstract void BuildChip();24
 
        25
 /// <summary>
        /// <summary>26
 /// 返回结果
        /// 返回结果27
 /// </summary>
        /// </summary>28
 /// <returns>食品对象</returns>
        /// <returns>食品对象</returns>29
 public abstract Food GetFood();
        public abstract Food GetFood();30
 }
    }31
 }
}32

 using System;
using System;2

3
 namespace KFC
namespace KFC4
 {
{5
 /// <summary>
    /// <summary>6
 /// NormalBuilder类,具体构造者,普通套餐
    /// NormalBuilder类,具体构造者,普通套餐7
 /// </summary>
    /// </summary>8
 public class NormalBuilder:Builder
    public class NormalBuilder:Builder9
 {
    {10
 private Food NormalFood = new Food();
        private Food NormalFood = new Food();11

12
 public override void BuildHamb()
        public override void BuildHamb()13
 {
        {14
 NormalFood.Add("NormalHamb","¥10.50");
            NormalFood.Add("NormalHamb","¥10.50");15
 }
        }16
 
        17
 public override void BuildCoke()
        public override void BuildCoke()18
 {
        {19
 NormalFood.Add("CokeCole","¥4.50");
            NormalFood.Add("CokeCole","¥4.50");20
 }
        }21

22
 public override void BuildChip()
        public override void BuildChip()23
 {
        {24
 NormalFood.Add("FireChips","¥2.00");
            NormalFood.Add("FireChips","¥2.00");25
 }
        }26

27
 public override Food GetFood()
        public override Food GetFood()28
 {
        {29
 return NormalFood;
            return NormalFood;30
 }
        }31

32
 }
    }33
 }
}34

 using System;
using System;2

3
 namespace KFC
namespace KFC4
 {
{5
 /// <summary>
    /// <summary>6
 /// GoldBuilder类,具体构造者,黄金套餐
    /// GoldBuilder类,具体构造者,黄金套餐7
 /// </summary>
    /// </summary>8
 public class GoldBuilder:Builder
    public class GoldBuilder:Builder9
 {
    {10
 private Food GoldFood = new Food();
        private Food GoldFood = new Food();11

12
 public override void BuildHamb()
        public override void BuildHamb()13
 {
        {14
 GoldFood.Add("GoldHamb","¥13.50");
            GoldFood.Add("GoldHamb","¥13.50");15
 }
        }16
 
        17
 public override void BuildCoke()
        public override void BuildCoke()18
 {
        {19
 GoldFood.Add("CokeCole","¥4.50");
            GoldFood.Add("CokeCole","¥4.50");20
 }
        }21

22
 public override void BuildChip()
        public override void BuildChip()23
 {
        {24
 GoldFood.Add("FireChips","¥3.50");
            GoldFood.Add("FireChips","¥3.50");25
 }
        }26

27
 public override Food GetFood()
        public override Food GetFood()28
 {
        {29
 return GoldFood;
            return GoldFood;30
 }
        }31

32
 }
    }33
 }
}34

4.客户从建造者检索产品。从餐馆员工准备好套餐后,顾客再从餐馆员工那儿拿回套餐。这步客户程序要做的仅仅是取回已经生成的产品对象,如时序图中红色部分所示。

完整的客户程序:
 using System;
using System;2
 using System.Configuration;
using System.Configuration;3
 using System.Reflection;
using System.Reflection;4

5
 namespace KFC
namespace KFC6
 {
{7
 /// <summary>
    /// <summary>8
 /// Client 类
    /// Client 类9
 /// </summary>
    /// </summary>10
 public class Client
    public class Client11
 {
    {12
 public static void Main(string[] args)
        public static void Main(string[] args)13
 {
        {14
 FoodManager foodmanager = new FoodManager();
            FoodManager foodmanager = new FoodManager();15

16
 Builder instance;
            Builder instance;17

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

20
 string No = Console.ReadLine();
            string No = Console.ReadLine();21

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

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

26
 foodmanager.Construct(instance);
            foodmanager.Construct(instance);27

28
 Food food = instance.GetFood();
            Food food = instance.GetFood();29
 food.Show();
            food.Show();30

31
 Console.ReadLine();
            Console.ReadLine();32
 }
        }33
 }
    }34
 }
}35

通过分析不难看出,在这个例子中,在准备套餐的过程是稳定的,即按照一定的步骤去做,而套餐的组成部分则是变化的,有可能是普通套餐或黄金套餐等。这个变化就是建造者模式中的“变化点“,就是我们要封装的部分。
另外一个例子
在这里我们再给出另外一个关于建造房子的例子。客户程序通过调用指导者 (CDirector class)的BuildHouse()方法来创建一个房子。该方法有一个布尔型的参数blnBackyard,当blnBackyard为假时指导者将创建一个Apartment(Concrete Builder),当它为真时将创建一个Single Family Home(Concrete Builder)。这两种房子都实现了接口Ihouse。
程序实现:
 //关于建造房屋的例子
//关于建造房屋的例子2
 using System;
using System;3
 using System.Collections;
using System.Collections;4

5
 /// <summary>
/// <summary>6
 /// 抽象建造者
/// 抽象建造者7
 /// </summary>
/// </summary>8
 public interface IHouse
public interface IHouse9
 {
{10
 bool GetBackyard();
    bool GetBackyard();11
 long NoOfRooms();
    long NoOfRooms();12
 string  Description();
    string  Description();13
 }
}14

15
 /// <summary>
/// <summary>16
 /// 具体建造者
/// 具体建造者17
 /// </summary>
/// </summary>18
 public class CApt:IHouse
public class CApt:IHouse19
 {
{20
 private bool mblnBackyard;
    private bool mblnBackyard;21
 private Hashtable Rooms;
    private Hashtable Rooms;22
 public CApt()
    public CApt()23
 {
    {24
 CRoom room;
        CRoom room;    25
 Rooms = new Hashtable();
        Rooms = new Hashtable();26
 room = new CRoom();
        room = new CRoom();27
 room.RoomName = "Master Bedroom";
        room.RoomName = "Master Bedroom";28
 Rooms.Add ("room1",room);
        Rooms.Add ("room1",room);29

30
 room = new CRoom();
        room = new CRoom();31
 room.RoomName = "Second Bedroom";
        room.RoomName = "Second Bedroom";32
 Rooms.Add ("room2",room);
        Rooms.Add ("room2",room);33

34
 room = new CRoom();
        room = new CRoom();35
 room.RoomName = "Living Room";
        room.RoomName = "Living Room";36
 Rooms.Add ("room3",room);
        Rooms.Add ("room3",room);37
 
        38
 mblnBackyard = false;
        mblnBackyard = false;39
 }
    }40

41
 public bool GetBackyard()
    public bool GetBackyard()42
 {
    {43
 return mblnBackyard;
        return mblnBackyard;44
 }
    }45
 public long NoOfRooms()
    public long NoOfRooms()46
 {
    {47
 return Rooms.Count;
        return Rooms.Count; 48
 }
    }49
 public string  Description()
    public string  Description()50
 {
    {51
 IDictionaryEnumerator myEnumerator  = Rooms.GetEnumerator();
        IDictionaryEnumerator myEnumerator  = Rooms.GetEnumerator();52
 string strDescription;
        string strDescription;53
 strDescription = "This is an Apartment with " + Rooms.Count + " Rooms \n";
        strDescription = "This is an Apartment with " + Rooms.Count + " Rooms \n";54
 strDescription = strDescription + "This Apartment doesn't have a backyard \n";
        strDescription = strDescription + "This Apartment doesn't have a backyard \n";                        55
 while (myEnumerator.MoveNext())
        while (myEnumerator.MoveNext())56
 {
        {57
 strDescription = strDescription + "\n" + myEnumerator.Key + "\t" + ((CRoom)myEnumerator.Value).RoomName;
            strDescription = strDescription + "\n" + myEnumerator.Key + "\t" + ((CRoom)myEnumerator.Value).RoomName;58
 }
        }59
 return strDescription;
        return strDescription;60
 }
    }61
 }
}62

63
 /// <summary>
/// <summary>64
 /// 具体建造者
/// 具体建造者65
 /// </summary>
/// </summary>66
 public class CSFH:IHouse
public class CSFH:IHouse67
 {
{68
 private bool mblnBackyard;
    private bool mblnBackyard;69
 private Hashtable Rooms;
    private Hashtable Rooms;70
 public CSFH()
    public CSFH()71
 {
    {72
 CRoom room;
        CRoom room;73
 Rooms = new Hashtable();
        Rooms = new Hashtable();74

75
 room = new CRoom();
        room = new CRoom();76
 room.RoomName = "Master Bedroom";
        room.RoomName = "Master Bedroom";77
 Rooms.Add ("room1",room);
        Rooms.Add ("room1",room);78

79
 room = new CRoom();
        room = new CRoom();80
 room.RoomName = "Second Bedroom";
        room.RoomName = "Second Bedroom";81
 Rooms.Add ("room2",room);
        Rooms.Add ("room2",room);82

83
 room = new CRoom();
        room = new CRoom();84
 room.RoomName = "Third Room";
        room.RoomName = "Third Room";85
 Rooms.Add ("room3",room);
        Rooms.Add ("room3",room);86
 
        87
 room = new CRoom();
        room = new CRoom();88
 room.RoomName = "Living Room";
        room.RoomName = "Living Room";89
 Rooms.Add ("room4",room);
        Rooms.Add ("room4",room);90

91
 room = new CRoom();
        room = new CRoom();92
 room.RoomName = "Guest Room";
        room.RoomName = "Guest Room";93
 Rooms.Add ("room5",room);
        Rooms.Add ("room5",room);94

95
 mblnBackyard = true;
        mblnBackyard = true;96
 
 97
 }
    }98

99
 public bool GetBackyard()
    public bool GetBackyard()100
 {
    {101
 return mblnBackyard;
        return mblnBackyard;102
 }
    }103
 public long NoOfRooms()
    public long NoOfRooms()104
 {
    {105
 return Rooms.Count;
        return Rooms.Count;106
 }
    }107
 public string  Description()
    public string  Description()108
 {
    {109
 IDictionaryEnumerator myEnumerator  = Rooms.GetEnumerator();
        IDictionaryEnumerator myEnumerator  = Rooms.GetEnumerator();110
 string strDescription;
        string strDescription;111
 strDescription = "This is an Single Family Home with " + Rooms.Count + " Rooms \n";
        strDescription = "This is an Single Family Home with " + Rooms.Count + " Rooms \n";112
 strDescription = strDescription + "This house has a backyard \n";
        strDescription = strDescription + "This house has a backyard \n"; 113
 while (myEnumerator.MoveNext())
        while (myEnumerator.MoveNext())114
 {
        {115
 strDescription = strDescription + "\n" + myEnumerator.Key + "\t" + ((CRoom)myEnumerator.Value).RoomName;
            strDescription = strDescription + "\n" + myEnumerator.Key + "\t" + ((CRoom)myEnumerator.Value).RoomName; 116
 }
        }      117
 return strDescription;
        return strDescription;118
 }
    }119
 }
}120

121
 public interface IRoom
public interface IRoom122
 {
{123
 string RoomName{get;set;}
    string RoomName{get;set;}124
 }
}125

126
 public class CRoom:IRoom
public class CRoom:IRoom127
 {
{128
 private string mstrRoomName;
    private string mstrRoomName;129
 public string RoomName
    public string RoomName130
 {
    {131
 get
        get132
 {
        {133
 return mstrRoomName;
            return mstrRoomName;134
 }
        }135
 set
        set 136
 {
        {137
 mstrRoomName = value;
            mstrRoomName = value;138
 }
        }139
 }
    }140
 }
}141

142
 /// <summary>
/// <summary>143
 /// 指导者
/// 指导者144
 /// </summary>
/// </summary>145
 public class CDirector
public class CDirector146
 {
{147
 public IHouse BuildHouse(bool blnBackyard)
    public IHouse BuildHouse(bool blnBackyard)148
 {
    {149
 if (blnBackyard)
        if (blnBackyard)150
 {
        {151
 return new CSFH();
            return new CSFH();152
 }
        }153
 else
        else154
 {
        {155
 return new CApt();
            return new CApt(); 156
 }
        }157
 }
    }158
 }
}159

160
 /// <summary>
/// <summary>161
 /// 客户程序
/// 客户程序162
 /// </summary>
/// </summary>163
 public class Client
public class Client164
 {
{165
 static void Main(string[] args)
    static void Main(string[] args) 166
 {
    {167
 CDirector objDirector = new CDirector();
        CDirector objDirector = new CDirector();168
 IHouse objHouse;
        IHouse objHouse;169

170
 string Input = Console.ReadLine();
        string Input = Console.ReadLine();171
 objHouse = objDirector.BuildHouse(bool.Parse(Input));
        objHouse = objDirector.BuildHouse(bool.Parse(Input));172
 
    173
 Console.WriteLine(objHouse.Description());
        Console.WriteLine(objHouse.Description());174
 Console.ReadLine();
        Console.ReadLine();175
 }
    }176
 }
}177

178

建造者模式的几种演化
省略抽象建造者角色
系统中只需要一个具体建造者,省略掉抽象建造者,结构图如下:

指导者代码如下:
 class Director
 class Director2
 {
  {3
 private ConcreteBuilder builder;
   private ConcreteBuilder builder;4
 
 5
 public void Construct()
   public void Construct()6
 {
    {7
 builder.BuildPartA();
     builder.BuildPartA();8
 builder.BuildPartB();
     builder.BuildPartB();9
 }
   }10
 }
 }省略指导者角色
抽象建造者角色已经被省略掉,还可以省略掉指导者角色。让Builder角色自己扮演指导者与建造者双重角色。结构图如下:

建造者角色代码如下:
 public class Builder
 public class Builder2
 {
  {3
 private Product product = new Product();
   private Product product = new Product();4
 
 5
 public void BuildPartA()
   public void BuildPartA()6
 {
    { 7
 //
     //

8
 }
   }9
 
 10
 public void BuildPartB()
   public void BuildPartB()11
 {
    {12
 //
     //

13
 }
   }14
 
 15
 public Product GetResult()
   public Product GetResult()16
 {
    {17
 return product;
     return product;18
 }
   }19
 
 20
 public void Construct()
   public void Construct()21
 {
    {22
 BuildPartA();
     BuildPartA();23
 BuildPartB();
     BuildPartB();24
 }
   }25
 }
 }客户程序:
 public class Client
 public class Client2
 {
  {3
 private static Builder builder;
   private static Builder builder;4
 
 5
 public static void Main()
   public static void Main()6
 {
    {7
 builder = new Builder();
     builder = new Builder();8
 builder.Construct();
     builder.Construct();9
 Product product = builder.GetResult();
     Product product = builder.GetResult();10
 }
   }11
 }
 }合并建造者角色和产品角色
建造模式失去抽象建造者角色和指导者角色后,可以进一步退化,从而失去具体建造者角色,此时具体建造者角色和产品角色合并,从而使得产品自己就是自己的建造者。这样做混淆了对象的建造者和对象本身,但是有时候一个产品对象有着固定的几个零件,而且永远只有这几个零件,此时将产品类和建造类合并,可以使系统简单易读。结构图如下:

实现要点
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、   ……
总结
建造者模式的实质是解耦组装过程和创建具体部件,使得我们不用去关心每个部件是如何组装的。
______________________________________________________________________________________
源程序下载:/Files/Terrylee/BuilderPattern.rar
参考资料:
《Java与设计模式》阎宏 著
《设计模式(中文版)》
《DesignPatternsExplained》
出处:http://terrylee.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 
                    
                 

 
     
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号