Builder 建造者模式
前言
当一个对象的构造十分复杂时,我们需要将“构造过程”和他的“表示”进行分离,使得同样的构建过程可以表示不同的对象。
这个时候,需要使用 Builder 模式。用户只需指定建造者的类型就可以得到对应的产品。而具体如何构造用户并不关心。
而不同的对象的构造又是不同的,因此需要不同的建造者一一对应。
类图设计如下:

实例代码
Builer 相关:Builder, BuilderA, BuilderB
/** 抽象创建者 */ public abstract class Builder { abstract Product getProduct(); abstract void builderName(); abstract void builderBody(); } /** 具体创建者,实际场景中,会有多个实现,即一个产品实现对应一个构建者 */ public class BuilderA extends Builder { Product product = new ProductA(); @Override Product getProduct() { return product; } /** 具体构建者需要知道如何构建对象 */ @Override void builderName() { product.name = "Name A"; } @Override void builderBody() { product.body = "Body A"; } } /** 具体创建者,实际场景中,会有多个实现,即一个产品实现对应一个构建者 */ public class BuilderB extends Builder { Product product = new ProductB(); @Override Product getProduct() { return product; } /** 具体构建者需要知道如何构建对象 */ @Override void builderName() { product.name = "Name B"; } @Override void builderBody() { product.body = "Body B"; } }
Product 相关:Product,ProductA,ProductB
/** 产品,可以被抽象 */ public abstract class Product { String name; String body; } public class ProductA extends Product{ String nameA = "New A"; @Override public String toString() { return "ProductB{" + "nameA='" + nameA + '\'' + ", name='" + name + '\'' + ", body='" + body + '\'' + '}'; } } public class ProductB extends Product{ String nameB = "New B"; @Override public String toString() { return "ProductB{" + "nameB='" + nameB + '\'' + ", name='" + name + '\'' + ", body='" + body + '\'' + '}'; } }
Director 相关:Director
/** 指挥者 */ public class Director { /** 此方法可以固定构建对象的过程,只需要传递具体构建者即可 */ void createProduct(Builder builder) { builder.builderName(); builder.builderBody(); } }
测试类:
/** 测试客户端 */ public class BuilderClient { public static void main(String[] args) { Builder a = new BuilderA(); Builder b = new BuilderB(); Director director = new Director(); director.createProduct(a); director.createProduct(b); System.out.println(a.getProduct()); System.out.println(b.getProduct()); } }
结果:
ProductB{nameA='New A', name='Name A', body='Body A'} ProductB{nameB='New B', name='Name B', body='Body B'}
从上面的代码中可以看出,通过构造不同的 Builder,可以得到对应的产品。大家可能会问,为什么不直接创建产品?实际上,生产环境中的构造过程远比 demo 复杂,将构造对象的复杂过程全部放入指挥者 Director 中,能够有效避免创建过程的错误。
通过使用 Builder,能够重复利用创建者,确保每次构造产品都是正确的。
即:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
这里的“同样的构建过程” 就是 Director 中的 createProduct 方法。
“不同的表示”,则是每个 Builder 实现对应一个具体产品的具体构建内容。具体内容可以根据业务需求进行创建。
Spring 框架中,Builder 模式无处不在。总之,Builder 就是为了构建不同的对象的同时,提供了稳定的构建过程,所有对象的构建过程都是被 Driector 指挥的。而对象的具体构建内容则是子类 Builder 来根据需求实现。有效的将对象的内容和构建过程分离,同时也保证了构建过程的稳定,不易出错。
分类:
杂谈
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?