当前位置: 首页 > 科技观察

使用Lombok的@Builder注解实现构造器模式_0

时间:2023-03-13 22:16:43 科技观察

使用Lombok的@Builder注解实现构造函数模式。使用@Builder的简单方法如何调用多输入法更加灵活方便?请看下面的例子:voidmethod(@NotNullStringfirstParam,@NotNullStringsecondParam,StringthirdParam,StringfourthParam,LongfifthParam,@NotNullObjectsixthParam){...}如果非空参数是可选的,那么有以下调用方法:method("A","B",null,null,null,newObject());method("A","B","C",null,2L,"D");method("A","B",null,null,3L,this);...这个例子暴露了一些问题,如:调用者必须知道修改哪个参数(比如第一个调用方法改成第二个,调用者必须知道修改第五个参数为Long类型)。输入参数的顺序不能改变。需要传入的参数名是不可见的。从提供者的角度来看,如果想提供一个参数较少的方法,需要大量的重载,如下:voidmethod(@NotNullStringfirstParam,@NotNullStringsecondParam,StringthirdParam,@NotNullObjectsixthParam);voidmethod(@NotNullStringfirstParam,@NotNullStringsecondParam,StringthirdParam,StringfourthParam,@NotNullObjectsixthParam);voidmethod(@NotNullString@NotNParam,StringsecondParam,StringthirdParam,StringfourthParam,LongfifthParam,@NotNullObjectsixthParam);...为了提高可用性和避免代码重复,我们可以使用方法构建器。Lombok项目已经提供了一个注解,可以更轻松地生成构建器。因此,上面的例子可以转化为如下方式:@Builder(builderMethodName="methodBuilder",buildMethodName="call")voidmethod(@NotNullStringfirstParam,@NotNullStringsecondParam,StringthirdParam,StringfourthParam,LongfifthParam,@NotNullObjectsixthParam){...}然后你可以这样调用方法:methodBuilder().firstParam("A").secondParam("B").sixthParam(newObject()).call();methodBuilder().firstParam("A").secondParam("B").thirdParam("C").fifthParam(2L).sixthParam("D").call();methodBuilder().firstParam("A").secondParam("B").fifthParam(3L).sixthParam(this).call();这样,提高了方法的可读性和灵活性。默认情况下,静态方法的构建器方法(获取构建器实例的方法)是静态方法。默认情况下,call()方法将抛出原始方法的异常。默认值在很多情况下,需要为方法的输入参数指定默认值,而Java不像其他一些语言,没有语义来支持这种需求。所以大多数情况下是通过方法重载来实现的,像这样:method(){method("Hello");}method(Stringa){method(a,"builder");}method(Stringa,Stringb){method(a,b,"world!");}method(Stringa,Stringb,Stringc){...acutallogichere...}当使用Lombok构建器时,它会在目标类中生成一个构建器类。此构建器类:具有与方法相同数量的属性和参数。带参数的set方法。类也可以手动定义,这样就可以为参数定义默认值。上面的方法也可以写成:@Builder(builderMethodName="methodBuilder",buildMethodName="call",builderClassName="MethodBuilder")method(Stringa,Stringb,Stringc){...这里的实际逻辑...}privateclassMethodBuilder{privateStringa="Hello";私人字符串b=“建设者”;privateStringc="world!";}有了这个加法,如果调用者没有指定参数,那么构建器类将使用中定义的默认值。注意:在这种情况下,我们不需要在类中声明方法的所有入参,Lombok会自动配置。对于泛型方法,我们有通过输入参数定义返回类型的需求,例如:publicTread(byte[]content,Classtype){...}在这种情况下,构建器类will是一个泛型类,但是builder方法将创建一个没有约束类型的实例。请看下面的例子:@Builder(builderMethodName="methodBuilder",buildMethodName="call",builderClassName="MethodBuilder")publicTread(byte[]content,Classtype){...}在这种情况下,methodBuilder方法将创建一个没有约束类型的MethodBuilder实例。结果,下面的代码不会被编译(入参定义为Class,传入Class):methodBuilder().content(newbyte[]{}).type(String.class).call();以上问题可以通过强制转换类型来解决:methodBuilder().content(newbyte[]{}).type((Class)String.class).call();这样就可以编译了。但是这样一来,调用方法后返回的类型就不是String,而是一个未知类型的泛型T。字符串结果=(String)methodBuilder().content(newbyte[]{}).type((Class)String.class).call();然后,我们需要再次转换输出结果。虽然我们的初衷是为调用者提供一种方便的方法,但建议考虑以下两种解决方案之一。重写Builder方法如上所述,问题的根源在于builder方法创建了构建器类的实例,但没有传入特定类型的参数。所以我们可以重载类中的builder方法,实例化一个指定类型的builder类:@Builder(builderMethodName="methodBuilder",buildMethodName="call",builderClassName="MethodBuilder")publicTread(finalbyte[]内容,finalClasstype){...}publicMethodBuildermethodBuilder(finalClasstype){returnnewMethodBuilder().类型(类型);}公共类MethodBuilder{privateClass类型;publicMethodBuildertype(Classtype){this.type=type;归还这个;}publicTcall(){returnread(content,type);}}这种情况下,调用者不需要进行强制类型转换,调用过程如下:Listresult=methodBuilder(List.class).content(newbyte[]{}).call();在setter方法中强制转换也可以在类型参数设置方法中强制builder实例类型:@Builder(builderMethodName="methodBuilder",buildMethodName="call",builderClassName="MethodBuilder")publicTread(finalbyte[]内容,finalClass{privateClass类型;publicMethodBuildertype(finalClasstype){this.type=(Class)type;返回(MethodBuilder)这个;}publicTcall(){returnread(content,type);}}使用此方法,无需手动定义构建器方法从调用者的角度来看,类型参数像其他任何参数一样直接传入。结论在方法上使用@Builder可以带来以下好处:增加调用者的灵活性在不写重载方法的前提下,可以定义参数的默认值提高方法调用的可读性可以传递相同的构建器实例像这样进行调用的警告是,在某些情况下,使用方法构建器会给提供者带来不必要的复杂性。各种方法构建器的demo请参考GitHub上的资料。译者介绍翟柯,社区编辑,目前在杭州从事软件研发工作。从事电子商务、征信等系统工作。他享受分享知识的过程,丰富自己的生活。原标题:MethodBuilderWithLombok@Builder,作者:DanielBuza