动机:在软件系统中,有时候面临着“一个复杂对象”的创建工作, 其通常由各个部分的子对象用一定的算法构成;由于需求的变化, 这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起 的算法却相对稳定;如何应对这种变化?如何提供一种“封装机制”来隔离复杂对象的各个部分的变化,从而保持系统中的“稳定构建算法不随需求的 改变而改变
意图:将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。——《设计模式》GOF
可适用性:当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。当构造过程必须允许被构造的对象有不同的表示时。
UML图解:
示例代码:游戏场景中Builder模式的应用
house.cs文件代码:
1 public abstract class House 2 { 3 4 } 5 6 public abstract class Door 7 { 8 9 } 10 public abstract class Windows 11 { 12 13 } 14 public abstract class Floor 15 { 16 17 } 18 public abstract class Wall 19 { 20 21 }
RomainHouse.cs文件代码:
1 public class RomainHouse:House 2 { 3 4 } 5 public class RomainDoor : Door 6 { 7 8 } 9 public class RomainWindows : Windows 10 { 11 12 } 13 public class RomainWall : Wall 14 { 15 16 } 17 18 public class RomainFloor : Floor 19 { 20 21 }
Builder.cs文件代码:
1 /// <summary> 2 /// 游戏中的房屋生成器(抽象层次) 3 /// </summary> 4 public abstract class Builder 5 { 6 public abstract void BuildDoor(); 7 public abstract void BuildWall(); 8 public abstract void BuildWindows(); 9 public abstract void BuildFloor(); 10 public abstract void BuildHouseCeiling(); 11 12 public abstract House GetHouse(); 13 } 14 15 /// <summary> 16 /// 具体罗马房屋生成器 17 /// </summary> 18 public class RomainHouseBuilder : Builder 19 { 20 21 public override void BuildDoor() 22 { 23 //TODO:door... 24 } 25 26 public override void BuildWall() 27 { 28 //TODO:wall... 29 } 30 31 public override void BuildWindows() 32 { 33 //TODO:windows... 34 } 35 36 public override void BuildFloor() 37 { 38 //TODO:floor... 39 } 40 41 public override void BuildHouseCeiling() 42 { 43 //TODO:build a house... 44 } 45 46 public override House GetHouse() 47 { 48 return new RomainHouse(); 49 } 50 }
客户程序及调用代码:
1 /// <summary> 2 /// 客户程序 3 /// </summary> 4 public class GameManager 5 { 6 //构建过程(即算法是不经常变化的)是稳定的... 7 public static House CreateHouse(Builder builder) 8 { 9 builder.BuildDoor(); 10 builder.BuildDoor(); 11 12 builder.BuildWindows(); 13 builder.BuildWindows(); 14 builder.BuildWindows(); 15 builder.BuildWindows(); 16 17 builder.BuildWall(); 18 builder.BuildWall(); 19 builder.BuildWall(); 20 builder.BuildWall(); 21 22 builder.BuildFloor(); 23 builder.BuildFloor(); 24 25 builder.BuildHouseCeiling(); 26 27 return builder.GetHouse(); 28 } 29 } 30 31 public class App 32 { 33 public static void Main() 34 { 35 /*** 36 * 当房屋的风格变化时,只需要继承Builder实现其对应的具体风格房屋的生成器即可 37 * 而客户代码可以通过配置文件的形式,通过.NET的反射机制调用改变后的具体生成器 38 * ***/ 39 //从配置文件中动态加载具体房屋生成器dll,保证了客户代码的稳定性;即当你的应用程序 40 //版本升级时,你只需要将改变的dll给用户,另者再修改一下配置文件即可扩展此程序 41 string assemblyName=ConfigurationManager.AppSettings["BuilderAssembly"]; 42 string builderName=ConfigurationManager.AppSettings["BuilderName"]; 43 Assembly builderAssembly = Assembly.Load(assemblyName); 44 Type builderType = builderAssembly.GetType(builderName); 45 Builder builder =(Builder)Activator.CreateInstance(builderType); 46 47 House house = GameManager.CreateHouse(builder); 48 49 //House house=GameManager.CreateHouse(new RomainHouseBuilder()); 50 } 51 }
注:本示例代码是本人学习Webcast C#面向对象设计模式纵横谈系列讲座视频时,跟着李建忠老师一步一步的编写的,在此奉献出来,仅供大家参考