1 建造者模式簡介
1.1 定義
建造者模式(Builder)將復雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示。
1.2 使用頻率
中低
2 建造者模式結構
2.1 結構圖
2.2 參與者
建造者模式參與者:
◊ Builder:為創建一個Product對象的各個部件指定抽象接口;
◊ ConcreteBuilder
° 實現Builder的接口以構造和裝配該產品的各個部件
° 定義並明確它所創建的表示
° 提供一個檢索Product的接口
◊ Director:構造一個使用Builder接口的對象;
◊ Product
° 表示被構造的復雜對象。ConcreteBuilder創建該產品的內部表示並定義它的裝配過程
° 包含定義組成部件的類,包括將這些部件裝配成最終產品的接口
在建造者模式中,Director規定了創建一個對象所需要的步驟和次序,Builder則提供了一些列完成這些步驟的方法,ConcreteBuilder給出了這些方法的具體實現,是對象的直接創建者。
3 建造者模式結構實現
Product.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Structural { public class Product { private List<string> _parts = new List<string>(); public void Add(string part) { _parts.Add(part); } public void Show() { Console.WriteLine("Product Parts"); foreach (string part in _parts) { Console.WriteLine(part); } } } }
Builder.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Structural { public abstract class Builder { public abstract void BuildPartA(); public abstract void BuildPartB(); public abstract Product GetResult(); } }
ConcreteBuilder1.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Structural { public class ConcreteBuilder1 : Builder { private Product _product = new Product(); public override void BuildPartA() { _product.Add("PartA"); } public override void BuildPartB() { _product.Add("PartB"); } public override Product GetResult() { return _product; } } }
ConcreteBuilder2.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Structural { public class ConcreteBuilder2 : Builder { private Product _product = new Product(); public override void BuildPartA() { _product.Add("PartX"); } public override void BuildPartB() { _product.Add("PartY"); } public override Product GetResult() { return _product; } } }
Director.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Structural { public class Director { /// <summary> /// Builder uses a complex series of steps /// </summary> public void Construct(Builder builder) { builder.BuildPartA(); builder.BuildPartB(); } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using DesignPatterns.BuilderPattern.Structural; namespace DesignPatterns.BuilderPattern { class Program { static void Main(string[] args) { // Create director and builders Director director = new Director(); Builder b1 = new ConcreteBuilder1(); Builder b2 = new ConcreteBuilder2(); // Construct two products director.Construct(b1); Product p1 = b1.GetResult(); p1.Show(); director.Construct(b2); Product p2 = b2.GetResult(); p2.Show(); } } }
運行輸出:
Product Parts
PartA
PartB
Product Parts
PartX
PartY
請按任意鍵繼續. . .
4、建造者模式實踐應用
Vehicle.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Practical { /// <summary> /// The 'Product' class /// </summary> public class Vehicle { private string _vehicleType; private Dictionary<string, string> _parts = new Dictionary<string, string>(); /// <summary> /// Constructor /// </summary> public Vehicle(string vehicleType) { this._vehicleType = vehicleType; } /// <summary> /// Indexer /// </summary> public string this[string key] { get { return _parts[key]; } set { _parts[key] = value; } } public void Show() { Console.WriteLine("\n---------------------------"); Console.WriteLine("Vehicle Type: {0}", _vehicleType); Console.WriteLine(" Frame : {0}", _parts["frame"]); Console.WriteLine(" Engine : {0}", _parts["engine"]); Console.WriteLine(" #Wheels: {0}", _parts["wheels"]); Console.WriteLine(" #Doors : {0}", _parts["doors"]); } } }
VehicleBuilder.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Practical { /// <summary> /// The 'Builder' abstract class /// </summary> public abstract class VehicleBuilder { protected Vehicle vehicle; // Gets vehicle instance public Vehicle Vehicle { get { return vehicle; } } // Abstract build methods public abstract void BuildFrame(); public abstract void BuildEngine(); public abstract void BuildWheels(); public abstract void BuildDoors(); } }
MotorCycleBuilder.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Practical { public class MotorCycleBuilder : VehicleBuilder { public MotorCycleBuilder() { vehicle = new Vehicle("MotorCycle"); } public override void BuildFrame() { 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"; } } }
CarBuilder.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Practical { public class CarBuilder : VehicleBuilder { public CarBuilder() { vehicle = new Vehicle("Car"); } public override void BuildFrame() { 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"; } } }
ScooterBuilder.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Practical { public class ScooterBuilder : VehicleBuilder { public ScooterBuilder() { vehicle = new Vehicle("Scooter"); } public override void BuildFrame() { vehicle["frame"] = "Scooter Frame"; } public override void BuildEngine() { vehicle["engine"] = "50 cc"; } public override void BuildWheels() { vehicle["wheels"] = "2"; } public override void BuildDoors() { vehicle["doors"] = "0"; } } }
Shop.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BuilderPattern.Practical { public class Shop { public void Construct(VehicleBuilder vehicleBuilder) { vehicleBuilder.BuildFrame(); vehicleBuilder.BuildEngine(); vehicleBuilder.BuildWheels(); vehicleBuilder.BuildDoors(); } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using DesignPatterns.BuilderPattern.Practical; namespace DesignPatterns.BuilderPattern { class Program { static void Main(string[] args) { VehicleBuilder builder; // Create shop with vehicle builders Shop shop = new Shop(); // Construct and display vehicles builder = new ScooterBuilder(); shop.Construct(builder); builder.Vehicle.Show(); builder = new CarBuilder(); shop.Construct(builder); builder.Vehicle.Show(); builder = new MotorCycleBuilder(); shop.Construct(builder); builder.Vehicle.Show(); } } }
運行輸出:
--------------------------- Vehicle Type: Scooter Frame : Scooter Frame Engine : 50 cc #Wheels: 2 #Doors : 0 --------------------------- Vehicle Type: Car Frame : Car Frame Engine : 2500 cc #Wheels: 4 #Doors : 4 --------------------------- Vehicle Type: MotorCycle Frame : MotorCycle Frame Engine : 500 cc #Wheels: 2 #Doors : 0 請按任意鍵繼續. . .
5 建造者模式應用分析
建造者模式適用情形:
◊ 需要生成的產品對象有復雜的內部結構
◊ 需要生成的產品對象的屬性相互依賴,建造者模式可以強迫生成順序
◊ 在對象創建過程中會使用到系統中的一些其他對象,這些對象在產品對象的創建過程中不易得到
建造者模式特點:
◊ 建造者模式的使用使得產品的內部表對象可以獨立地變化。使用建造者模式可以使客戶不必知道產品內部組成的細節
◊ 每一個Builder都相對獨立,而與其他Builder無關
◊ 可使對構造過程更加精細控制
◊ 將構建代碼和表示代碼分開
◊ 建造者模式的缺點在於難於應付分步驟構建算法的需求變動