建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式使得建造代码与表示代码的分离,可以使客户端不必知道产品内部组成的细节,从而降低了客户端与具体产品之间的耦合度,下面通过类图来帮助大家更好地理清建造者模式中类之间的关系。

  建造者模式中主要有三类角色:

  • Product产品类
  • Builder抽象建设者:规范产品的组建,一般是由子类实现。
  • ConcreteBuilder具体建造者:实现抽象类定义的所有方法,并且返回一个组建好的对象。
  • Director导演类:负责安排已有模板的顺序,然后告诉Builder开始建造。
 

具体实现

namespace ConsoleApplication1
{
    /// <summary>
    /// 产品类
    /// </summary>
    public class Product
    {
        public void doSomething()
        {
            //独立业务处理
        }
    }
    /// <summary>
    /// 抽象建造者
    /// </summary>
    public abstract class Builder
    {
        //设置产品的不同部分,以获取不同的产品
        public abstract void setPart();
        //建造产品
        public abstract Product buildProduct();
    }
    public class ConcreteProduct : Builder
    {
        private Product product = new Product();
        //设置产品零件
        public override void setPart()
        {
           /*
            *产品内部的逻辑处理
            */
        }
        public override Product buildProduct()
        {
            return product;
        }
    }
    public class Director
    {
        private Builder builder = new ConcreteProduct();
        public Product getAProduct()
        {
            builder.setPart();
            /*
             * 设置不同的零件,产生不同的产品
             */
            return builder.buildProduct();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.ReadLine();
        }
    }
}
View Code
 建造者模式的优点

   建造者模式具有以下优点:

  • 封装性
          使用建造者模式可以使客户端不必知道产品内部组成的细节。
  • 建造者独立,容易扩展
          建造者彼此间相互独立的,对系统的扩展非常有利。
  • 便于控制细节风险
          由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
 
建造者模式的使用场景
  • 相同的方法,不同的执行顺序,产生不同的事件结果时。
  • 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。
  • 产品类非常复杂,或者产品类中调用顺序不同产生了不同的效能。
  • 在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时。
一个构建汽车模式的范例:
完整类图如下:
具体代码如下:
namespace TempApplication
{
    /// <summary>
    /// 车辆模型的抽象类
    /// </summary>
    public abstract class CarModel
    {
        private List<string> sequence = new List<string>();

        public List<string> Sequence
        {
            set { this.sequence = value; }
        }

        protected abstract void start();

        protected abstract void stop();

        protected abstract void alarm();

        protected abstract void engineBoom();

        public void run()
        {
            foreach (string item in sequence)
            {
                switch (item)
                {
                    case "start":
                        this.start();  //启动汽车
                        break;
                    case "stop":
                        this.stop();   //停止汽车
                        break;
                    case "alarm":
                        this.alarm();  //喇叭开始叫了
                        break;
                    case "engine boom":
                        this.engineBoom();  //引擎开始轰鸣
                        break;
                    default:
                        throw new Exception("未定义的操作流程");
                }
            }
        }
    }

    public class BenzModel : CarModel
    {
        protected override void start()
        {
            Console.WriteLine("奔驰车跑起来是这个样子的...");
        }
        protected override void stop()
        {
            Console.WriteLine("奔驰车应该这样停车...");
        }
        protected override void alarm()
        {
            Console.WriteLine("奔驰车的喇叭声音是这个样子的...");
        }
        protected override void engineBoom()
        {
            Console.WriteLine("奔驰车的引擎是这个声音的...");
        }
    }

    public class BMWModel : CarModel
    {
        protected override void start()
        {
            Console.WriteLine("宝马车跑起来是这个样子的...");
        }
        protected override void stop()
        {
            Console.WriteLine("宝马车应该这样停车...");
        }
        protected override void alarm()
        {
            Console.WriteLine("宝马车的喇叭声音是这个样子的...");
        }
        protected override void engineBoom()
        {
            Console.WriteLine("宝马车的引擎是这个声音的...");
        }
    }

    /// <summary>
    /// 抽象汽车组装者
    /// </summary>
    public abstract class CarBuilder
    {
        //建造一个模式,你要给我一个顺序要求,就是组装顺序
        public abstract void setSuqence(List<string> sequence);
        //设置完毕顺序后,就可以直接拿到这个车辆模型
        public abstract CarModel getCarModel();
    }

    public class BenzBuilder : CarBuilder
    {
        private BenzModel benz = new BenzModel();
        public override void setSuqence(List<string> sequence)
        {
            this.benz.Sequence = sequence;
        }
        public override CarModel getCarModel()
        {
            return this.benz;
        }
    }

    public class BMWBuilder : CarBuilder
    {
        private BMWModel bmw = new BMWModel();
        public override void setSuqence(List<string> sequence)
        {
            this.bmw.Sequence = sequence;
        }
        public override CarModel getCarModel()
        {
            return this.bmw;
        }
    }

    /// <summary>
    /// 导演类
    /// </summary>
    public class Director
    {
        private List<string> sequence = new List<string>();
        private BenzBuilder benzBuilder = new BenzBuilder();
        private BMWBuilder bmwBuilder = new BMWBuilder();

        /// <summary>
        /// A类型的奔驰车模型,先start,然后stop,其他什么引擎、喇叭一概没有
        /// </summary>
        /// <returns></returns>
        public BenzModel getABenzModel()
        {
            this.sequence.Clear();
            //ABenzModel的执行顺序
            this.sequence.Add("start");
            this.sequence.Add("stop");
            //按照顺序返回一个奔驰车
            this.benzBuilder.setSuqence(this.sequence);
            return (BenzModel)this.benzBuilder.getCarModel();
        }
        /// <summary>
        /// B类型的奔驰车模型,先发动引擎,然后启动,然后停止,没有喇叭
        /// </summary>
        /// <returns></returns>
        public BenzModel getBBenzModel()
        {
            this.sequence.Clear();
            this.sequence.Add("engine boom");
            this.sequence.Add("start");
            this.sequence.Add("stop");
            this.benzBuilder.setSuqence(this.sequence);
            return (BenzModel)this.benzBuilder.getCarModel();
        }

        /// <summary>
        /// C类型的宝马车模型,先按下喇叭,然后启动,然后停止
        /// </summary>
        /// <returns></returns>
        public BMWModel getCBMWModel()
        {
            this.sequence.Clear();
            this.sequence.Add("engine boom");
            this.sequence.Add("start");
            this.sequence.Add("stop");
            this.bmwBuilder.setSuqence(this.sequence);
            return (BMWModel)this.bmwBuilder.getCarModel();
        }

        /// <summary>
        /// D类型的宝马车只有一个功能,就是跑.
        /// </summary>
        /// <returns></returns>
        public BMWModel getDBMWModel()
        {
            this.sequence.Clear();
            this.sequence.Add("start");
            this.bmwBuilder.setSuqence(this.sequence);
            return (BMWModel)this.bmwBuilder.getCarModel();
        }

        /*
         * 这里可以有很多方法,按你自己的喜欢的顺序来定义
         */
    }



    class Client
    {
        static void Main(string[] args)
        {
            Director director = new Director();

            //A类型的奔驰车
            director.getABenzModel().run();

            //B类型的奔驰车
            director.getBBenzModel().run();

            //C类型的宝马车
            director.getCBMWModel().run();

            Console.Read();
        }
    }  
}
View Code