建设者还是建设者?我们大声说出来

你好!我想推测一下对于简单对象使用生成器的明智性。



为了简单起见,我将使用批注lombok'a:



@Value

@Builder



经过一番谷歌搜索后,我们得到了该生成-将复杂对象的构造与其表示分离开来,以便通过相同的设计过程获得不同的视图。它仅适用于复杂对象吗?



让我们看一个简单的例子:



@Value
public class Info {
    @Nullable String uuid;
    @Nullable String email;
    @Nullable String phone;
}


很简单的一堂课。实际上,我们得到了一个通过构造函数初始化的不可变对象。



但是,正如我们所看到的,所有字段都是可为空的,并且创建这样的对象看起来不会很好:



        final Info info1 = new Info(null, "email@email.com", "79998888888");
        final Info info2 = new Info("3d107928-d225-11ea-87d0-0242ac130003", null, null);
        final Info info3 = new Info("3d107928-d225-11ea-87d0-0242ac130003 ", "email@email.com", null);
...


当然有选择:



  1. 具有几个不同类型字段的对象可以通过几个构造函数来传递。但这并不能解决上述类的问题。
  2. 使用设置器是主观的,它会使代码混乱。




那建设者呢?



@Value
@Builder
public class Info {
    @Nullable String uuid;
    @Nullable String email;
    @Nullable String phone;
}


我们得到了一个非常优雅的简单对象构造



        final Info info1 = Info.builder()
                .uuid("3d107928-d225-11ea-87d0-0242ac130003")
                .phone("79998888888")
                .build();
        final Info2 info2 = Info.builder()
                .email("email@email.com")
                .phone("79998888888")
                .build();
...
}


但是,要在项目中使用杰克逊必要补充我们的课程,以使其成功反序列化:



@Value
@Builder(builderClassName = "InfoBuilder")
@JsonDeserialize(builder = Info.InfoBuilder.class)
public class Info {
    @Nullable String uuid;
    @Nullable String email;
    @Nullable String phone;

    @JsonPOJOBuilder(withPrefix = "")
    public static class InfoBuilder {

    }
}


对于这两种方法,我们各有利弊:



builder:



+

1.代码变得更加简洁。

3.构造函数参数中的null不明显。

2.减少混淆相同类型参数的机会。

-1

.我们创建了一个额外的对象,整个GC都可以安全地删除该对象,但是您不要忘记它。

2.如有必要,请使用杰克逊-上课。



构造函数:



+

1.最小程度地堆满我们的课程,没有水。

2.没有不必要的对象创建。

-1

.通常,null会到达此类对象的构造函数。

2.当有人更改密码时,可能会出错。



结果



根据我的经验,我倾向于使用构建器。成本不高,但是输出是易于阅读的代码。



当然,编写测试以避免使用构造函数的第二个缺点。



PS:这是我的第一篇文章,对于建设性的批评和意见,我将不胜感激。



All Articles