1、建造者模式简介
1.1>、定义
建造者模式(Builder)将复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
1.2>、使用频率
中低
1.3>、原型模式应用
在软件系统中,有时候面临一个复杂对象的创建工作,该对象通常由各个部分子对象用一定的算法构成,或者按一定的步骤组合而成;这些算法和步骤是稳定的,而构成这个对象的子对象却经常由于需求的变化而不断变化。
生活中的例子,要组装一台电脑,它的组装过程基本是不变的,都可以由主板、CPU、内存等按照某个稳定方式组合而成。然而主板、CPU、内存等零件本身都是可能多变的。将内存等这种易变的零件与电脑的其他部件分离,实现解耦合,则可以轻松实现电脑不断升级。
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_parts = new List (); 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 { ////// Builder uses a complex series of steps /// 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 PartsPartAPartBProduct PartsPartXPartY请按任意键继续. . .
4、建造者模式实践应用
Vehicle.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace DesignPatterns.BuilderPattern.Practical{ ////// The 'Product' class /// public class Vehicle { private string _vehicleType; private Dictionary_parts = new Dictionary (); /// /// Constructor /// public Vehicle(string vehicleType) { this._vehicleType = vehicleType; } ////// Indexer /// 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{ ////// The 'Builder' abstract class /// 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无关
◊ 可使对构造过程更加精细控制
◊ 将构建代码和表示代码分开
◊ 建造者模式的缺点在于难于应付分步骤构建算法的需求变动