设计模式 - 10)建造者模式
假设你是个木工手艺人,会做各种高矮胖瘦的人物,现在让你做一个男生和女生。
class Person
{
Ilist<string> parts = new List<string>();
public void Add(string part)
{
parts.Add(part);
}
public void Show()
{
Console.WriteLine
}
}
class PersonWomanBuilder
{
public void Builder()
{
Console.WriteLine("女头 ");
Console.WriteLine("女脖子");
Console.WriteLine("女手 ");
Console.WriteLine("女脚 ");
Console.WriteLine("女身体");
Console.WriteLine("女眉毛");
}
}
class PersonManBuilder
{
public void Builder()
{
Console.WriteLine("男头 ");
Console.WriteLine("男脖子");
Console.WriteLine("男手 ");
Console.WriteLine("男脚 ");
Console.WriteLine("男身体");
}
}
PersonWomanBuilder womanBuilder = new PersonWomanBuilder ();
womanBuilder .Builder();
PersonManBuilder manBuilder = new PersonManBuilder();
manBuilder .Builder();
很明显,上面在做男生的时候,漏了一个步骤,加男眉毛。
因此我们建一个抽象类,让各种人物都需要继承这个抽象类,实现规定的抽象方法。
abstract class PersonBuilder
{
public abstract void BuildHead();
public abstract void BuildNeck();
public abstract void BuildHand();
public abstract void BuildLeg();
public abstract void BuildBody();
public abstract void BuildEyebrow();
}
class PersonManBuilder : PersonBuilder
{
public override void BuildBody()
{
Console.WriteLine("男身体");
}
public override void BuildHand()
{
Console.WriteLine("男手");
}
...
}
class PersonWomanBuilder : PersonBuilder
{
public override void BuildBody()
{
Console.WriteLine("女身体");
}
public override void BuildHand()
{
Console.WriteLine("女手");
}
}
到这一步,我们就可以避免建造人物的时候,缺失步骤。
然后我们再设计一个指挥官,用它来控制建造的控制,避免需要在客户端依次调用建造人物的各个部位,从而避免漏掉用某个部位,隔离用户与建造过程的关联。
class PersonDirector
{
PersonBuilder pb;
public PersonDirector(PersonBuilder pb)
{
this.pb = pb;
}
public void CreatePerson()
{
pb.BuildHead();
pb.BuildNeck();
pb.BuildBody();
pb.BuildHand();
pb.BuildLeg();
pb.BuildMao();
}
}
// 业务代码
PersonDirector pdWoman = new PersonDirector(new PersonWomanBuilder());
pdWoman.CreatePerson();
PersonDirector pdMan = new PersonDirector(new PersonManBuilder());
pdMan.CreatePerson();
深入理解一下:
class PersonProduct
{
IList<string> parts = new List<string>();
public void Add(string part)
{
parts.Add(part);
}
public void Show()
{
Console.WriteLine("\n产品 创建:");
foreach (string part in parts)
{
Console.WriteLine(part);
}
}
}
abstract class PersonBuilder
{
public abstract void BuilderPartA();
public abstract void BuilderPartB();
public abstract PersonProduct GetResult();
}
class ManPersonBuilder : PersonBuilder
{
private PersonProduct product = new PersonProduct();
public override void BuilderPartA()
{
product.Add("部件A");
}
public override void BuilderPartB()
{
product.Add("部件B");
}
public override PersonProduct GetResult()
{
return product;
}
}
class WomanPersonBuilder : PersonBuilder
{
private PersonProduct product = new PersonProduct();
public override void BuilderPartA()
{
product.Add("部件X");
}
public override void BuilderPartB()
{
product.Add("部件Y");
}
public override PersonProduct GetResult()
{
return product;
}
}
class Director
{
public void Construct(PersonBuilder pb)
{
pb.BuilderPartA();
pb.BuilderPartB();
}
}
public class BuilderViewModel
{
public BuilderViewModel()
{
Director dc = new Director();
ManPersonBuilder mpb = new ManPersonBuilder();
dc.Construct(mpb);
PersonProduct pp1 = mpb.GetResult();
pp1.Show();
WomanPersonBuilder wmpb = new FatPersonBuilder();
dc.Construct(wmpb);
PersonProduct pp2 = wmpb.GetResult();
pp2.Show();
}
}
- 设计一个产品 product,设计一个生产者 Builder 抽象类,规定需要实现的方法,设计一个指挥官 Director,实现一个生产流程(传入一个生产者,执行生产者的某些方法);
- 设计不同类型的生产者继承 Builder,不同的生产者实现抽象方法,在抽象方法中实现各自对产品 product 的设计;
- 将不同类型的生产者 builder 传入并由 指挥官 director 指挥 生产 产品 product。
可用于生成 不同皮肤、不同大小的人物 等场景。