设计模式学习之路——Builder 生成器模式
生成器模式有点类似于抽象工厂模式,两者都返回由许多方法和对象组成的类。它们之间的主要差别是,抽象工厂返回的是一系列相关的类,而生成器是根据提供给它的数据一步一步地构建一个复杂的对象。
动机:
在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?
意图:
将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
——《设计模式》GoF
结构:
协作:
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | using System; using System.Collections.Generic; using System.Text; namespace Builder { class Program { static void Main( string [] args) { Console.WriteLine( "true: 中式风格房屋,false:西式风格房屋" ); string Input = Console.ReadLine(); try { HouseBuilder builder = ClienManger.builder( bool .Parse(Input)); House chinaHouse = ClienManger.CreateHouse(builder); chinaHouse.Show(); } catch { Console.WriteLine( "输入错误!" ); } Console.ReadKey(); } } public class House { private List< string > door = new List< string >(); public List< string > Door { get { return door; } set { door = value; } } private List< string > windows = new List< string >(); public List< string > Windows { get { return windows; } set { windows = value; } } private string wall; public string Wall { get { return wall; } set { wall = value; } } private string floor; public string Floor { get { return floor; } set { floor = value; } } public void Show() { Console.WriteLine(Door.Count.ToString() + "个" + Door[0].ToString()); Console.WriteLine(Wall); Console.WriteLine(Windows.Count.ToString() + "个" + Windows[0].ToString()); Console.WriteLine(Floor); } } public abstract class HouseBuilder { public abstract void BuildDoor(); public abstract void BuildWall(); public abstract void BuildWindows(); public abstract void BuildFloor(); public abstract House GetHouse(); } public class ClienManger { public static House CreateHouse(HouseBuilder builder) { builder.BuildDoor(); builder.BuildFloor(); builder.BuildWall(); builder.BuildWindows(); return builder.GetHouse(); } public static HouseBuilder builder( bool bl) { if (bl) { return new ChinaHouseBuilder(); } else { return new EuroHouseBuilder(); } } } public class ChinaHouseBuilder : HouseBuilder { private House chinaHouse = new House(); public override void BuildDoor() { chinaHouse.Door.Add( "门(中国风格)" ); chinaHouse.Door.Add( "门(中国风格)" ); } public override void BuildWall() { chinaHouse.Wall = "墙(中国风格)" ; } public override void BuildWindows() { chinaHouse.Windows.Add( "窗(中国风格)" ); chinaHouse.Windows.Add( "窗(中国风格)" ); } public override void BuildFloor() { chinaHouse.Floor = "地板(中国风格)" ; } public override House GetHouse() { return chinaHouse; } } public class EuroHouseBuilder : HouseBuilder { private House EuroHouse = new House(); public override void BuildDoor() { EuroHouse.Door.Add( "门(欧洲风格)" ); } public override void BuildWall() { EuroHouse.Wall = "墙(欧洲风格)" ; } public override void BuildWindows() { EuroHouse.Windows.Add( "窗(欧洲风格)" ); } public override void BuildFloor() { EuroHouse.Floor = "地板(欧洲风格)" ; } public override House GetHouse() { return EuroHouse; } } } |
Builder 模式的几个要点:
1.Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
2.变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
3. Abstract Factory模式解决“系列对象”的需求变化,Builder模式解决“对象部分”的需求变化。Builder模式通常和Composite模式组合使用。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步