(一)定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们。用户不知道内部的具体构建细节。
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的每一个子类都需要对应到不同的产品去做构建的动作,这就需要定义很多个具体建造者类来实现这种变化。
适用性:
① 创建复杂对象的算法是独立于它的组成部件及装配过程。
创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
② 构造的过程允许构造对象有不同的表现。