C#设计模式系列:建造者模式(Builder)

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无关

  ◊ 可使对构造过程更加精细控制

  ◊ 将构建代码和表示代码分开

  ◊ 建造者模式的缺点在于难于应付分步骤构建算法的需求变动

posted @ 2014-03-30 10:08  libingql  阅读(8118)  评论(0编辑  收藏  举报