建造者模式:将一个复杂对象的创建过程与它的显示分离,用户只需指定需要创建对象的类型,而不用去关心具体的建造过程。将所有构建过程相同的对象抽象出来,通过拓展可以创建不同的表示。
Builder:抽象类,根据产品的创建过程或配件抽象而来,规定了创建产品需要的配件等,可防止具体建造者创建的过程漏下某一步骤。
ConcreteBuilder:具体建造者,继承自Builder类,实现了产品的创建过程。
Director:指挥者,即客户只需要告诉它需要什么产品,由它调用具体建造者的方法创建产品,将创建产品的过程封装起来,使产品的创建与显示分离。
Product:创造出来的具体的产品。
例子
游戏里有各种人物角色,有胖的、瘦的,但毋庸置疑每个角色都需要头、身体、胳膊、腿等部位,每一个部位都是一个模块,看起来创建一个角色很复杂。但是却可以利用创建者模式,将角色的创建过程抽象出来,而每个角色的不同实现又可以通过具体建造者创建。
//抽象的Builder类
abstract class PersonBuilder
{
protected Graphics g;
protected Pen p;
public PersonBuilder(Graphics g,Pen p)
{
this.g = g;
this.p = p;
}
public abstract void BuildHead();
public abstract void BuildBody();
public abstract void BuildArmLeft();
public abstract void BuildArmRight();
public abstract void BuildLegLeft();
public abstract void BuildLegRight();
}
//具体建造者类
class PersonThinBuilder : PersonBuilder
{
public PersonThinBuilder(Graphics g, Pen p) : base(g, p)
{
}
public override void BuildArmLeft()
{
g.DrawLine(p, 60, 50, 40, 100);
}
public override void BuildArmRight()
{
g.DrawLine(p, 70, 50, 90, 100);
}
public override void BuildBody()
{
g.DrawRectangle(p, 60, 50, 10, 50);
}
public override void BuildHead()
{
g.DrawEllipse(p, 50, 20, 30, 30);
}
public override void BuildLegLeft()
{
g.DrawLine(p, 60, 100, 45, 150);
}
public override void BuildLegRight()
{
g.DrawLine(p, 70, 100, 85, 150);
}
}
//Director类
class PersonDirector
{
private PersonBuilder pb;
public PersonDirector(PersonBuilder pb)
{
this.pb = pb;
}
public void CreatePerson()
{
pb.BuildHead();
pb.BuildBody();
pb.BuildArmLeft();
pb.BuildArmRight();
pb.BuildLegLeft();
pb.BuildLegRight();
}
}
//客户端
private void button1_Click(object sender, EventArgs e)
{
Pen p = new Pen(Color.Red);
PersonThinBuilder ptb = new PersonThinBuilder(pictureBox1.CreateGraphics(), p);
//告诉Director类创建哪种产品
PersonDirector pdThin = new PersonDirector(ptb);
pdThin.CreatePerson();
}
适用场景
1.当创建的对象非常复杂,又不希望知道具体的创建过程时
2.当创建不同对象的构建流程基本一致时,比如炒饭、炒面、炒饼,希望有一个具体的规定流程,以免操作失误时,可以用建造者模式
3.对象构建流程基本一致,但又希望可以具体更改某个产品,即产品可以有细微变化
优缺点
优点:
1.复杂对象的创建过程与显示分离,代码结构更加清晰,耦合度降低
2.当需要增加具体的产品时,只需要增加一个具体建造者类即可,符合“开闭原则”。
3.对象的创建过程更加规范,可以降低失误
4.拥有基本一致的创建过程,但却可以创建不同的产品
缺点:
1.只能用于构建过程大体一致的产品,使用范围受限