审校 | 梁策 孙淑娟
创新互联建站于2013年成立,是专业互联网技术服务公司,拥有项目网站建设、做网站网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元青县做网站,已为上家服务,为青县各地企业和个人服务,联系电话:13518219792
我们将研究如何通过Lombok的@Builder注解让含有多个入参的方法更容易被调用,从而提高可用性。
怎样才能更灵活方便地调用多入参方法呢?请看下面的例子:
void method(@NotNull String firstParam, @NotNull String secondParam,
String thirdParam, String fourthParam,
Long fifthParam, @NotNull Object sixthParam) {
...
}
如果非空参数是可选的,那么有以下几种调用方式:
method("A", "B", null, null, null, new Object());
method("A", "B", "C", null, 2L, "D");
method("A", "B", null, null, 3L, this);
...
这个例子暴露了一些问题,比如:
从提供者的角度来看,如果要提供参数较少的方法则需要大量重载,如下:
void method(@NotNull String firstParam, @NotNull String secondParam, @NotNull Object sixthParam);
void method(@NotNull String firstParam, @NotNull String secondParam, String thirdParam, @NotNull Object sixthParam);
void method(@NotNull String firstParam, @NotNull String secondParam, String thirdParam, String fourthParam, @NotNull Object sixthParam);
void method(@NotNull String firstParam, @NotNull String secondParam, String thirdParam, String fourthParam, Long fifthParam, @NotNull Object sixthParam);
...
为了提高可用性且避免重复代码,我们可以使用方法构建器。Lombok项目已经提供了一个注解,它可以使生成构建器变得更简单。因此,上面的例子可以改造为以下方式:
@Builder(builderMethodName = "methodBuilder", buildMethodName = "call")
void method(@NotNull String firstParam, @NotNull String secondParam,
String thirdParam, String fourthParam,
Long fifthParam, @NotNull Object sixthParam) {
...
}
然后就可以这样调用方法:
methodBuilder()
.firstParam("A")
.secondParam("B")
.sixthParam(new Object())
.call();
methodBuilder()
.firstParam("A")
.secondParam("B")
.thirdParam("C")
.fifthParam(2L)
.sixthParam("D")
.call();
methodBuilder()
.firstParam("A")
.secondParam("B")
.fifthParam(3L)
.sixthParam(this)
.call();
这样一来,方法的可读性及灵活性都提高了。
在许多情况下,需要去为方法的入参指定默认值,而Java与其他一些语言不同,它没有语义来支持这一需求。因此,在大多数情况下,它都是通过方法重载来实现的,如下:
method() { method("Hello"); }
method(String a) { method(a, "builder"); }
method(String a, String b) { method(a, b, "world!"); }
method(String a, String b, String c) { ... acutal logic here ... }
当使用Lombok builder时,会在目标类中生成一个构建器类。这个构建器类:
该类也可以手动定义,这样就可以为参数定义默认值。上面的方法也就可以写成:
@Builder(builderMethodName = "methodBuilder", buildMethodName = "call", builderClassName = "MethodBuilder")
method(String a, String b, String c) {
... acutal logic here ...
}
private class MethodBuilder {
private String a = "Hello";
private String b = "builder";
private String c = "world!";
}
有了这个补充,如果调用者没有指定一个参数,那么将使用构建器类中定义的默认值。
注意:在这种情况下,我们不需要在类中声明该方法的所有入参,Lombok会自动配置。
我们会有通过入参去定义返回类型的需求,例如:
publicT read(byte[] content, Class type) {...}
在这种情况下,builder类将是一个泛型类,但是builder方法将创建一个没有约束类型的实例。请看下面的例子:
@Builder(builderMethodName = "methodBuilder", buildMethodName = "call", builderClassName = "MethodBuilder")
publicT read(byte[] content, Class type) {...}
在这种情况下,methodBuilder方法将创建一个没有约束类型的MethodBuilder实例。这导致下面的代码不会被编译(入参定义为Class,传入Class):
methodBuilder()
.content(new byte[]{})
.type(String.class)
.call();
上述问题可以通过强制转换类型来解决:
methodBuilder()
.content(new byte[]{})
.type((Class)String.class)
.call();
这样,它就可以通过编译。但是这么使用,调用方法后返回的类型不是String,而是未知类型的泛型T。
String result = (String)methodBuilder()
.content(new byte[]{})
.type((Class)String.class)
.call();
那么,我们需要再将输出结果进行强制转换。而我们最初的目的是提供一种方便调用者的方法,因此建议考虑下面的两种解决方案之一。
如上所述,问题的根源在于builder方法在没有传入特定类型参数的情况下,创建了builder类的实例。所以我们可以在类中重载构建器方法,并实例化一个指定类型的构建器类:
@Builder(builderMethodName = "methodBuilder", buildMethodName = "call", builderClassName = "MethodBuilder")
publicT read(final byte[] content, final Class type) {...}
publicMethodBuilder methodBuilder(final Class type) {
return new MethodBuilder().type(type);
}
public class MethodBuilder{
private Classtype;
public MethodBuildertype(Class type) { this.type = type; return this; }
public T call() { return read(content, type); }
}
在这种情况下,调用者不需要进行强制类型转换,调用过程如下:
List result = methodBuilder(List.class)
.content(new byte[]{})
.call();
也可以在类型参数set方法中强转构建器实例类型:
@Builder(builderMethodName = "methodBuilder", buildMethodName = "call", builderClassName = "MethodBuilder")
publicT read(final byte[] content, final Class type) {...}
public class MethodBuilder{
private Classtype;
publicMethodBuilder type(final Class type) {
this.type = (Class)type;
return (MethodBuilder) this;
}
public T call() { return read(content, type); }
}
使用这种方式就不需要手动定义构建器方法。从调用者的角度来看,类型参数就像其他参数一样直接传入。
在方法上使用@Builder可以带来以下优势:
需要注意的是,在某些情况下,使用方法构建器会给提供者带来不必要的复杂情况。各类方法构建器的demo可参考GitHub上的信息。
翟珂,社区编辑,目前在杭州从事软件研发工作,做过电商、征信等方面的系统,享受分享知识的过程,充实自己的生活。
原文标题:Method Builder With Lombok @Builder,作者:Daniel Buza
当前标题:使用Lombok的@Builder注解实现构造器模式
URL分享:http://www.csdahua.cn/qtweb/news5/271155.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网