建造者模式 Builder
建造者模式:将一个复杂对象的构建于它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式解决的是 “产品部分” 的需求变化问题,而抽象工厂模式解决的是“系列产品”的需求变化问题。
//目标复杂对象的实体类
public class Transformers
{
public string TransName { get; set; } //名称
private List<string> allParts = new List<string>(); //组成部分
public void AssemblePart(string part) //组装
{
allParts.Add(part);
}
public void ShowTime() //展示
{
Console.WriteLine("变形金刚开始变形……");
foreach (var part in allParts)
{
Console.WriteLine("模块【" + part + "】组合完成…");
}
Console.WriteLine("I am " + TransName + " !");
Console.WriteLine("变形金刚变形完毕!\n");
}
}
//封装了建造各部分模块功能的抽象类
public abstract class BuilderTrans
{
public abstract void BuildHead(); //建造模块1的功能
public abstract void BuildBody(); //建造模块2的功能
public abstract void BuildHand(); //建造模块3的功能
public abstract void BuildFoot(); //建造模块4的功能
public abstract void SetTransName(); //建造模块5的功能
public abstract Transformers GetResult(); //返回复杂对象整体
}
//原来的需求
public class BuilderTrans1 : BuilderTrans
{
Transformers trans1 = new Transformers();
public override void SetTransName()
{
trans1.TransName = "擎天柱";
}
public override void BuildHead()
{
trans1.AssemblePart("擎天柱头部");
}
public override void BuildBody()
{
trans1.AssemblePart("擎天柱躯干");
}
public override void BuildHand()
{
trans1.AssemblePart("擎天柱双手");
}
public override void BuildFoot()
{
trans1.AssemblePart("擎天柱双脚");
}
public override Transformers GetResult()
{
return trans1;
}
}
//新增的需求
public class BuilderTrans2 : BuilderTrans
{
Transformers trans2 = new Transformers();
public override void SetTransName()
{
trans2.TransName = "大黄蜂";
}
public override void BuildHead()
{
trans2.AssemblePart("大黄蜂头部");
}
public override void BuildBody()
{
trans2.AssemblePart("大黄蜂躯干");
}
public override void BuildHand()
{
trans2.AssemblePart("大黄蜂双手");
}
public override void BuildFoot()
{
trans2.AssemblePart("大黄蜂双脚");
}
public override Transformers GetResult()
{
return trans2;
}
}
//让具体建造者开始生产各模块的实体类
public class BossCommand
{
public void BeginTrans(BuilderTrans builder) //调用建造者生产各个模块
{
builder.BuildHead(); //建造模块1
builder.BuildBody(); //建造模块2
builder.BuildHand(); //建造模块3
builder.BuildFoot(); //建造模块4
builder.SetTransName(); //建造模块5
}
}
//程序调用入口(Main方法)
class Program
{
static void Main(string[] args)
{
BossCommand command = new BossCommand(); //实例化准备对所有建造者下达命令
//原来的需求
BuilderTrans builderTrans1 = new BuilderTrans1(); //实例化专门的建造者
command.BeginTrans(builderTrans1); //受命建造各模块,若省略则结果只是没有各模块的“空壳”。
builderTrans1.GetResult().ShowTime(); //建造者返回建造结果并展示
//新增的需求
BuilderTrans builderTrans2 = new BuilderTrans2();
command.BeginTrans(builderTrans2);
builderTrans2.GetResult().ShowTime();
Console.ReadKey();
}
}
由于建造者封装(隐藏)了具体产品(模块)的创建/组装过程,所以要改变一个产品的内部表示,只需要再实现一个具体的建造者就可以了,从而能很好地应对产品组成组件的需求变化。