简介
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
建造者模式的核心思想就是将一个复杂对象的构建与其表示分离,让用户只需要关注需要构造的对象的属性即可。这样用户不需要知道对象的内部实现细节,只需要通过Builder提供的接口方法来设置对象属性,就可以得到一个完整的对象。
建造者( Builder )模式包含如下角色:
- 抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建。
- 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例。
- 产品类(Product):要创建的复杂对象。
- 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
优点
- 建造者独立,易扩展。
- 便于控制细节风险。
缺点
- 产品必须有共同点,范围有限制。
- 如内部变化复杂,会有很多的建造类。
应用场景
- 需要生成的对象具有复杂的内部结构。
- 需要生成的对象内部属性本身相互依赖。
实现
案例:一个采购系统中,如果需要采购员去采购一批电脑时,在这个实际需求中,电脑就是一个复杂的对象,它是由CPU、主板、硬盘、显卡、机箱等组装而成的,如果此时让采购员一台一台电脑去组装的话真是要累死采购员了,这里就可以采用建造者模式来解决这个问题,我们可以把电脑的各个组件的组装过程封装到一个建造者类对象里,建造者只要负责返还给客户端全部组件都建造完毕的产品对象就可以了。然而现实生活中也是如此的,如果公司要采购一批电脑,此时采购员不可能自己去买各个组件并把它们组织起来,此时采购员只需要像电脑城的老板说自己要采购什么样的电脑就可以了,电脑城老板自然会把组装好的电脑送到公司。
- 抽象建造者:抽象建造者为创建复杂产品对象的各个部分指定抽象创建接口
/// <summary>
/// 抽象制造者-电脑中各个硬件部分的抽象接口
/// </summary>
public abstract class Builder
{
/// <summary>
/// CPU抽象创建
/// </summary>
public abstract void CreateCpu();
/// <summary>
/// 主板抽象创建
/// </summary>
public abstract void CreateMotherboard();
/// <summary>
/// 显卡抽象创建
/// </summary>
public abstract void CreateGraphicsCard();
/// <summary>
/// 获取组装好的电脑信息
/// </summary>
/// <returns></returns>
public abstract Computer GetComputer();
}
- 具体建造者:继承抽象建造者,实现抽象创建接口。指定创建的类型。创建各个具体的部分。
/// <summary>
/// 具体产品创建者-联想电脑各个硬件部分实现接口
/// </summary>
public class LenovoBuilder : Builder
{
Computer computer = new Computer(ComputerType.Lenovo);
public override void CreateCpu()
{
computer.Add("联想CPU");
}
public override void CreateGraphicsCard()
{
computer.Add("联想主板");
}
public override void CreateMotherboard()
{
computer.Add("联想显卡");
}
public override Computer GetComputer()
{
return computer;
}
}
/// <summary>
/// 具体产品创建者-华为电脑各个硬件部分实现接口
/// </summary>
public class HuaweiBuilder : Builder
{
Computer computer = new Computer(ComputerType.Huawei);
public override void CreateCpu()
{
computer.Add("华为CPU");
}
public override void CreateGraphicsCard()
{
computer.Add("华为主板");
}
public override void CreateMotherboard()
{
computer.Add("华为显卡");
}
public override Computer GetComputer()
{
return computer;
}
}
/// <summary>
/// 具体产品创建者-小米电脑各个硬件部分实现接口
/// </summary>
public class XiaomiBuilder : Builder
{
Computer computer = new Computer(ComputerType.Xiaomi);
public override void CreateCpu()
{
computer.Add("小米CPU");
}
public override void CreateGraphicsCard()
{
computer.Add("小米主板");
}
public override void CreateMotherboard()
{
computer.Add("小米显卡");
}
public override Computer GetComputer()
{
return computer;
}
}
- 产品角色:复杂产品对象,将各个部分组成产品的接口
/// <summary>
/// 产品角色:电脑的组装
/// </summary>
public class Computer
{
private ComputerType _type;
public Computer(ComputerType type)
{
_type = type;
}
//电脑配件组装
private List<string> computerParts = new List<string>();
public void Add(string computerPart)
{
computerParts.Add(computerPart);
}
/// <summary>
/// 展示组装过程
///
/// </summary>
public void Show()
{
Console.WriteLine($"电脑组装正式开始!");
foreach (string computerPart in computerParts)
{
Console.WriteLine($"配件:{computerPart} 已装好!");
}
Console.WriteLine("电脑组成完成了!");
}
}
public enum ComputerType : int
{
[Description("华为")]
Huawei = 0,
[Description("联想")]
Lenovo = 1,
[Description("小米")]
Xiaomi = 2,
}
- 指挥者:调用各个部分,按固定的算法创建。不涉及到具体产品类的信息。仅负责各个部分完整的创建
/// <summary>
/// 指挥者(导演)-固定组装算法
/// </summary>
public class Commander
{
public void Construct(Builder builder)
{
builder.CreateMotherboard();
builder.CreateGraphicsCard();
builder.CreateCpu();
}
}
- 上层应用演示调用
{
#region 组装联想电脑
//实例化指挥者
Commander commander = new Commander();
//指定具体产品
Builder builder = new LenovoBuilder();
//组装构建产品
commander.Construct(builder);
//展示产品
Computer computer = builder.GetComputer();
computer.Show();
#endregion
}
{
#region 组装华为电脑
//实例化指挥者
Commander commander = new Commander();
//指定具体产品
Builder builder = new HuaweiBuilder();
//组装构建产品
commander.Construct(builder);
//展示产品
Computer computer = builder.GetComputer();
computer.Show();
#endregion
}
{
#region 组装小米电脑
//实例化指挥者
Commander commander = new Commander();
//指定具体产品
Builder builder = new XiaomiBuilder();
//组装构建产品
commander.Construct(builder);
//展示产品
Computer computer = builder.GetComputer();
computer.Show();
#endregion
}