(一)定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们。用户不知道内部的具体构建细节。
UML类图:抽象不应该依赖细节,细节应该依赖于抽象
(二)类与对象之间的关系:
Builder:抽象建造者。为创建一个Product对象的各个部件指定抽象接口。
ConcreteBuilder:具体建造者。实现Builder接口。
❶ 构造和装配产品的各个部件。
❷ 定义并明确它所创建的表示。
❸ 提供一个返回这个产品的接口。
Director:指挥者。构建一个使用Builder接口的对象。
Product:产品角色。
❶ 被构建的复杂对象,具体建造者创建该产品的内部表示并定义它的装配过程。
❷ 包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
(三)时序图:
(四)4.1 案例分析:车间造车
车间装配车辆是分步骤完成的复杂装配过程,车行采用不同的车间装配出不同的车辆。但是每个车辆装配的过程是稳定的,不同是会根据不同的需求装配出不同的车辆。因此可以将该问的处理采用生成器模式来解决。
类关系图如下:
代码如下:


源码using System; using System.Collections; using System.Text; namespace 设计模式.生成器模式 { public class Shop { public Shop(VehicleBuilder vehicleBuilder) //聚合关系,从构造函数传参来构建类 { vehicleBuilder.BuildFrame(); vehicleBuilder.BuildEngine(); vehicleBuilder.BuildWheels(); vehicleBuilder.BuildDoors(); } } public abstract class VehicleBuilder { protected Vehicle vehicle; public Vehicle Vehicle { get { return vehicle; } } public abstract void BuildFrame(); public abstract void BuildEngine(); public abstract void BuildWheels(); public abstract void BuildDoors(); } public class MotorCycleBuilder : VehicleBuilder { public override void BuildFrame() { vehicle = new Vehicle("摩托车"); vehicle["frame"] = "MotorCycle Frame"; } public override void BuildEngine() { vehicle["engine"] = "500 CC"; } public override void BuildWheels() { vehicle["wheels"] = "2"; } public override void BuildDoors() { vehicle["doors"] = "0"; } } public class CarBuilder : VehicleBuilder { public override void BuildFrame() { vehicle = new Vehicle("轿车"); vehicle["frame"] = "Car Frame"; } public override void BuildEngine() { vehicle["engine"] = "2500 CC"; } public override void BuildWheels() { vehicle["wheels"] = "4"; } public override void BuildDoors() { vehicle["doors"] = "4"; } } public class ScooterBuilder : VehicleBuilder { public override void BuildFrame() { vehicle = new Vehicle("单脚滑行车"); vehicle["frame"] = "Scooter Frame"; } public override void BuildEngine() { vehicle["engine"] = "none"; } public override void BuildWheels() { vehicle["wheels"] = "2"; } public override void BuildDoors() { vehicle["doors"] = "0"; } } public class Vehicle { private string type; private Hashtable parts = new Hashtable(); public Vehicle(string type) { this.type = type; } public object this[string key] { get { return parts[key]; } set { parts[key] = value; } } public string Show() { Console.WriteLine(" ----------------------------------"); Console.WriteLine("车辆类型:" + type); Console.WriteLine(" 框架:" + parts["frame"]); Console.WriteLine(" 发动机:" + parts["engine"]); Console.WriteLine(" #轮子数:" + parts["wheels"]); Console.WriteLine(" #车门数:" + parts["doors"]); StringBuilder sb=new StringBuilder(); sb.AppendFormat("车辆类型:{0}",type).AppendLine(); sb.AppendFormat(" 框架:{0}",parts["frame"]).AppendLine(); sb.AppendFormat(" 发动机:{0}",parts["engine"]).AppendLine(); sb.AppendFormat(" #轮子数:{0}", parts["wheels"]).AppendLine(); sb.AppendFormat(" #车门数:{0}" , parts["doors"]); return sb.ToString(); } } }
4.2 案例分析:房屋构建


代码实现class Program { static void Main(string[] args) { IHouse house = BuildHouse(false); Console.WriteLine(house.Description()); Console.ReadKey(); } public static IHouse BuildHouse(bool isBackyard) { if (isBackyard) { return new SingleFamilyHouse(); } else { return new Aparement(); } } } public interface IHouse { Boolean GetBackyard(); long NoOfRooms(); string Description(); } public class Room { public string RoomName { get; set; } } public class Aparement : IHouse { private Boolean isBackyard; //是否带院子 private List<Room> rooms; public Aparement() { rooms = new List<Room>(); Room room = new Room(); //与Room类形成组合关系 room.RoomName = "Master Room"; rooms.Add(room); room = new Room(); room.RoomName = "Second BedRoom"; rooms.Add(room); room = new Room(); room.RoomName = "Living Room"; rooms.Add(room); isBackyard = false; } public bool GetBackyard() { return isBackyard; } public long NoOfRooms() { return rooms.Count; } public string Description() { StringBuilder strDescript = new StringBuilder(); strDescript.AppendFormat("这是一间公寓,有{0}间房间,这间公寓没有后院", rooms.Count).AppendLine(); foreach (Room item in rooms) { strDescript.AppendFormat("{0}房间{1}", rooms.FindIndex(t => t.RoomName == item.RoomName), item.RoomName).AppendLine(); } return strDescript.ToString(); } } public class SingleFamilyHouse : IHouse { private bool isBackyard; private List<Room> rooms; public SingleFamilyHouse() { rooms = new List<Room>(); Room room = new Room(); //与Room类形式组合关系。 room.RoomName = "Master Room"; rooms.Add(room); room = new Room(); room.RoomName = "Second BedRoom"; rooms.Add(room); room = new Room(); room.RoomName = "Third BedRoom"; rooms.Add(room); room = new Room(); room.RoomName = "Guest BedRoom"; rooms.Add(room); room = new Room(); room.RoomName = "Living Room"; rooms.Add(room); isBackyard = true; } public bool GetBackyard() { return isBackyard; } public long NoOfRooms() { return rooms.Count; } public string Description() { StringBuilder strDescript = new StringBuilder(); strDescript.AppendFormat("这是一间公寓,有{0}间房间,这间公寓有后院", rooms.Count).AppendLine(); foreach (Room item in rooms) { strDescript.AppendFormat("{0}房间{1}", rooms.FindIndex(t => t.RoomName == item.RoomName), item.RoomName).AppendLine(); } return strDescript.ToString(); } }
(五)建造者模式的适用性及优缺点分析
优点:建造者模式使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体建造者就可以了。建造者模式将一个复杂对象的生成责任进行了很好的分配。它把构造过程放到指挥者的方法中,把装配过程放到具体建造者类中。建造者模式的产品之间都有共通点。
缺点:如果产品之间的差异性很大,这就需要借助工厂方法模式或抽象工厂模式。另外,如果产品的内部变化复杂,Builder的每一个子类都需要对应到不同的产品去做构建的动作,这就需要定义很多个具体建造者类来实现这种变化。
适用性:
① 创建复杂对象的算法是独立于它的组成部件及装配过程。
创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
② 构造的过程允许构造对象有不同的表现。