當對象擁有重要屬性且須按特定順序賦值,或屬性間存在依賴時,構建邏輯變得複雜。建造者模式將此「零件組裝過程」外部化到建造者對象,客戶端獲得的是完整構建好的產品。名為「建造」而非「生成」,強調從零件組裝產品的過程性。

指導者將客戶請求分解為零件建造請求,委派給具體建造者;具體建造者執行具體工作,對客戶端透明。
// Builder pattern -- Structural example
using System; using System.Collections;
class Director {
public void Construct(Builder builder) {
builder.BuildPartA(); builder.BuildPartB();
}
}
abstract class Builder {
abstract public void BuildPartA();
abstract public void BuildPartB();
abstract public Product GetResult();
}
class ConcreteBuilder1 : Builder {
private Product product;
override public void BuildPartA() { product = new Product(); product.Add("PartA"); }
override public void BuildPartB() { product.Add("PartB"); }
override public Product GetResult() { return product; }
}
class ConcreteBuilder2 : Builder {
private Product product;
override public void BuildPartA() { product = new Product(); product.Add("PartX"); }
override public void BuildPartB() { product.Add("PartY"); }
override public Product GetResult() { return product; }
}
class Product {
ArrayList parts = new ArrayList();
public void Add(string part) { parts.Add(part); }
public void Show() {
Console.WriteLine("Product Parts -------");
foreach (string part in parts) Console.WriteLine(part);
}
}
public class Client {
public static void Main() {
Director director = new Director();
Builder b1 = new ConcreteBuilder1(), b2 = new ConcreteBuilder2();
director.Construct(b1); b1.GetResult().Show();
director.Construct(b2); b2.GetResult().Show();
}
}
// Builder pattern -- Real World example
using System; using System.Collections;
class Shop {
public void Construct(VehicleBuilder vb) {
vb.BuildFrame(); vb.BuildEngine(); vb.BuildWheels(); vb.BuildDoors();
}
}
abstract class VehicleBuilder {
protected Vehicle vehicle;
public Vehicle Vehicle { get { return vehicle; } }
abstract public void BuildFrame();
abstract public void BuildEngine();
abstract public void BuildWheels();
abstract public void BuildDoors();
}
class MotorCycleBuilder : VehicleBuilder {
override public void BuildFrame() { vehicle = new Vehicle("MotorCycle"); vehicle["frame"] = "MotorCycle Frame"; }
override public void BuildEngine() { vehicle["engine"] = "500 cc"; }
override public void BuildWheels() { vehicle["wheels"] = "2"; }
override public void BuildDoors() { vehicle["doors"] = "0"; }
}
class CarBuilder : VehicleBuilder {
override public void BuildFrame() { vehicle = new Vehicle("Car"); vehicle["frame"] = "Car Frame"; }
override public void BuildEngine() { vehicle["engine"] = "2500 cc"; }
override public void BuildWheels() { vehicle["wheels"] = "4"; }
override public void BuildDoors() { vehicle["doors"] = "4"; }
}
class ScooterBuilder : VehicleBuilder {
override public void BuildFrame() { vehicle = new Vehicle("Scooter"); vehicle["frame"] = "Scooter Frame"; }
override public void BuildEngine() { vehicle["engine"] = "none"; }
override public void BuildWheels() { vehicle["wheels"] = "2"; }
override public void BuildDoors() { vehicle["doors"] = "0"; }
}
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 void Show() {
Console.WriteLine("---------------------------");
Console.WriteLine("Vehicle Type: " + type);
Console.WriteLine(" Frame : " + parts["frame"]);
Console.WriteLine(" Engine : " + parts["engine"]);
Console.WriteLine(" #Wheels: " + parts["wheels"]);
Console.WriteLine(" #Doors : " + parts["doors"]);
}
}
public class BuilderApp {
public static void Main() {
Shop shop = new Shop();
VehicleBuilder b1 = new ScooterBuilder(), b2 = new CarBuilder(), b3 = new MotorCycleBuilder();
shop.Construct(b1); b1.Vehicle.Show();
shop.Construct(b2); b2.Vehicle.Show();
shop.Construct(b3); b3.Vehicle.Show();
}
}
僅有一個具體建造者時,可移除抽象介面,指導者直接依賴具體類。
若抽象建造者已省略,可讓建造者自身承擔指導者職責(如 StringBuilder):
public class Builder {
private Product product = new Product();
public void BuildPartA() { /* ... */ }
public void BuildPartB() { /* ... */ }
public Product GetResult() { return product; }
public void Construct() { BuildPartA(); BuildPartB(); }
}
適用場景:
核心優勢: