首页 > 解决方案 > Java 使用具有公共字段的构建器

问题描述

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

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();
}

谢谢你的想法

标签: javajava-8builder

解决方案


(假设标准构建器符号: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")指巴拉克·奥巴马(Barack Obama)写的关于乔治·布什(George Bush)的书,还是反过来?确定这一点的唯一方法是读取 的参数名称tag,或读取源/javadocs,这些都可能不可用(您也可以反编译以更可靠地理解参数值,但最好避免这样做)。

将此与以下内容进行比较:

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

无论您打电话到哪里,您都可以只使用您的构建器就可以逃脱惩罚tag()


推荐阅读