意图(Intent)
将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
解释:以建造房屋为例,建造房屋的构成不变,其中各个部分:窗,床,门等会变化。例如,今天是纱窗,明天换成玻璃窗,今天是欧式风格的床,明天换成木板床,构建不变,但是他们的表示会不断地变化。
动机(Motivation)
在软件系统中,有时候面临着“一个复杂对象(房屋)”的创建工作,其通常由各个部分的子对象(床,窗,们)用一定的算法构成;由于需求的变化,这个复杂对象的各个部分(窗,床,门的风格)经常面临着剧烈的变化,但是将它们组合在一起的算法(构造房屋的算法)却相对稳定。
结构(structure)
角色(roles)
Builder为创建一个product对象的各个部件指定抽象接口。
ConcreteBuilder实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,提供一个检索产品的接口。
Director构造一个使用Builder接口的对象。
Produc表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。包含定义组成组件的类,包括将这些组件装配成最终产品的接口。
适用性
1.当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方法时。
2.当构造过程必须允许被构造的对象有不同的表示时。
举例:以构造房屋为例
//Product类,产品类,由多个部件组成
class House { }
Builder类,抽象建造者类,确定产品两个部件PartA和PartB组成,并声明一个得到产品建造后结果的方法GetRuslt,本实例中,房屋两个部分分别是:门和窗,然然后声明得到一个建造房屋的方法GetHouse
abstract class Builder
{
public abstract void BuildDoor();
public abstract void BuildWinsows();
public abstract House GetHouse();
}
ConcreteProduct类-具体建造者类,本实例中,假设需要建造罗马Rome风格的房屋的HouseRomeBuilder类
class HouseRomeBuilder:Builder
{
private House RomeHouse = new House();
public override void BuildDoor()
{
Console.WriteLine("建造一个Rome风格的门");
}
public override void BuildWinsows()
{
Console.WriteLine("建造一个Rome风格的窗户");
}
public override House GetHouse()
{
return RomeHouse;
}
}
Diercot类,指挥者类,用来指挥建造过程,本例中,用来指挥给房屋创建门和窗
class Director
{
public void CreateHouse(Builder builder)
{
builder.BuildDoor();
builder.BuildWinsows();
}
}
客户端代码,客户不需要知道具体的建造过程
Director director = new Director();
Builder romebuilder = new HouseRomeBuilder();
director.CreateHouse(romebuilder);
House house = romebuilder.GetHouse();
Console.Read();
运行效果
这时候,如果想把门和窗的风格都变成Modern风格的,只需要在创建一个ConcreteProduct类-具体建造者类,在本例中,就是在创建一个HouseModernBuilder
class HouseModernBuilder : Builder
{
private House ModernHouse = new House();
public override void BuildDoor()
{
Console.WriteLine("建造一个Modern风格的门");
}
public override void BuildWinsows()
{
Console.WriteLine("建造一个Modern风格的窗户");
}
public override House GetHouse()
{
return ModernHouse;
}
}
客户端代码只需要变动两行即可
Builder romebuilder = new HouseRomeBuilder();
Builder modernbuilder = new HouseModernBuilder();
通过这个实例可以发现,创建房屋的过程是稳定的,而房屋内部各个部分是经常变动的,这就是将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。