GOF《设计模式》中说道:将一个复杂对象的构建与其表示向分离,使得同样的构建过程可以创建不同的表示。 所谓“复杂对象”,是指:此对象中还含有其它的子对象。 何时采用: 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


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

{

}
#endregion


具体实现宝马车的Builder#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


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

{

}
#endregion


具体实现丰田车的Builder#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() + "个");


返回成型产品#region 返回成型产品
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();
}
}
}
前往:设计模式学习笔记清单