Java 23 种设计模式:从踩坑到精通 | 建造者模式 —— 构造器参数太多?试试链式调用

张开发
2026/6/4 20:52:59 15 分钟阅读

分享文章

Java 23 种设计模式:从踩坑到精通 | 建造者模式 —— 构造器参数太多?试试链式调用
Java 23 种设计模式从踩坑到精通 | Builder —— 构造器参数太多试试链式调用摘要当一个对象有十几个甚至几十个可选参数时重叠构造器会让代码臃肿难读setter又可能破坏不可变性。建造者模式通过链式调用分步构建对象既清晰又安全。本文从“构造器地狱”出发带你拆解 Builder 的实现原理、变体写法与工厂模式对比并给出 LombokBuilder、StringBuilder等实战案例彻底掌握优雅的对象创建之道。《Java 23 种设计模式从踩坑到精通》开篇系列介绍与目录 上一篇抽象工厂模式 当前建造者模式 下一篇原型模式 返回系列总目录1. 从“构造器地狱”说起假设你要定义一个“电脑”对象它有 CPU、内存、硬盘、显卡、显示器等几十个配置有些是必选的大多数是可选的。如果使用重叠构造器代码会变成这样publicclassComputer{privateStringcpu;// 必选privateStringram;// 必选privateStringhdd;// 可选privateStringgpu;// 可选privateStringmonitor;// 可选publicComputer(Stringcpu,Stringram){...}publicComputer(Stringcpu,Stringram,Stringhdd){...}publicComputer(Stringcpu,Stringram,Stringhdd,Stringgpu){...}// 无穷无尽的构造器重载...}调用时参数顺序极易出错可读性极差。如果改用 JavaBean 的setter模式虽然调用清晰了却会导致对象在构造过程中可能处于不一致状态且失去了不可变性。建造者模式正是为这类“参数爆炸”场景而生的它通过一个内部 Builder 类将必选参数放在 Builder 构造器中可选参数通过链式方法设置最后调用build()一次性创建不可变对象。1.1 你的代码该不该用 Builder判断标准是 → 用 Builder否 → 用普通构造器/工厂对象参数 ≥ 4 个且多数可选✅❌需要保证对象创建后不可变✅❌构造过程中需要参数校验✅❌参数只有 2~3 个且全部必选❌✅2. 模式定义与 UML 结构建造者模式将一个复杂对象的构建与它的表示分离使得同样的构建过程可以创建不同的表示。它属于创建型设计模式。标准建造者模式的 UML 类图四个角色产品Product最终被创建的复杂对象抽象建造者Builder定义创建产品各个部件的接口具体建造者ConcreteBuilder实现 Builder 接口完成各部件的具体建造并返回产品导演Director控制建造过程按特定顺序调用建造者的构建步骤可选。3. 代码实现组装电脑3.1 产品类publicclassComputer{privateStringcpu;// 必选privateStringram;// 必选privateStringhdd;// 可选privateStringgpu;// 可选privateStringmonitor;// 可选// 构造器设为 private只能通过 Builder 创建privateComputer(Builderbuilder){this.cpubuilder.cpu;this.rambuilder.ram;this.hddbuilder.hdd;this.gpubuilder.gpu;this.monitorbuilder.monitor;}OverridepublicStringtoString(){returnComputer{cpucpu\, ramram\, hddhdd\, gpugpu\, monitormonitor\};}// 静态内部类建造者publicstaticclassBuilder{privateStringcpu;privateStringram;privateStringhdd;privateStringgpu;privateStringmonitor;// 必选参数通过 Builder 构造器传入publicBuilder(Stringcpu,Stringram){this.cpucpu;this.ramram;}// 可选参数通过链式 setter 设置publicBuilderhdd(Stringhdd){this.hddhdd;returnthis;}publicBuildergpu(Stringgpu){this.gpugpu;returnthis;}publicBuildermonitor(Stringmonitor){this.monitormonitor;returnthis;}// 最终构建方法publicComputerbuild(){returnnewComputer(this);}}}✅ 构建链式调用清晰易读且Computer对象一旦创建便不可变线程安全。3.2 客户端调用ComputercomputernewComputer.Builder(Intel i9,32GB).hdd(1TB SSD).gpu(RTX 4090).monitor(4K Dell).build();System.out.println(computer);// Computer{cpuIntel i9, ram32GB, hdd1TB SSD, gpuRTX 4090, monitor4K Dell}3.3 使用 Director 控制标准流程当需要按照严格步骤建造或者存在多种标准配置时可以引入导演类。publicclassComputerDirector{publicComputerbuildGamingPC(){returnnewComputer.Builder(AMD Ryzen 9,32GB).gpu(RTX 4080).hdd(2TB NVMe).monitor(144Hz 2K).build();}publicComputerbuildOfficePC(){returnnewComputer.Builder(Intel i5,16GB).hdd(512GB SSD).build();}}4. 建造者模式 vs 工厂模式对比维度工厂模式建造者模式关注点产品类型的选择创建哪种产品产品内部构件的组装过程如何一步步创建对象复杂度一般创建单个对象构造简单创建复杂对象参数多、构建步骤多表示差异不同工厂返回不同子类产品同样的构建过程可以创建不同表示内部组成不同创建方式一次性返回完整对象分步骤构建最后调用build()产出选型口诀创建对象简单、重点在种类 → 用工厂创建对象复杂、参数多、步骤多 → 用建造者。5. 框架与实践中的应用5.1 JDKStringBuilderStringBuilder通过append()逐步添加内容最后toString()返回不可变字符串。StringresultnewStringBuilder().append(Hello).append( ).append(World).append(!).toString();5.2 Lombok BuilderLombok 在编译期自动生成建造者代码。BuilderpublicclassUser{privateStringname;privateintage;privateStringemail;}UseruserUser.builder().name(Andy).age(30).email(andyexample.com).build();5.3 SpringRestTemplateBuilder / UriComponentsBuilderSpring 中大量使用 Builder 来构建复杂对象。5.4 MyBatisSqlSessionFactoryBuilderSqlSessionFactoryBuilder负责读取配置文件一步步构建出SqlSessionFactory是标准的建造者模式。6. 优缺点一览优点缺点解耦构建与表示客户端不必知道产品内部结构代码量增加每个产品都要配套建造者类链式调用可读性强接口变动影响大增加字段需要同步修改 Builder保证对象完整性可在build()中校验不适合参数很少的简单对象7. 常见误区与面试高频题❌ 误区1建造者模式就是链式 setter链式调用只是表现核心在于分离构建与表示并保证最终对象的不可变性。❌ 误区2参数多就一定用 Builder如果参数只有两三个且都是必选简单构造器或静态工厂方法更简洁。 面试高频追问Builder 与工厂模式的区别→ 工厂关注产品类型一次性创建Builder 关注内部组装分步构建。StringBuilder 为什么是建造者模式→append()逐步添加字符最终toString()返回不可变字符串。Lombok Builder 的优缺点→ 简化代码但隐藏细节且不便于调试。恭喜如果你能分清“参数多且可选用 Builder参数少且固定用工厂/构造器”你就已经掌握了创建型模式选型的核心原则。面试中问到“创建复杂对象的最佳实践”Builder 就是你的王牌答案。8. 六大设计原则在建造者模式中的体现设计原则体现单一职责SRP产品负责数据Builder 负责组装Director 负责流程开闭原则OCP可通过扩展具体 Builder 创建不同产品表示里氏替换LSP不同 Builder 遵循同一接口可替换依赖倒置DIPDirector 依赖抽象 Builder不依赖具体建造者接口隔离ISPBuilder 接口只定义构建相关方法迪米特法则LoD客户端只与 Builder 交互无需了解产品内部 《Java 23 种设计模式从踩坑到精通》快速导航开篇系列介绍与目录上一篇抽象工厂模式当前建造者模式你在这里下一篇原型模式 即将发布创建型模式汇总单例、工厂、建造者、原型结构型模式汇总适配器、装饰器、代理……行为型模式汇总观察者、策略、模板方法…… 关注《Java 23 种设计模式从踩坑到精通》用 25 篇文章彻底吃透设计模式。福利预告全系列代码及 UML 源码将在完结时统一打包开放点击「关注」「收藏」第一时间获取。下一篇原型模式 —— 克隆对象深拷贝与浅拷贝的坑你踩过吗 即将发布敬请关注 除了设计模式我也在深挖智能物流实战WMS、托盘调度、机器学习落地。欢迎点击头像看看专栏 《出版社物流WMS智能调度实战》。技术相通思路可鉴。

更多文章