建造者模式(Builder Pattern)是23种经典设计模式中的创建型模式之一,其核心思想是将复杂对象的构建过程与其表示分离,使得同样的构建流程可以生成不同结构或配置的对象。以下从定义、结构、应用场景、优缺点及代码示例展开分析:
一、模式定义
建造者模式通过分步构建复杂对象,将对象的构造逻辑(如部件创建、组装顺序)封装在独立的建造者类中,客户端只需指定建造者类型即可获得最终产品,无需了解内部细节。
类比:如同在餐厅点餐,顾客只需选择套餐类型(如A套餐、B套餐),厨师(建造者)会按固定流程准备食材(部件)并组合成完整餐品(产品)。
二、模式结构
建造者模式通常包含以下角色:
1.产品(Product)
复杂对象,由多个部件组成(如汽车由引擎、轮胎、车身等部件构成)。
2.抽象建造者(Builder)
定义创建产品各部件的抽象方法(如buildEngine()、buildWheel()),并提供获取最终产品的方法(如getVehicle())。
3.具体建造者(ConcreteBuilder)
实现抽象建造者接口,具体定义部件的创建和组装逻辑,返回不同配置的产品实例。
4.指挥者(Director)
封装构建流程,调用建造者的方法按固定顺序组装产品(可选角色,客户端也可直接调用建造者)。
三、应用场景
1.复杂对象构造
对象由多个部件构成,且部件创建步骤复杂(如计算机组装需选择CPU、内存、硬盘等)。
2.相同流程不同表示
构建过程稳定,但部件组合方式多样(如汽车可组装为SUV、跑车等不同型号)。
3.隔离构造与使用
客户端无需关心对象内部细节,只需关注最终产品(如通过StringBuilder.append()逐步构建字符串,最后调用toString()获取结果)。
4.可选部件处理
对象包含可选属性,避免使用冗长的构造函数或Setter方法(如通过链式调用设置对象属性)。
四、优缺点分析
1.优点
(1)解耦构建与表示:客户端无需知道产品内部结构,只需指定建造者类型。
(2)扩展性强:新增具体建造者不影响现有代码,符合开闭原则。
(3)控制构建细节:可灵活调整部件创建顺序或条件(如根据配置选择引擎类型)。
2.缺点
(1)类数量增加:需定义抽象建造者、具体建造者等额外类,系统复杂度上升。
(2)维护成本高:若产品内部结构变化,所有建造者均需修改。
(3)适用范围有限:仅适用于部件数量多、构造过程复杂的对象。
五、代码示例(C#)
以下是一个 完整的 C# 建造者模式示例,包含 产品类、抽象建造者、具体建造者、指挥者 和 客户端调用,并支持 链式调用:
csharp
using System;
// 1. 产品类(Computer)
public class Computer
{
public string CPU { get; set; }
public string RAM { get; set; }
public string Storage { get; set; }
public string GPU { get; set; }
public bool HasKeyboard { get; set; }
public bool HasMouse { get; set; }
public override string ToString()
{
return $@"
Computer Configuration:
CPU: {CPU}
RAM: {RAM}
Storage: {Storage}
GPU: {GPU}
Keyboard: {(HasKeyboard ? "Included" : "Not Included")}
Mouse: {(HasMouse ? "Included" : "Not Included")}";
}
}
// 2. 抽象建造者(IComputerBuilder)
public interface IComputerBuilder
{
IComputerBuilder SetCPU(string cpu);
IComputerBuilder SetRAM(string ram);
IComputerBuilder SetStorage(string storage);
IComputerBuilder SetGPU(string gpu);
IComputerBuilder IncludeKeyboard(bool include);
IComputerBuilder IncludeMouse(bool include);
Computer Build();
}
// 3. 具体建造者(GamingComputerBuilder)
public class GamingComputerBuilder : IComputerBuilder
{
private Computer _computer = new Computer();
public IComputerBuilder SetCPU(string cpu) { _computer.CPU = cpu; return this; }
public IComputerBuilder SetRAM(string ram) { _computer.RAM = ram; return this; }
public IComputerBuilder SetStorage(string storage) { _computer.Storage = storage; return this; }
public IComputerBuilder SetGPU(string gpu) { _computer.GPU = gpu; return this; }
public IComputerBuilder IncludeKeyboard(bool include) { _computer.HasKeyboard = include; return this; }
public IComputerBuilder IncludeMouse(bool include) { _computer.HasMouse = include; return this; }
public Computer Build() { return _computer; }
}
// 4. 指挥者(ComputerDirector)
public class ComputerDirector
{
public Computer BuildGamingPC(IComputerBuilder builder)
{
return builder
.SetCPU("AMD Ryzen 9 5900X")
.SetRAM("64GB DDR4")
.SetStorage("2TB NVMe SSD")
.SetGPU("NVIDIA RTX 3080 Ti")
.IncludeKeyboard(true)
.IncludeMouse(true)
.Build();
}
public Computer BuildOfficePC(IComputerBuilder builder)
{
return builder
.SetCPU("Intel i5")
.SetRAM("16GB DDR4")
.SetStorage("512GB SSD")
.SetGPU("Integrated Graphics")
.IncludeKeyboard(false)
.IncludeMouse(false)
.Build();
}
}
// 5. 客户端代码
class Program
{
static void Main()
{
// 使用指挥者构建标准配置
var director = new ComputerDirector();
var builder = new GamingComputerBuilder();
Computer gamingPC = director.BuildGamingPC(builder);
Computer officePC = director.BuildOfficePC(builder);
Console.WriteLine("=== Standard Gaming PC ===");
Console.WriteLine(gamingPC);
Console.WriteLine("\n=== Standard Office PC ===");
Console.WriteLine(officePC);
// 直接链式调用自定义配置
Computer customPC = new GamingComputerBuilder()
.SetCPU("Apple M1 Ultra")
.SetRAM("128GB")
.SetStorage("8TB SSD")
.SetGPU("AMD Radeon Pro")
.IncludeKeyboard(true)
.Build();
Console.WriteLine("\n=== Custom PC ===");
Console.WriteLine(customPC);
}
}
关键设计点
1.链式调用
通过返回 IComputerBuilder 实现流畅接口(如 SetCPU().SetRAM().Build())。
2.指挥者
封装固定构建流程(如 BuildGamingPC()),适合重复性构造。
3.灵活性
既可通过指挥者快速构建标准配置,也可直接链式调用自定义配置。
适用于需要 分步构建复杂对象 且 支持多种配置 的场景(如电脑、汽车、报表生成等)。
六、模式变体与实际应用
1.链式调用
通过方法返回this实现链式调用(如new Computer.Builder().cpu("i9").ram("32GB").build()),简化客户端代码。
2.与工厂模式结合
工厂模式关注对象创建,建造者模式关注对象构造过程,两者可结合使用(如先通过工厂获取建造者,再调用建造者组装产品)。
3.JDK中的应用
StringBuilder、StringBuffer均采用建造者模式,通过append()方法逐步构建字符串,最后调用toString()获取结果。
七、总结
建造者模式适用于构造复杂对象的场景,通过解耦构建过程与产品表示,提升代码的灵活性和可维护性。其核心优势在于分步构建和精细控制,但需权衡类数量增加带来的复杂度。在实际开发中,可根据对象复杂度选择是否引入指挥者角色,或直接使用链式调用的简化形式。
