1.意图
将复杂对象的创建与表示分离,使得同样的构建过程可以创建不同的表示。需要注意一下几点:
-1构建与表示分离:表明生成器模式的结构,构建过程被封装在导航器中......
1.意图
将复杂对象的创建与表示分离,使得同样的构建过程可以创建不同的表示。需要注意一下几点:
-1构建与表示分离:表明生成器模式的结构,构建过程被封装在导航器中,生成器则负责实现具体的表示。
-2同样的构建过程:生成器模式关注的是构建过程,即构建过程是相同的。
-3不同的表示:生成器模式并不在意生产对象的结果,其构造的产品不一定有相同的类型。
2.使用场合
创建复杂对象的算法应该独立于该对象的组成部分及其封装方式,以及构造过程必须允许被构造的对象有不同表示情况下使用生成器模式。
3.结构
4.实现实例
代码
//生成器抽象类
using System;
namespace FaceBuilder
{
public abstract class FaceBuilder
{
public FaceBuilder()
{
}
public abstract void BuildFace();
public abstract void BuildEyes();
public abstract void BuildNodes();
public abstract void BuildEars();
public abstract void BuildMouth();
}
}
//GUI生成器
namespace FaceBuilder
{
public class GUIFaceBuilder:FaceBuilder
{
private Graphics grap;
private Pen p;
public GUIFaceBuilder(Graphics g)
{
grap=g;
p=new Pen(Color.Blue);
}
public override void BuildFace()
{
grap.DrawEllipse(p,100,100,200,300);
}
public override void BuildEyes()
{
grap.DrawEllipse(p,125,220,50,30);
grap.DrawEllipse(p,225,220,50,30);
}
public override void BuildNodes()
{
grap.DrawEllipse(p,80,250,20,40);
grap.DrawEllipse(p,300,250,20,40);
}
public override void BuildEars()
{
grap.DrawEllipse(p,190,250,20,50);
}
public override void BuildMouth()
{
grap.DrawEllipse(p,190,350,20,1);
}
public Graphics GetFace()
{
return grap;
}
}
}
//对象生成器
namespace FaceBuilder
{
public class ObjectFaceBuilder:FaceBuilder
{
private Face face;
public ObjectFaceBuilder()
{
}
public override void BuildFace()
{
face=new Face();
}
public override void BuildEars()
{
face.leftear=new Ear();
face.rightear=new Ear();
}
public override void BuildEyes()
{
face.lefteye=new Eye();
face.righteye=new Eye();
}
public override void BuildMouth()
{
face.mouth=new Mouth();
}
public override void BuildNose()
{
face.nose=new Nose();
}
public Face GetFace()
{
return face;
}
}
}
//导航器
namespace FaceBuilder
{
public class FaceDirector
{
private FaceBuilder b;
public FaceDirector(FaceBuilder b)
{
this.b=b;
}
public void CreateFace()
{
b.BuildFace();
b.BuildEyes();
b.BuildEars();
b.BuildMouth();
b.BuildNose();
}
}
}
//生成器模式的使用
GUIFaceBuilder b=new GUIFaceBuilder(this.CreateGraphics());
FaceDirector c=new FaceDirector(b);
c.CreateFace();
(1)Builder:为创建Product对象的各个部分指定抽象接口。
(2)ConcreteBuilder:实现Builder的接口以及构造和装配该产品的各个部件,定义并说明确定它所创建的表示,并提供一个检索产品的接口的对象。
(3)Director:构造一个使用Builder接口的对象。
(4)Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,以及这些部件装配成最终产品的接口。
5.效果
采用生成器模式可以轻松的改变产品的内部表示,上例中的脸谱画得不太好。但是如果我们创建一个新的生成器,艺术的绘制脸谱的各个部分,即可以改善脸谱的质量。而这项工作完全可以和程序主体分离,由一位爱好美术的程序独立完成。
生成器模式将构造代码和表示分开,一个脸谱可以用位图、字符串或对象模型来表示,构造代码完全一致。
构造过程可以更精细的控制,生成器模式强调的是产品的构造过程,产品各部分具有依赖关系非常重要。
需要注意的是,不同生成器产品的对象可能不属于同一类型,因此使用生成器的客户端必须知道产品的具体类型。例如在创建脸谱的示例中,产生的GUI脸谱和脸谱对象是完全不同的类型。这意味着生成器经常不能互换,不同的生成器正对的客户程序也不同。
6.生成器模式与抽象工厂的区别
生成器模式关注于将构造对象的过程和构建的各个部分分开,而抽象工厂更关注于构建一个产品系列。实际上最大的区别就是生成器模式创建的产品不一定具有共同的父类,只要有类似的构造过程即可。
在上例中,FaceBuilder仅仅抽象了构建的过程,并没有规定一定产生的产品类型,具体的产品由具体的Builder类决定。从上例产生的一个简单的Graphics对象中我们可以获得一个脸谱的位图,但也可以使用相同的导航器和结构获得一个Face对象。
7.生成器与生成器模式
模式的名称有时不能完全代表模式的结构。在生成器模式中,生成器是重要的组成部分,但是有生成器则不能构成生成器模式。
实际上,生成器可以单独使用,只是在使用时没有导航器,需要用户控制构建的过程。在.NET中提供了多种类型的生成器,他们屏蔽了对象创建细节,然而这并不等于采用了生成器模式。
StringBuilder是一个典型的生成器。使用时没有导航器所以它不是导航器模式。
8.相关模式
生成器模式关注的是复杂对象的构建过程,它将对象的构建过程和表示分开,分开封装为导航器和生成器,这样可以采用相同的构建过程实现不同对象的表现。相关模式如下:
(1)抽象工厂:生成器模式产生的对象不一定时同一类型,这是与抽象工厂最大的区别。在使用抽象工厂时,客户不需要知道返回对象的具体类型,这是因为抽象工厂构造的是具有相同接口的产品系列:在使用生成器时,客户必须知道返回对象的具体类型,因为不同的生成器返回的类型是不同的。
(2)组合模式:组合模式描述的复杂对象经常需要采用生成器来创建。