【问题标题】:Java using builder with common fieldsJava 使用具有公共字段的构建器
【发布时间】:2019-08-22 08:44:14
【问题描述】:

我有一本带建设者的课本。我有以下这些方法,它们似乎相互包含。 我想知道有没有更方便的方法来使用这个构建器。我无法更改生成器。

public static void tag(String type, String name, String id, String title, String genre, String author) {
Book.builder()
        .type(type)
        .name(name)
        .status(STATUS)
        .addTag(ID, id)
        .addTag(TITLE, title)
        .addTag(GENRE, genre)
        .addTag(AUTHOR, author)
        .build();
 }

public static void tag(String type, String name, String id, String author) {
    Book.builder()
            .type(type)
            .name(name)
            .status(STATUS)
            .addTag(ID, id)
            .addTag(AUTHOR, author)
            .build();
}

public static void tag(String type, String name) {
    Book.builder()
            .type(type)
            .name(name)
            .status(STATUS)
            .build();
}

public static void tag(String type, String name, Details details) {
    Book.builder()
            .type(type)
            .name(name)
            .status(STATUS)
            .addTag(JOB_ID, details.getJobId())
            .addTag(PROVIDER, details.getProvider())
            .addTag(LOCALE, details.getLocale())
            .build();
}

public static void tag(String type, String name, Details details, String id, String title, String genre, String author) {
    Book.builder()
            .type(type)
            .name(name)
            .status(STATUS)
            .addTag(JOB_ID, details.getJobId())
            .addTag(PROVIDER, details.getProvider())
            .addTag(LOCALE, details.getLocale())
            .addTag(ID, id)
            .addTag(TITLE, title)
            .addTag(GENRE, genre)
            .addTag(AUTHOR, author)
            .build();
}

感谢您的想法

【问题讨论】:

  • 你想要实现上面代码没有的什么功能?

标签: java java-8 builder


【解决方案1】:

(假设标准构建器符号:https://dzone.com/articles/design-patterns-the-builder-pattern

目前,您的方法不返回任何内容。这意味着您创建对象并立即丢弃它们(例如,除非.build() 将它们持久化到某个数据库,但这是不寻常且不好的做法)。

另外,你重复了很多代码。虽然在与建筑商合作时这更可以原谅,但最好还是消除它。删除重复的一个好方法是让一些方法返回不完整的构建器,然后添加它们。例如:

public static BookBuilder tagBuilder(String type, String name, String id, String author) {
     return tagBuilder(type, name)
            .status(STATUS)
            .addTag(ID, id)
            .addTag(AUTHOR, author);
}

public static BookBuilder tagBuilder(String type, String name) {
    return Book.builder()
            .type(type)
            .name(name);
}

当你想创建这本书时,只需调用:

Book book = tagBuilder("hello", "world", "foo", "bar").build();

但是,我会问您为什么需要这些课程。为什么不在代码中使用构建器,否则会调用tag()。构建器比冗长、重载的方法更受青睐的主要原因之一是可读性。

例如,以下代码可读性不强——很难知道它的作用:

CustomType customObj = new CustomType("abc 123", 7, 4);

比较一下:

CustomType customObj = CustomTypeBuilder.builder()
   .setLicensePlate("abc, 123")
   .setAge(7)
   .setWheelCount(4)
   .build();

我没有更改类或对象的名称,但突然清楚这代表了车辆。

同样,tag("novel", "Barack Obama", "id123", "George Bush") 是指巴拉克奥巴马写的关于乔治布什的书,还是反过来?确定这一点的唯一方法是阅读tag 的参数名称,或者阅读源代码/javadocs,这些都可能不可用(您也可以反编译以更可靠地理解参数值,但最好避免这样做) .

比较一下:

Book book = BookBuilder.builder()
    .setTitle("Barack Obama")
    .setType("novel")
    .setId("id123")
    .setAuthor("George Bush")
    .build();

无论您打电话给tag(),您都可以只使用您的构建器。

【讨论】:

  • 换句话说,这些重载的静态工厂方法正在(重新)引入所有问题,构建器最初解决了。
  • 因为builder太长,我以为写在一个单独的类里会清理代码。
  • 你会发现,一个long builder方法,虽然在屏幕上占据了更多的空间,但是在未来的6个月内会更容易理解。如果长行是一个问题,您可以按照我在回答中的格式进行格式化,每个构建器调用都在一个新行上。在更基本的层面上,例如,如果您有 7 个要设置的属性,您将必须提供 7 个变量作为 something 的参数。我认为构建器虽然占用更多空间,但更有意义且不易出现拼写错误
猜你喜欢
  • 2013-08-27
  • 2018-03-16
  • 2012-04-28
  • 2020-12-04
  • 2013-08-10
  • 1970-01-01
  • 2014-09-09
  • 2010-11-04
  • 1970-01-01
相关资源
最近更新 更多