建造者模式(Builder Pattern)-创建型模式第四篇

也许得写一个段落放在文章的开头才会显得整篇没那么单调,我想写些什么,但指头落下的那一刻便忘了。简言之,设计模式犹如人生。好吧,也许这就算一个简单的开头,请让我们来看今天的主角,建造者模式(Builder Pattern),我不确定中文称它建造者模式是否准确,偶尔也会看到有人称其构建者或生成器模式。

定义:

Builder模式,通过将对象的构造过程与其本身分离开来,以简化复杂对象的创建过程,并且能够实现相同的构造过程可以创建不同的对象。

解决的问题:

  1. 如何通过简单的方式创建一个复杂的对象
  2. 如何通过相同的过程来创建类的不同实例

怎么去解决:

  1. 在一个独立的Builder对象中去创建和组装复杂对象的各个部分
  2. 通过对Builder的抽象,在创建复杂对象的过程中委托给具有相同接口的不同Builder实现,以达到相同的过程创建不同的对象

UML:

实例:

using System;

/// <summary>
/// Builder Pattern
/// </summary>
namespace BuilderPattern
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            DoWork();
        }

        private static void DoWork()
        {
            DisplayerDirector displayerDirector;
            while (true)
            {
                Console.WriteLine("Please select the type of displayer you want.");
                Console.WriteLine($"A: LED{Environment.NewLine}B: LCD");
                var inputKey = Console.ReadKey();
                Console.WriteLine();
                switch (inputKey.KeyChar.ToString().ToUpper())
                {
                    case "A":
                        var ledDisplayerBuilder = new LEDDisplayerBuilder();
                        ledDisplayerBuilder.AddBrand("SUMSUNG").AddModel("SN-001").AddPrice(1000).AddObject("SUMSUNG TV");
                        displayerDirector = new DisplayerDirector(ledDisplayerBuilder);
                        Console.WriteLine(displayerDirector.Build());
                        break;

                    case "B":
                        var lcdDisplayerBuilder = new LCDDisplayerBuilder();
                        lcdDisplayerBuilder.AddBrand("GreatWall").AddModel("GW-001").AddPrice(600);
                        displayerDirector = new DisplayerDirector(lcdDisplayerBuilder);
                        Console.WriteLine(displayerDirector.Build());
                        break;

                    case "X":
                        return;

                    default:
                        Console.WriteLine("You enter a wrong character and enter 'x' to exit the program");
                        break;
                }
            }
        }
    }

    public interface IDisplayerBuilder
    {
        Displayer Build();

        IDisplayerBuilder AddBrand(string brand);

        IDisplayerBuilder AddModel(string model);

        IDisplayerBuilder AddPrice(double price);

        IDisplayerBuilder AddObject(object whatever);
    }

    public class LCDDisplayerBuilder : IDisplayerBuilder
    {
        private Displayer _displayer = new Displayer();

        public IDisplayerBuilder AddBrand(string brand)
        {
            _displayer.Brand = brand;
            return this;
        }

        public IDisplayerBuilder AddModel(string model)
        {
            _displayer.Model = "LCD " + model;
            return this;
        }

        public IDisplayerBuilder AddObject(object whatever)
        {
            _displayer.Whatever = whatever;
            return this;
        }

        public IDisplayerBuilder AddPrice(double price)
        {
            _displayer.Price = price;
            return this;
        }

        public Displayer Build()
        {
            return _displayer;
        }
    }

    public class LEDDisplayerBuilder : IDisplayerBuilder
    {
        private Displayer _displayer = new Displayer();

        public IDisplayerBuilder AddBrand(string brand)
        {
            _displayer.Brand = brand;
            return this;
        }

        public IDisplayerBuilder AddModel(string model)
        {
            _displayer.Model = "LED " + model;
            return this;
        }

        public IDisplayerBuilder AddObject(object whatever)
        {
            _displayer.Whatever = whatever;
            return this;
        }

        public IDisplayerBuilder AddPrice(double price)
        {
            _displayer.Price = price;
            return this;
        }

        public Displayer Build()
        {
            return _displayer;
        }
    }

    public class DisplayerDirector
    {
        public IDisplayerBuilder DisplayerBuilder { get; }

        public DisplayerDirector(IDisplayerBuilder displayerBuilder)
        {
            DisplayerBuilder = displayerBuilder;
        }

        public Displayer Build()
        {
            return DisplayerBuilder.Build();
        }
    }

    /// <summary>
    /// The instance represents Displayer which need to be created finally. In this example, it is assumed to be a complex object.
    /// </summary>
    public class Displayer
    {
        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        /// <value>
        /// The name.
        /// </value>
        public string Brand { get; set; }

        /// <summary>
        /// Gets or sets the model.
        /// </summary>
        /// <value>
        /// The model.
        /// </value>
        public string Model { get; set; }

        /// <summary>
        /// Gets or sets the price.
        /// </summary>
        /// <value>
        /// The price.
        /// </value>
        public double Price { get; set; }

        /// <summary>
        /// Gets or sets the whatever.
        /// </summary>
        /// <value>
        /// The whatever.
        /// </value>
        public object Whatever { get; set; }

        public override string ToString()
        {
            return [email protected]" Brand: {Brand + Environment.NewLine} Model: {Model + Environment.NewLine} Price: {Price} Yuan {Environment.NewLine}";
        }
    }
}

注释:

  1. 在这个例子里我们假设Displayer是最终需要创建的那个复杂对象In this example, it is assumed to be a complex object.
  2. 在构建的过程中我们控制着最终对象的各个部分,你能够有能力选择需要什么或者不需要什么you can control which process you want
  3. 通过切换不同的Builder实现,你使一样的过程创造出完全不同的对象The same processed can build different object.

输出:

One Reply to “建造者模式(Builder Pattern)-创建型模式第四篇”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.