建造者模式(Builder Pattern):
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以创建它们,
用户不知道内部具体的构建细节。
Builder:抽象建造者
(1)为创建 一个Product对象的各个部件指定抽象接口。
ConcreteBuilder:具体建造者
(1)实现Builder接口,构造和装配产品的各个部件
(2)定义并明确它所创建的表示
(3)提供一个返回这个产品的接口
Director:指挥者
构建一个适应Builder接口的对象
Product:产品角色
(1)被构建的复杂对象,具体建造者创建该产品的内部表示并定义它的装配过程。
(2)包含定义组成部件的类,包含将这些部件装配成最终产品的接口。
建造者模式解析:
/// <summary>
/// Product类:产品类,由多个部件组成
/// </summary>
class Product
{
IList<string> parts = new List<string>();
/// <summary>
/// 添加产品部件
/// </summary>
/// <param name="part"></param>
public void Add(string part)
{
this.parts.Add(part);
}
public void Show()
{
Console.WriteLine("\n产品 创建----");
foreach (string part in parts)
{
Console.WriteLine(part);
}
}
}
/// <summary>
/// Builder类:抽象建造者类,确定产品由两个部件PartA和PartB组成,并声明一个得到产品构建后结果的方法
/// </summary>
abstract class Builder
{
public abstract void BuilderPartA();
public abstract void BuilderPartB();
public abstract Product GetResult();
}
class ConcreteBuilder1 : Builder
{
private Product product = new Product();
public override void BuilderPartA()
{
Console.WriteLine("部件A");
}
public override void BuilderPartB()
{
Console.WriteLine("部件B");
}
public override Product GetResult()
{
return product;
}
}
class ConcreteBuilder2 : Builder
{
private Product procudt = new Product();
public override void BuilderPartA()
{
Console.WriteLine("部件X");
}
public override void BuilderPartB()
{
Console.WriteLine("部件Y");
}
public override Product GetResult()
{
return procudt;
}
}
/// <summary>
/// Director:指挥者类
/// </summary>
class Director
{
/// <summary>
/// 用来只会构建过程
/// </summary>
/// <param name="builder"></param>
public void Construct(Builder builder)
{
builder.BuilderPartA();
builder.BuilderPartB();
}
}
class Program
{
static void Main(string[] args)
{
Director director = new Director();
Builder b1 = new ConcreteBuilder1();
Builder b2 = new ConcreteBuilder2();
director.Construct(b1);
Product p1=b1.GetResult();
p1.Show();
director.Construct(b2);
Product p2 = b2.GetResult();
p2.Show();
}
}
应用场景:
主要用于创建一些复杂的对象,这些对象内部构建间的顺序通常是稳定的,但对象内部的构建通常面临这复杂的变化。
实例:画游戏小人
/// <summary>
/// Builder抽象建造类
/// 抽象的建造人的类,稳定住花小人的每一个步骤,不让任何人遗忘当中的任何一步
/// </summary>
public abstract class PersonBuilder
{
protected Graphics g;
protected Pen p;
public PersonBuilder(Graphics g, Pen p)
{
this.g = g;
this.p = p;
}
public abstract void BuilderHead();
public abstract void BuilderBody();
public abstract void BuilderArmLeft();
public abstract void BuilderArmRight();
public abstract void BuilderLegLeft();
public abstract void BuilderLegRight();
}
/// <summary>
/// ConcreteBuilder类:具体的建造者类
/// 建造一个瘦的小人,让继承PersonBuilder类,这样就必须重写抽象类的方法,避免遗忘
/// </summary>
public class PersonThinBuilder:PersonBuilder
{
public PersonThinBuilder(Graphics g, Pen p)
: base(g,p)
{
}
public override void BuilderHead()
{
g.DrawEllipse(p, 50, 20, 30, 30);
}
public override void BuilderBody()
{
g.DrawRectangle(p, 60, 50, 10, 50);
}
public override void BuilderArmLeft()
{
g.DrawLine(p, 60, 50, 40, 100);
}
public override void BuilderArmRight()
{
g.DrawLine(p, 70, 50, 90, 100);
}
public override void BuilderLegLeft()
{
g.DrawLine(p, 60, 100, 45, 150);
}
public override void BuilderLegRight()
{
g.DrawLine(p, 70, 100, 85, 150);
}
}
/// <summary>
/// ConcreteBuilder类:具体的建造者类
/// 建造一个胖的小人,让继承PersonBuilder类,这样就必须重写抽象类的方法,避免遗忘
/// </summary>
public class PersonFatBuilder:PersonBuilder
{
public PersonFatBuilder(Graphics g, Pen p)
: base(g, p)
{
}
public override void BuilderHead()
{
g.DrawEllipse(p, 50, 20, 30, 30);
}
public override void BuilderBody()
{
g.DrawEllipse(p, 45, 50, 40, 50);
}
public override void BuilderArmLeft()
{
g.DrawLine(p, 50, 50, 30, 100);
}
public override void BuilderArmRight()
{
g.DrawLine(p, 80, 50, 100, 100);
}
public override void BuilderLegLeft()
{
g.DrawLine(p,60, 100, 45, 150);
}
public override void BuilderLegRight()
{
g.DrawLine(p, 70, 100, 85, 150);
}
}
/// <summary>
/// Director:指挥者类
/// 用来控制建造过程,也用来隔离用户与建造过程的关联
/// </summary>
public class PersonDirector
{
private PersonBuilder _pb;
/// <summary>
/// 用户告诉指挥者,需要什么样的小人
/// </summary>
/// <param name="pb"></param>
public PersonDirector(PersonBuilder pb)
{
this._pb = pb;
}
/// <summary>
/// 根据用户的选择构建小人
/// </summary>
public void CreatePerson()
{
_pb.BuilderHead();
_pb.BuilderBody();
_pb.BuilderArmLeft();
_pb.BuilderArmRight();
_pb.BuilderLegLeft();
_pb.BuilderLegRight();
}
}
客户端调用:
Pen p = new Pen(Color.Blue);
PersonBuilder pbthin = new PersonThinBuilder(this.pictureBox1.CreateGraphics(), p);
PersonDirector pdthin = new PersonDirector(pbthin);
pdthin.CreatePerson();
PersonBuilder pbfat = new PersonFatBuilder(this.pictureBox2.CreateGraphics(), p);
PersonDirector pdfat = new PersonDirector(pbfat);
pdfat.CreatePerson();