同事写了一个疯狂的类构造器,我要疯了,Builder 模式都不会么?! (2)

2)把 Bean 类所有参数复制到 XxxBuilder,然后在 XxxBuilder 新建必须参数的构造器,其他参数使用变量名作为方法然后返回自身(this)以便形成链式调用;

3)在 Bean 类里面新建一个接收 XxxBuilder 参数的私有构造器,避免使用 new 创建对象;

4)在 XxxBuilder 类新建一个 build 方法开始构建 Bean 类,也是作为链式调用的结束;

使用方法:

使用方式如下,先创建构造器,然后在每个方法后使用 . 带出所有方法,一目了然,最后调用 build 方法以结束链式调用创建 bean。

同事写了一个疯狂的类构造器,我要疯了,Builder 模式都不会么?!

参考代码如下:

/** * @author: 栈长 * @from: 公众号Java技术栈 */ private static void testBuilder() { Task task = new Task.TaskBuilder(99, "紧急任务") .type(1) .content("处理一下这个任务") .status(0) .finishDate(new Date()) .build(); System.out.println(task); }

结果输出:

Task{id=99,, content='处理一下这个任务', type=1, status=0, finishDate=...

Builder 模式的优点:

链式调用,优雅、清晰、一目了然;

一行代码完成对象创建,避免了多行代码赋值过程出错;

省去了大量冗余变量,避免变量复制出错;

Builder 模式的缺点:

需要冗余的 Builder 类,以及大量相等重复的成员变量,大大增加了代码量,维护难度相对较大;

只适合一次赋值创建对象,多次赋值的场景还需要新增 set 方法配合,不是很灵活;

Lombok 实现 Builder 模式

常规的 Builder 模式需要新增大量的代码,维护难度比较大,这里栈长再介绍一下 Lombok 中的 Builder 模式,一个 @Builder 注解搞定所有,轻松维护。

用 Lombok 改良后的代码如下:

/** * @author: 栈长 * @from: 公众号Java技术栈 */ @Builder public class LombokTask { private long id; private String name; private String content; private int type; private int status; private Date finishDate; }

我还能说什么?两个字:真香!

再来看下怎么使用:

/** * @author: 栈长 * @from: 公众号Java技术栈 */ private static void testLombokBuilder() { LombokTask lombokTask = new LombokTask.LombokTaskBuilder() .id(99) .name("紧急任务") .type(1) .content("处理一下这个任务") .status(0) .finishDate(new Date()) .build(); System.out.println(lombokTask); }

或者 new 都不要了,直接调用静态方法:

/** * @author: 栈长 * @from: 公众号Java技术栈 */ private static void testLombokBuilder2() { LombokTask lombokTask = LombokTask.builder() .id(99) .name("紧急任务") .type(1) .content("处理一下这个任务") .status(0) .finishDate(new Date()) .build(); System.out.println(lombokTask); }

接下来我们来看下这个 @Builder 注解到底做了什么:

public class LombokTask { private long id; private String name; private String content; private int type; private int status; private Date finishDate; LombokTask(final long id, final String name, final String content, final int type, final int status, final Date finishDate) { this.id = id; this.name = name; this.content = content; this.type = type; this.status = status; this.finishDate = finishDate; } public static LombokTask.LombokTaskBuilder builder() { return new LombokTask.LombokTaskBuilder(); } public static class LombokTaskBuilder { private long id; private String name; private String content; private int type; private int status; private Date finishDate; LombokTaskBuilder() { } public LombokTask.LombokTaskBuilder id(final long id) { this.id = id; return this; } public LombokTask.LombokTaskBuilder name(final String name) { this.name = name; return this; } public LombokTask.LombokTaskBuilder content(final String content) { this.content = content; return this; } public LombokTask.LombokTaskBuilder type(final int type) { this.type = type; return this; } public LombokTask.LombokTaskBuilder status(final int status) { this.status = status; return this; } public LombokTask.LombokTaskBuilder finishDate(final Date finishDate) { this.finishDate = finishDate; return this; } public LombokTask build() { return new LombokTask(this.id, this.name, this.content, this.type, this.status, this.finishDate); } public String toString() { return "LombokTask.LombokTaskBuilder(id=" + this.id + ",, content=" + this.content + ", type=" + this.type + ", status=" + this.status + ", finishDate=" + this.finishDate + ")"; } } }

这是反编译后的代码,可以看出来逻辑都是一样的。

Lombok 还可以添加各种类构造器、toString 等系列注解,几个注解完全可以达到想要的效果,但代码量和可维护性是天壤之别。

很多人不建议使用 Lombok,仁者见仁,智者见智,这里不再讨论,相关话题可以阅读我之前写的文章:

推荐一款代码神器,代码量至少省一半!

公司来了个新同事不会用 Lombok,还说我代码有问题!

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspxss.html