写点什么

【愚公系列】2022 年 05 月 二十三种设计模式 (三)- 建造者模式 (Builder Pattern)

作者:愚公搬代码
  • 2022 年 5 月 03 日
  • 本文字数:3123 字

    阅读完需:约 10 分钟

前言

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。

一、建造者模式(Builder Pattern)

建造者模式属于创建型模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。


建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。

二、使用步骤

角色

1、抽象建造者(Builder)


给出一个抽象结论,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的对象部件的创建;


2、具体建造者(Concrete Builder)


实现建造者接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。在构造过程完成后,提供产品的实例;


3、指导者(Director)


调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建;


4、产品类(Product)


需要创建的具体的复杂对象。

示例



命名空间 BuilderPattern 中包含 Vehicle 机动车类充当产品类,Builder 基类为抽象建造者,东风悦达 Yuedakia 类、大众汽车 Volkswagen 类、特斯拉 Tesla 类。另外包含 1 个机动车扩展类和 1 个指导者。本示例向大家演示 3 个不同的汽车厂商在生产比较复杂的汽车时所采用的策略。


public abstract class Builder {
protected Vehicle _product = new Vehicle();
public abstract void BuildCarframe();
public abstract void BuildWheel();
public abstract void BuildDoor();
public abstract void BuildApparatus();
public abstract void BuildColor();
public virtual Vehicle GetResult() { return _product; }
}
复制代码


建造者基类 Builder,定义生产不同汽车部位的接口并在内部维持对机动车的引用。


public class Tesla : Builder {
public override void BuildCarframe() { _product.Carframe = "ZZ32093M3485C1356"; }
public override void BuildWheel() { _product.Wheel = 4; }
public override void BuildDoor() { _product.Door = 5; }
public override void BuildApparatus() { _product.Apparatus = "Model X"; }
public override void BuildColor() { _product.Color = Color.Red; }
}
复制代码


具体建造者特斯拉 Tesla 类,实现抽象建造者 Builder 的接口。


public class Volkswagen : Builder {
public override void BuildCarframe() { _product.Carframe = "VS89362P1903C9852"; }
public override void BuildWheel() { _product.Wheel = 4; }
public override void BuildDoor() { _product.Door = 4; }
public override void BuildApparatus() { _product.Apparatus = "Skoda"; }
public override void BuildColor() { _product.Color = Color.Blue; }
}
复制代码


具体建造者大众汽车 Volkswagen 类,实现抽象建造者 Builder 的接口。


public class Yuedakia : Builder {
public override void BuildCarframe() { _product.Carframe = "YK9391J0231L30D32"; }
public override void BuildWheel() { _product.Wheel = 4; }
public override void BuildDoor() { _product.Door = 4; }
public override void BuildApparatus() { _product.Apparatus = "Kia K3"; }
public override void BuildColor() { _product.Color = Color.Wheat; }
}
复制代码


具体建造者东风悦达 Yuedakia 类,实现抽象建造者 Builder 的接口。


public class Vehicle {     public string Carframe { get; set; }     public int Wheel { get; set; }     public int Door { get; set; }     public string Apparatus { get; set; }     public Color Color { get; set; }     public void Print() {        Console.WriteLine($"{this.VehicleInfo()}");    } }
复制代码


机动车 Vehicle 类,这是我们通过建造者模式所要创建的复杂对象。


public class Director {
public void Construct(Builder builder) { builder.BuildCarframe(); builder.BuildWheel(); builder.BuildDoor(); builder.BuildApparatus(); builder.BuildColor(); }
}
复制代码


这是指导类 Director,它负责对象的创建过程。


public static class Extentions {     public static string VehicleInfo(this Vehicle vehicle) {        var type = vehicle.GetType();        var properties = type.GetProperties();        var result = string.Empty;        foreach (var prop in properties) {            result +=                $"{prop.Name}:{prop.GetValue(vehicle, null)}{Environment.NewLine}";        }        return result;    } }
复制代码


一个扩展类,方便演示过程中打印出相关信息。


public class Program {
private static Director _director = null;
private static List<Builder> _builders = null;
private static Vehicle _vehicle = null;
public static void Main(string[] args) { _director = new Director(); _vehicle = new Vehicle();
_builders = new List<Builder>() { new Tesla(), new Volkswagen(), new Yuedakia() };
foreach (var builder in _builders) { _director.Construct(builder); _vehicle = builder.GetResult(); _vehicle.Print(); }
Console.ReadKey(); }
}
复制代码


以上是调用方的代码,分别维持对指导者、建造者和机动车的引用,接下来我们创建了 3 辆汽车,特斯拉的 Model X、大众汽车的 Skoda 和东风悦达的 Kia K3。以下是这个案例的输出结果:


Carframe:ZZ32093M3485C1356Wheel:4Door:5Apparatus:Model XColor:Color [Red]
Carframe:VS89362P1903C9852Wheel:4Door:4Apparatus:SkodaColor:Color [Blue]
Carframe:YK9391J0231L30D32Wheel:4Door:4Apparatus:Kia K3Color:Color [Wheat]
复制代码


<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

总结

优点

1、易于解耦,将产品本身与产品创建过程进行解耦,可以使用相同的创建过程来得到不同的产品;2、易于精确控制对象的创建,将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰;3、易于拓展,增加新的具体建造者无需修改原有类库的代码,易于拓展,符合“开闭原则”。

缺点

1、建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;2、如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制;3、如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

使用场景

1、需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;2、隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

发布于: 刚刚阅读数: 2
用户头像

还未添加个人签名 2022.03.01 加入

该博客包括:.NET、Java、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、python、大数据等相关使用及进阶知识。查看博客过程中,如有任何问题,皆可随时沟通。

评论

发布
暂无评论
【愚公系列】2022 年 05 月 二十三种设计模式(三)-建造者模式(Builder Pattern)_5月月更_愚公搬代码_InfoQ写作社区