设计模式:建造者模式(Builder Pattern)
作者:TerryLee 创建于:2006-01-04 出处: http://terrylee.cnblogs.com/archive/2006/01/04/310716.html 收录于:2013-02-28
模型图
意图
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
适用性
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 当构造过程必须允许被构造的对象有不同的表示时。
代码实现
示例概述:
客户端:顾客。想去买一套套餐(这里面包括汉堡,可乐,薯条),可以有1号和2号两种套餐供顾客选择。
指导者角色:收银员。知道顾客想要买什么样的套餐,并告诉餐馆员工去准备套餐。
建造者角色:餐馆员工。按照收银员的要求去准备具体的套餐,分别放入汉堡,可乐,薯条等。
产品角色:最后的套餐,所有的东西放在同一个盘子里面。
KFC店买套餐代码如下:
1 using System; 2 using System.Collections; 3 using System.Reflection; 4 namespace KFC 5 { 6 // Food类,即产品类 7 public class Food 8 { 9 Hashtable food = new Hashtable(); 10 // 添加食品 11 public void Add(string strName, string Price) 12 { 13 food.Add(strName, Price); 14 } 15 // 显示食品清单 16 public void Show() 17 { 18 IDictionaryEnumerator myEnumerator = food.GetEnumerator(); 19 Console.WriteLine("Food List:"); 20 Console.WriteLine("------------------------------"); 21 string strfoodlist = ""; 22 while (myEnumerator.MoveNext()) 23 { 24 strfoodlist = strfoodlist + "\n\n" + myEnumerator.Key.ToString(); 25 strfoodlist = strfoodlist + ":\t" + myEnumerator.Value.ToString(); 26 } 27 Console.WriteLine(strfoodlist); 28 Console.WriteLine("\n------------------------------"); 29 } 30 } 31 // Builder类,即抽象建造者类,构造套餐 32 public abstract class Builder 33 { 34 // 添加汉堡 35 public abstract void BuildHamb(); 36 // 添加可乐 37 public abstract void BuildCoke(); 38 // 添加薯条 39 public abstract void BuildChip(); 40 // 返回结果 41 public abstract Food GetFood(); 42 } 43 // GoldBuilder类,具体构造者,黄金套餐 44 public class GoldBuilder : Builder 45 { 46 private Food GoldFood = new Food(); 47 public override void BuildHamb() 48 { 49 GoldFood.Add("GoldHamb", "¥13.50"); 50 } 51 public override void BuildCoke() 52 { 53 GoldFood.Add("CokeCole", "¥4.50"); 54 } 55 public override void BuildChip() 56 { 57 GoldFood.Add("FireChips", "¥3.50"); 58 } 59 public override Food GetFood() 60 { 61 return GoldFood; 62 } 63 } 64 // NormalBuilder类,具体构造者,普通套餐 65 public class NormalBuilder : Builder 66 { 67 private Food NormalFood = new Food(); 68 public override void BuildHamb() 69 { 70 NormalFood.Add("NormalHamb", "¥10.50"); 71 } 72 public override void BuildCoke() 73 { 74 NormalFood.Add("CokeCole", "¥4.50"); 75 } 76 public override void BuildChip() 77 { 78 NormalFood.Add("FireChips", "¥2.00"); 79 } 80 public override Food GetFood() 81 { 82 return NormalFood; 83 } 84 } 85 // FoodManager类,即指导者 86 public class FoodManager 87 { 88 public void Construct(Builder builder) 89 { 90 builder.BuildHamb(); 91 builder.BuildCoke(); 92 builder.BuildChip(); 93 } 94 } 95 // Client 类 96 public class Client 97 { 98 public static void Main(string[] args) 99 { 100 FoodManager foodmanager = new FoodManager(); 101 Builder instance; 102 Console.WriteLine("Please Enter Food No:"); 103 string No = Console.ReadLine(); 104 105 string foodType =System.Configuration.ConfigurationManager.AppSettings["No" + No]; 106 instance = (Builder)Assembly.Load("KFC").CreateInstance("KFC." + foodType); 107 foodmanager.Construct(instance); 108 Food food = instance.GetFood(); 109 food.Show(); 110 Console.ReadLine(); 111 } 112 } 113 } 114 App.config 115 116 <?xml version="1.0" encoding="utf-8" ?> 117 <configuration> 118 <appSettings> 119 <add key="No1" value="NormalBuilder"></add> 120 <add key="No2" value="GoldBuilder"></add> 121 </appSettings> 122 </configuration>
实现要点
1、建造者模式主要用于“分步骤构建一个复杂的对象”,在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
2、产品不需要抽象类,特别是由于创建对象的算法复杂而导致使用此模式的情况下或者此模式应用于产品的生成过程,其最终结果可能差异很大,不大可能提炼出一个抽象产品类。
3、Builder模式解决“对象部分”的需求变化,建造者模式常和组合模式(Composite
Pattern)结合使用。
效果
1、建造者模式的使用使得产品的内部表象可以独立的变化。使用建造者模式可以使客户端不必知道产品内部组成的细节。
2、每一个Builder都相对独立,而与其它的Builder无关。
3、可使对构造过程更加精细控制。
4、将构建代码和表示代码分开。
5、建造者模式的缺点在于难于应付“分步骤构建算法”的需求变动。