• 设计模式Builder生成器模式


       GOF《设计模式》中说道:将一个复杂对象的构建与其表示向分离,使得同样的构建过程可以创建不同的表示。
       所谓“复杂对象”,是指:此对象中还含有其它的子对象。
       何时采用: Builder模式所面对的情况是:各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将他们组合在 一起的算法却相对稳定。简单的说:子对象变化较频繁,组合算法相对稳定。比如生产汽车,理想状态下,生产步骤基本相同,只是不同的车款其具体部件有所不 同,变化的是部件,稳定的是生产流程,在此种情况下就采用Builder生成器模式。还比如组装电脑,组装步骤也基本就是那些步骤,但不同的使用了不同的 配件,所以也适合此模式。
       因此,这是解决一个复杂对象的创建工作,现在变化的部分和相对稳定的部分已经明确,我们要做的是隔离变化,如何将子对象和算法隔离是要解决的问题。
       我们现在定义一个场景:用Builder生成器生产汽车,在此处,我们有两个车款需要生产,它们是BMW或TOYOTA。
       下面我们按下面步骤来实现我们的Builder生成器模式
       一、抽象建造者角色:CarBuilder。它主要是用来定义两种接口,一种接口用于规范产品的各个部分的组成。比如,这里就规定了汽车五个重要组成部件的组成。第二种接口用于返回建造后的产品。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace CarBuilderPattern
    {
        
    #region 定义产品各个部件的抽象类

        
    #region 底盘抽象类
        
    public abstract class Undercarriage
        
    {
            
    #region 底盘品牌
            
    private  string   _undercarriagebrand;
            
    public string MyUnderCarriageBrand
            
    {
                
    get return _undercarriagebrand; }
                
    set { _undercarriagebrand = value; }
            }

            
    #endregion


            
    #region 底盘长度
            
    private int _undercarriagesize;
            
    public int MyUnderCarriageSize
            
    {
                
    get return _undercarriagesize; }
                
    set { _undercarriagesize = value; }
            }

            
    #endregion


            
    #region 底盘构造函数
            
    public  Undercarriage()
            
    {

            }


            
    public  Undercarriage(string BrandName)
            
    {
                MyUnderCarriageBrand 
    = BrandName;
            }

            
    #endregion

        }
    ;
        
    #endregion


        
    #region 车体抽象类
        
    public abstract class Body
        
    {
            
    #region 车体品牌
            
    private  string   _bodybrand;
            
    public string BodyBrand
            
    {
                
    get return _bodybrand; }
                
    set { _bodybrand = value; }
            }

            
    #endregion


            
    #region 车体颜色
            
    private string _bodycolor;
            
    public string BodyColor
            
    {
                
    get return _bodycolor; }
                
    set { _bodycolor = value; }
            }

            
    #endregion


            
    #region 车体构造函数
            
    public  Body()
            
    {

            }


            
    public Body(string BrandName)
            
    {
                BodyBrand 
    = BrandName;
            }

            
    #endregion

        }
    ;
        
    #endregion


        
    #region 轮胎抽象类
        
    public abstract class Wheel 
        
    {
            
    private  string   _wheelbrand;
            
    public string WheelBrand
            
    {
                
    get return _wheelbrand; }
                
    set { _wheelbrand = value; }
            }


            
    public  Wheel()
            
    {

            }


            
    public Wheel(string BrandName)
            
    {
                WheelBrand 
    = BrandName;
            }

        }
    ;
        
    #endregion


        
    #region 引擎抽象类
        
    public abstract class Engine 
        
    {
            
    private  string   _enginebrand;
            
    public string EngineBrand
            
    {
                
    get return _enginebrand; }
                
    set { _enginebrand = value; }
            }


            
    public  Engine()
            
    {

            }


            
    public Engine(string BrandName)
            
    {
                EngineBrand 
    = BrandName;
            }

        }
    ;
        
    #endregion


        
    #region 座位抽象类
        
    public abstract class Seat 
        
    {
            
    private  string   _seatbrand;
            
    public string SeatBrand
            
    {
                
    get return _seatbrand; }
                
    set { _seatbrand = value; }
            }


            
    public  Seat()
            
    {

            }


            
    public Seat(string BrandName)
            
    {
                SeatBrand 
    = BrandName;
            }

        }
    ;
        
    #endregion

        
    #endregion


        
    #region 定义产品抽象类
        
    //定义一个产品抽象类(车)
        
    //任何具体实际产品(宝马车,RAV4,UT,BUS)要从此类继承
        public abstract class Car
        
    {
            
    #region 品牌属性
            
    private  string   _carBrand;
            
    public string CarBrand
            
    {
                
    get return _carBrand; }
                
    set { _carBrand = value; }
            }

            
    #endregion


            
    #region 轮子个数属性
            
    private int _carWheelNumber;
            
    public int CarWheelNumber
            
    {
                
    get return _carWheelNumber; }
                
    set { _carWheelNumber = value; }
            }


            
    #endregion


            
    #region 座位个数属性
            
    private int _carSeatNumber;
            
    public int CarSeatNumber
            
    {
                
    get return _carSeatNumber; }
                
    set { _carSeatNumber = value; }
            }


            
    #endregion


            
    #region 车体颜色属性
            
    private string  _carBodyColor;
            
    public string CarBodyColor
            
    {
                
    get return _carBodyColor; }
                
    set { _carBodyColor = value; }
            }

            
    #endregion


            
    #region 底盘长度属性
            
    private string _carUnderCarriageSize;
            
    public string CarUnderCarriageSize
            
    {
                
    get return _carUnderCarriageSize; }
                
    set { _carUnderCarriageSize = value; }
            }

            
    #endregion


            
    #region 车子构造函数

            
    public  Car()
            
    {

            }


            
    public Car(string BrandName)
            
    {
                CarBrand 
    = BrandName;
            }

            
    #endregion

        }

        
    #endregion



        
    //建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成部分的建造。一般而言,此接口独立于应用程序的商业逻辑。
        
    //模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。

        
    #region 定义建造者角色(也是一个抽象类,无具体实现)
        
    public abstract class Builder
        
    {
            
    #region 建造方法(此产品各个组成部分的建造方法)
            
    public abstract Undercarriage BuildUndercarriage(string brandName); //构建车底盘
            public abstract Body BuildBody(string brandName); //构建车体
            public abstract Wheel BuildWheel(string brandName); //构建车轮
            public abstract Engine BuildEngine(string brandName); //构建发动引擎
            public abstract Seat  BuildSeat(string brandName);  //构建车座

            
    #endregion


            
    #region 结果返回方法(返回一个此产品)
            
    public abstract Car GetCar(Undercarriage myUndercarriage,Body myBody,Engine myEngine,Seat[] mySeats,Wheel[] myWheel);
            
    #endregion

        }

        
    #endregion


    }

      二、建造者模式的指导者:CarFactoryManager。指导者做的是稳定的建造工作,他按照固定的流程,重复做着相同的装配工作。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace CarBuilderPattern
    {
        
    //此部分是最稳定的,不会因为车款的变化而变化
        
    //因为此处定义了一个造车的流程,不管造什么车,基本流程大致相同
        class CarFactoryManager
        
    {
            
    //具体建造者(Concrete Builder)角色:担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。
            
    //这个角色主要完成的任务包括:实现Builder角色提供的接口,一步一步完成创建产品实例的过程;在建造过程完成后,提供产品的实例。

            
    public static Car CreateCars(Builder builder,string BrandName)
            
    {
              
                
    #region 一步一步完成创建产品实例的过程
                
    //定义了一个造车的流程(此流程可以根据xml或数据库获取如何造车的要求并在此处根据要求来造车)
                
    //此处,我们假设根据外部要求,我们在此处要造的车为:一个底盘,四个座位,一个车体,四个门,四个轮子,一个引擎
                Undercarriage myundercarriage= builder.BuildUndercarriage(BrandName); //安装底盘
               
                Body mybody
    = builder.BuildBody(BrandName); //安装车体

                Engine myengine
    =  builder.BuildEngine(BrandName); //安装引擎

                
    //安装四个座位
                Seat[] seats = 
                                    builder.BuildSeat(BrandName),
                                    builder.BuildSeat(BrandName),
                                    builder.BuildSeat(BrandName),
                                    builder.BuildSeat(BrandName)
                                }
    ;
                
    //安装四个轮胎
                Wheel[] wheels ={
                                    builder.BuildWheel(BrandName), 
                                    builder.BuildWheel(BrandName),
                                    builder.BuildWheel(BrandName),
                                    builder.BuildWheel(BrandName)
                                }
    ;

               

               
                
    #endregion


                
    #region 提供产品的实例
                
    return builder.GetCar(myundercarriage,mybody,myengine,seats,wheels); 

                
    #endregion



            }

        }

    }

      三、具体的建造者:BMWCar和TOYOTACar。他的工作就是实现各建造步骤的接口,以及实现返回产品的接口。
        宝马车建造者
      

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace CarBuilderPattern
    {
        
    //此部分是经常变化的

        
    #region 宝马车各部件的具体定义类:继承各部件的抽象类
        
    //我们可以在此处定义各部件的具体特性,如:不同的颜色,不同的尺寸,不同的外形等
        public class BMWUndercarriage:Undercarriage 
        
    { };
        
    public class BMWBody :Body 
        
    { };
        
    public class BMWWheel:Wheel     
        
    { };
        
    public class BMWEngine :Engine
        
    { };
        
    public class BMWSeat:Seat
        
    { };
        
    #endregion


        
    #region 定义一个具体产品类:宝马车,它继承自前面定义的抽象类Car
        
    public  class BMWCar:Car 
        
    {

        }

        
    #endregion


        
    #region  具体实现宝马车的Builder
        
    public class BMWBuilder : Builder
        
    {
            
    //定义宝马车具体如何构建各个部件的方法

            
    #region 宝马车构建车底盘方法
            
    public override  Undercarriage  BuildUndercarriage(string brandName)
            
    {
                BMWUndercarriage undercarriageBMW 
    = new BMWUndercarriage();
                undercarriageBMW.MyUnderCarriageBrand 
    = brandName;
                undercarriageBMW.MyUnderCarriageSize 
    = 4;
                
    return undercarriageBMW;
            }

            
    #endregion


            
    #region 宝马车构建车体
            
    public override Body  BuildBody(string brandName) 
            
    {
                BMWBody bodyBMW 
    = new BMWBody();
                bodyBMW.BodyBrand 
    = brandName;
                bodyBMW.BodyColor 
    = "红色";
                
    return bodyBMW;
            }
     
            
    #endregion


            
    #region  宝马车构建车轮
            
    public override Wheel  BuildWheel(string brandName) 
            
    {
                BMWWheel wheelBMW 
    = new BMWWheel();
                wheelBMW.WheelBrand 
    = brandName;
                
    return wheelBMW;
            }

            
    #endregion


            
    #region 宝马车构建发动引擎
            
    public override Engine  BuildEngine(string brandName) 
            
    {
                BMWEngine EngineBMW
    = new BMWEngine();
                EngineBMW.EngineBrand 
    = brandName;
                
    return EngineBMW;

            }

            
    #endregion


            
    #region 宝马车构建车座

            
    public override Seat  BuildSeat(string brandName) 
            
    {
                BMWSeat SeatBMW 
    = new BMWSeat();
                SeatBMW.SeatBrand 
    = brandName;
                
    return SeatBMW;
            }

            
    #endregion



            
    #region 返回产品
            
    public override Car GetCar(Undercarriage myUndercarriage, Body myBody, Engine myEngine, Seat[] mySeats, Wheel[] myWheel)
            
    {
                BMWCar mycar 
    = new BMWCar();

                
    //在这里对各个部件进行组合和处理
                mycar.CarBrand = "宝马车";
                Console.WriteLine(
    "本次Builder工厂制造的是"+mycar.CarBrand.ToString());
                Console.WriteLine(
    "底盘用的是:" +myUndercarriage.MyUnderCarriageBrand.ToString());
                Console.WriteLine(
    "底盘长度是:" + myUndercarriage.MyUnderCarriageSize.ToString()+"");
                Console.WriteLine(
    "车体用的是:"+myBody.BodyBrand.ToString());
                Console.WriteLine(
    "车体用颜色是:" + myBody.BodyColor.ToString());
                Console.WriteLine(
    "引擎用的是:" + myEngine.EngineBrand.ToString()+"引擎");
                Console.WriteLine(
    "座位有"+mySeats.Length.ToString()+"");
                Console.WriteLine(
    "轮胎有" + myWheel.Length.ToString() + "");

                
    #region 返回成型产品
                
    return mycar;
                
    #endregion

            }

            
    #endregion


        }

        
    #endregion

    }

       丰田车建造者

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace CarBuilderPattern
    {
        
    #region 丰田车各部件的具体定义类:继承各部件的抽象类
        
    //我们可以在此处定义各部件的具体特性,如:不同的颜色,不同的尺寸,不同的外形等
        public class TOYOTAUndercarriage : Undercarriage
        
    { };
        
    public class TOYOTABody : Body
        
    { };
        
    public class TOYOTAWheel : Wheel
        
    { };
        
    public class TOYOTAEngine : Engine
        
    { };
        
    public class TOYOTASeat : Seat
        
    { };
        
    #endregion


        
    #region 定义一个具体产品类:丰田车,它继承自前面定义的抽象类Car
        
    public class TOYOTACar : Car
        
    {

        }

        
    #endregion


        
    #region  具体实现丰田车的Builder
        
    public class TOYOTABuilder : Builder
        
    {
            
    //定义丰田车具体如何构建各个部件的方法

            
    #region 丰田车构建车底盘方法
            
    public override Undercarriage BuildUndercarriage(string brandName)
            
    {
                TOYOTAUndercarriage undercarriageTOYOTA 
    = new TOYOTAUndercarriage();
                undercarriageTOYOTA.MyUnderCarriageBrand 
    = brandName;
                undercarriageTOYOTA.MyUnderCarriageSize 
    = 3;
                
    return undercarriageTOYOTA;
            }

            
    #endregion


            
    #region 丰田车构建车体
            
    public override Body BuildBody(string brandName)
            
    {
                TOYOTABody bodyTOYOTA 
    = new TOYOTABody();
                bodyTOYOTA.BodyBrand 
    = brandName;
                bodyTOYOTA.BodyColor 
    = "兰色";
                
    return bodyTOYOTA;
            }

            
    #endregion


            
    #region  丰田车构建车轮
            
    public override Wheel BuildWheel(string brandName)
            
    {
                TOYOTAWheel wheelTOYOTA 
    = new TOYOTAWheel();
                wheelTOYOTA.WheelBrand 
    = brandName;
                
    return wheelTOYOTA;
            }

            
    #endregion


            
    #region 丰田车构建发动引擎
            
    public override Engine BuildEngine(string brandName)
            
    {
                TOYOTAEngine EngineTOYOTA 
    = new TOYOTAEngine();
                EngineTOYOTA.EngineBrand 
    = brandName;
                
    return EngineTOYOTA;

            }

            
    #endregion


            
    #region 丰田车构建车座

            
    public override Seat BuildSeat(string brandName)
            
    {
                TOYOTASeat SeatTOYOTA 
    = new TOYOTASeat();
                SeatTOYOTA.SeatBrand 
    = brandName;
                
    return SeatTOYOTA;
            }

            
    #endregion



            
    #region 对丰田车的上述各部件进行具体组合,形成产品然后返回
            
    public override Car GetCar(Undercarriage myUndercarriage, Body myBody, Engine myEngine, Seat[] mySeats, Wheel[] myWheel)
            
    {
                TOYOTACar mycar 
    = new TOYOTACar();

                
    //在这里对各个部件进行组合和处理
                mycar.CarBrand = "丰田车";
                Console.WriteLine(
    "本次Builder工厂制造的是" + mycar.CarBrand.ToString());
                Console.WriteLine(
    "底盘用的是:" + myUndercarriage.MyUnderCarriageBrand.ToString());
                Console.WriteLine(
    "底盘长度是:" + myUndercarriage.MyUnderCarriageSize.ToString() + "");
                Console.WriteLine(
    "车体用的是:" + myBody.BodyBrand.ToString());
                Console.WriteLine(
    "车体用颜色是:" + myBody.BodyColor.ToString());
                Console.WriteLine(
    "引擎用的是:" + myEngine.EngineBrand.ToString() + "引擎");
                Console.WriteLine(
    "座位有" + mySeats.Length.ToString() + "");
                Console.WriteLine(
    "轮胎有" + myWheel.Length.ToString() + "");

                
    返回成型产品 返回成型产品
                
    return mycar;
                
    #endregion

            }

            
    #endregion


        }

        
    #endregion

    }

      四、 Car就是建造出来的复杂产品--汽车。在代码中,我们的各种建造步骤都是为创建产品中的各种配件服务的,Car定义了一个相对具体的产品,在应用中可以把这个产品进行比较高度的抽象,使得不同的具体建造者甚至可以建造出完全不同的产品。


      五、 看看客户端的代码,用户先是选择了一个具体的Builder,BMWCar或TOYOTACar,然后交由Builder工厂给他生产出相应的汽车产品。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace CarBuilderPattern
    {
        
    class Program
        {
            
    static void Main(string[] args)
            {
                
    //指导者(Director)角色:担任这个角色的类调用具体建造者角色(BMWBuilder)以创建产品对象。
                
    //导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。

               Car mycaBMW
    = CarFactoryManager.CreateCars(new  BMWBuilder(),"宝马车");

               Car mycarToyota 
    = CarFactoryManager.CreateCars(new TOYOTABuilder(), "丰田车");
               Console.Read();


            }
        }
    }


    前往:设计模式学习笔记清单
  • 相关阅读:
    element、vue 使用
    .net bigint,long传到前端发现精度不对
    服务器工具安装
    银行分控模型的建立
    Firebase —— a readymade backend system
    PouchDB —— build applications that work as well offline
    ASP.NET 之 UserRoleIdentity
    insert conflict do update
    【PostgreSQL数据库】PostgreSQL数据库gdb调试子进程
    mac禁用chrome左右双指滑动手势返回上一页
  • 原文地址:https://www.cnblogs.com/smallfa/p/1586994.html
Copyright © 2020-2023  润新知