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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值