Builder 使用创建者模式又叫建造者模式。简单来说,就是一步步创建一个对象,它对用户屏蔽了里面构建的细节,但却可以精细地控制对象的构造过程。
大家在构建大对象时,对象的属性比较多,我们可以采用一个构造器或者使用空的构造器构造,然后使用setter方法去设置。在使用者使用这些方法时,会很多冗长的构造器参数列表或者setter方法。我们可以使用Builder模式来简化大对象的构造,提高代码的简洁性,同时提高使用者的编码体验。
一个类的定义通常只会有一个地方,而使用这个类的地方会有很多,在定义类时为使用者多考虑一些,就能为使用这个类的开发者提高很多效率,同时让整个团队的代码变的更加简洁。
我一直认为一个类的设计和一个产品的设计者理念相同,产品经理设计一个功能首先能解决用户的痛点,同时还要提高用户体验,让用户用着爽。同样设计一个基础类,需要解决一个业务问题,同时需要从使用者的角度考虑,让使用者用着爽。一个优秀的基础类的设计者需要一点产品思维,代码就是你的产品。
Lombok是一个可以让Java代码变的更加简洁、让你的开发更加高效的利器。使用了Lombok之后,我们不需要写Getter&Setter、ToString等方法,这些都可以通过注解来代替,在编译期间,Lombok会帮助你生成相应的字节码。所以也不用担心性能损失。
Lombok也支持了Builder模式,你可以用几个注解来代替以上冗余的代码。
@Builder
publicclassOrder {
privateStringcode;
@Singular
privateList<String>offers;
@Singular
privateMap<String, Object>features;
}
使用:
Orderorder=Order.builder().code("1234")
.offer("满100减5")
.feature("category", "category")
.build();
@Builder内部操作
- 创建一个名为
ThisClassBuilder
的内部静态类,并具有和实体类相同的属性(称为构建器)。 - 在构建器中:对于目标类中的所有的属性和未初始化的
final
字段,都会在构建器中创建对应属性。 - 在构建器中:创建一个无参的
default
构造函数。 - 在构建器中:对于实体类中的每个参数,都会对应创建类似于
setter
的方法,只不过方法名与该参数名相同。 并且返回值是构建器本身(便于链式调用),如上例所示。 - 在构建器中:一个
build()
方法,调用此方法,就会根据设置的值进行创建实体对象。 - 在构建器中:同时也会生成一个
toString()
方法。 - 在实体类中:会创建一个
builder()
方法,它的目的是用来创建构建器。
@Builder
publicclassUser {
privatefinalIntegercode=200;
privateStringusername;
privateStringpassword;
}
// 编译后:
publicclassUser {
privateStringusername;
privateStringpassword;
User(Stringusername, Stringpassword) {
this.username=username; this.password=password;
}
publicstaticUser.UserBuilderbuilder() {
returnnewUser.UserBuilder();
}
publicstaticclassUserBuilder {
privateStringusername;
privateStringpassword;
UserBuilder() {}
publicUser.UserBuilderusername(Stringusername) {
this.username=username;
returnthis;
}
publicUser.UserBuilderpassword(Stringpassword) {
this.password=password;
returnthis;
}
publicUserbuild() {
returnnewUser(this.username, this.password);
}
publicStringtoString() {
return"User.UserBuilder(username="+this.username+", password="+this.password+")";
}
}
}
1. @Singular
Singular:单一的
@Builder
也可以为集合类型的参数或字段生成一种特殊的方法。 它采用修改列表中一个元素而不是整个列表的方式,可以是增加一个元素,也可以是删除一个元素。
Student.builder()
.sno( "001" )
.sname( "admin" )
.sage( 18 )
.sphone( "110" ).sphone( "112" )
.build();
这样就可以轻松地将List <String>
字段中包含2个字符串。 但是想要这样来操作集合,你需要使用@Singular
来注释字段或参数。
在使用@Singular
注释注释一个集合字段(使用@Builder
注释类),lombok
会将该构建器节点视为一个集合,并生成两个adder
方法而不是setter
方法。
- 一个向集合添加单个元素
- 一个将另一个集合的所有元素添加到集合中
将不生成仅设置集合(替换已添加的任何内容)的setter。 还生成了clear方法。 这些singular构建器相对而言是有些复杂的,主要是来保证以下特性:
- 在调用
build()
时,生成的集合将是不可变的。 - 在调用
build()
之后调用其中一个adder
方法或clear
方法不会修改任何已经生成的对象。如果对集合修改之后,再调用build()
,则会创建一个基于上一个对象创建的对象实体。 - 生成的集合将被压缩到最小的可行格式,同时保持高效。