为何在Builder设计模式中需要使用Builder类?
Builder模式里内部Builder类的作用,为啥不用链式Setter?
一、内部Builder类到底是干啥的?
内部Builder类核心就是帮你安全、清晰地创建一个完整的对象,具体说有这几个关键目的:
- 锁住对象的不可变性:目标类(比如示例里的
Employee)写完构造器就没别的修改入口了,一旦通过build()创建出来,字段就不能再改。这种不可变对象在多线程场景下天生安全,也不会被意外修改导致bug。 - 统一做参数校验:你可以在Builder的
build()方法里加校验逻辑,比如判断id不能是负数、name不能为空,确保创建出来的对象一定是合法有效的,不会出现半初始化的状态。 - 解决多字段构造的混乱:如果类有10个字段,写一堆参数不同的重叠构造器会让人晕头转向,用Builder的链式调用
id(1).name("Abc"),谁看都知道每个字段对应啥值,可读性拉满。
二、为啥不直接用链式Setter?
你给的第二种链式Setter写法看起来简洁,但藏着不少坑:
- 对象永远可变:创建完
new Employee().id(1).name("Abc")之后,别人还能调用emp.id(2)改字段,要是在多线程里,一个线程读一个线程改,很容易出问题;而且如果是业务上不允许修改的对象,这种写法根本没法保证。 - 没法确保对象完整:万一你漏写了
id(1),那Employee的id就是默认值0,这个无效对象就直接流入业务逻辑了。但Builder模式可以在build()里强制检查必填字段,没填就抛异常,从根源避免这种情况。 - 语义完全不一样:链式Setter是在修改一个已存在的对象,而Builder的链式调用是在组装一个即将创建的对象,
build()方法明确告诉你“好了,现在这个对象完整了,可以用了”,语义上更贴合对象初始化的场景。
两种写法对比
Builder模式实现
public class Employee { private int id; private String name; public Employee (Builder builder) { this.id = builder.id; this.name = builder.name; } public static class Builder { private int id; private String name; public Builder id(int id) { this.id = id; return this; } public Builder name(String name) { this.name = name; return this; } public Employee build() { // 这里可以加校验:比如id <=0 抛异常,name为空抛异常 return new Employee(this); } } } // 使用方式 Employee emp = new Employee.Builder().id(1).name("Abc").build();
链式Setter实现
public class Employee { private int id; private String name; public Employee id(int id) { this.id = id; return this; } public Employee name(String name) { this.name = name; return this; } } // 使用方式 Employee emp = new Employee().id(1).name("Abc");
内容的提问来源于stack exchange,提问作者Shameem94
相关产品推荐
相关产品推荐

