建造者模式(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# 建造者模式示例,包含 产品类、抽象建造者、具体建造者、指挥者 和 客户端调用,并支持 链式调用:
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()获取结果。
七、总结
建造者模式适用于构造复杂对象的场景,通过解耦构建过程与产品表示,提升代码的灵活性和可维护性。其核心优势在于分步构建和精细控制,但需权衡类数量增加带来的复杂度。在实际开发中,可根据对象复杂度选择是否引入指挥者角色,或直接使用链式调用的简化形式。