Builder
生成器模式是一种创建型模式,它主要是应对项目中一些复杂对象的创建工作。所谓“复杂对象”,是只:此对象中还含有其它的子对象。
Builder
模式所面对的情况是:各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将他们组合在一起的算法却相对稳定。简单的说:子对象变化较频繁,对算法相对稳定。
这是解决一个复杂对象的创建工作,现在变化的部分和相对稳定的部分已经明确,我们要做的是隔离变化,如何将子对象和算法隔离是要解决的问题。
《设计模式》中说道:将一个复杂对象的构建与其表示向分离,使得同样的构建过程可以创建不同的表示。
我们现在定义一个场景:还是选择汽车,
BMW
和
BORA
。试想一下,如果我们用较为普通的写法可以写成如下代码:
public
static
void
Main()
{
Car car = new Car();
Console.Write("Wheel:" + car._wheel + "\n");
Console.Write("OilBox:" + car._oilBox + "\n");
Console.Write("Body:" + car._body + "\n");
Console.Read();
}
public
class Car
{
public string _wheel =
“
BMWWheel
”
;
public string _oilbox =
“
BMWOilBox
”
;
public string _body =
“
BMWBody
”
;
}
当我们不确定或因需求变化而改变对汽车品牌的选择时,我们也许会频繁的更改
Car
类中的实现。
现在我们用
Manager
来管理汽车的构建。当然是构建一个抽象的类对象(对象如下图的
builder
,抽象类为
AbstractBuilder
)
,
对于
BMW
和
BORA
的构建类型继承
AbstractBuilder
类
首先我们先来编写
AbstractBuilder
抽象类的实现,代码如下:
public
abstract
class AbstractBuilder
{
public
string _wheel;
public
string _oilBox;
public
string _body;
public
abstract
void BuildWheel();
public
abstract
void BuildOilBox();
public
abstract
void BuildBody();
public
abstract Car GetCar();
}
public
abstract
class Car
{
}
然后我们再来实现BMW和BORA的构建,也就是Builder模式中频繁变化的部分,他们都要继承AbstractBuilder
BMW
:
public
class BMWBuilder:AbstractBuilder
{
public BMWBuilder()
{
//
// TODO:
在此处添加构造函数逻辑
//
}
public
override
void BuildWheel()
{
_wheel = "BMWWheel";
}
public
override
void BuildOilBox()
{
_oilBox = "BMWOilBox";
}
public
override
void BuildBody()
{
_body = "BMWBody";
}
public
override Car GetCar()
{
return
new BMWCar();
}
}
public
class BMWCar:Car
{}
BORA
:
public
class BORABuilder:AbstractBuilder
{
public BORABuilder()
{
//
// TODO:
在此处添加构造函数逻辑
//
}
public
override
void BuildWheel()
{
_wheel = "BORAWheel";
}
public
override
void BuildOilBox()
{
_oilBox = "BORAOilBox";
}
public
override
void BuildBody()
{
_body = "BORABody";
}
public
override Car GetCar()
{
return
new BORACar();
}
}
public
class BORACar:Car
{}
现在我们使用一种Manager方法来管理汽车的构建,这也就是Builder模式中提到的相对稳定的算法,我用一个类来实现:
private
class CarManager
{
public BuilderClass.Car CreateCar(BuilderClass.AbstractBuilder builder)
{
builder.BuildBody();
builder.BuildOilBox();
builder.BuildWheel();
Console.Write("Wheel:" + builder._wheel + "\n");
Console.Write("OilBox:" + builder._oilBox + "\n");
Console.Write("Body:" + builder._body + "\n");
Console.Read();
return builder.GetCar();
}
}
现在我们可以在客户程序中调用这个Manager来构建Car:
public
static
void
Main()
{
CarManager manager = new CarManager();
BuilderClass.Car car =
manager.CreateCar(new BuilderClass.BORABuilder());
}
结果如下:
Wheel:BORAWheel
OilBox:BORAOilBox
Body:BORABody
如果我们现在要换成
BMW
,我们只要在
Main
()函数中改变
manager.CreateCar
中的参数就可以:
public
static
void
Main()
{
CarManager manager = new CarManager();
BuilderClass.Car car =
manager.CreateCar(new BuilderClass.BMWBuilder());
}
结果如下:
Wheel:BMWWheel
OilBox:BMWOilBox
Body:BMWBody
这样,经过简单的修改可以实现对不同
Car
的构建。如果我们还有其他汽车的实现只要将他的类继承
AbstractBuilder
,然后在
Main
()中修改就可以。说道这里,我想起了在第一篇中提到的设计模式中的“开
---
闭原则”,这个方式是很符合这个原则的,对代码进行了扩展,以减少了代码修改量。而且我们还有很多方法可以利用,如:
WebConfig
中的
appSettings
来动态的配置,从数据库中读取,或利用依赖方式动态生成。
现在我们再来看看
Builder
模式的几个要点:
Builder
模式主要用于构建一个复杂的对象,但这个对象构建的算法是稳定的,对象中的各个部分经常变化。
Builder
模式主要在于应对复杂对象各个部分的频繁需求变动。但是难以应对算法的需求变动。这点一定要注意,如果用错了,会带来很多不必要的麻烦。
课程中还提到了
.Net
中的
Builder
模式的应用。如:
Page
类中的
OnInit
()等方法的实现。我们在写一个
Web
页面的时候。他的
codebehind
代码都是继承
System.Web.UI.Page
基类的。
OnInit
()函数是可以重写的