Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在所有参数都是必需的情况下使用生成器模式?_Java_Design Patterns_Builder_Builder Pattern - Fatal编程技术网

Java 如何在所有参数都是必需的情况下使用生成器模式?

Java 如何在所有参数都是必需的情况下使用生成器模式?,java,design-patterns,builder,builder-pattern,Java,Design Patterns,Builder,Builder Pattern,我有一个构建器模式,在这个模式中,我的所有参数很可能都是必需的,因此我创建了一个长构造函数,如下代码所示 public final class ResponseHolder { // all below six are related to response information private final String response; private final boolean isLinking; private final TypeHold type

我有一个构建器模式,在这个模式中,我的所有参数很可能都是必需的,因此我创建了一个长构造函数,如下代码所示

public final class ResponseHolder {

    // all below six are related to response information
    private final String response;
    private final boolean isLinking;
    private final TypeHold typeOfId;
    private final long userTimeInMs;
    private final long userLmdInDays;
    private final String maskInfo;

    // below two are related to error handling
    private final ErrorCode error;
    private final StatusCode status;

    private ResponseHolder(Builder builder) {
        this.response = builder.response;
        this.isLinking = builder.isLinking;
        this.typeOfId = builder.typeOfId;
        this.userTimeInMs = builder.userTimeInMs;
        this.userLmdInDays = builder.userLmdInDays;
        this.maskInfo = builder.maskInfo;
        this.error = builder.error;
        this.status = builder.status;
    }

    public static class Builder {
        protected final String response;
        protected final TypeHold typeOfId;
        protected final String maskInfo;
        protected final ErrorCode error;
        protected final StatusCode status;
        protected final boolean isLinking;
        protected final long userTimeInMs;
        protected final long userLmdInDays;


        public Builder(String response, TypeHold typeOfId, String maskInfo, ErrorCode error,
                StatusCode status, boolean isLinking, long userTimeInMs, long userLmdInDays) {
            this.response = response;
            this.typeOfId = typeOfId;
            this.maskInfo = maskInfo;
            this.error = error;
            this.status = status;
            this.isLinking = isLinking;
            this.userTimeInMs = userTimeInMs;
            this.userLmdInDays = userLmdInDays
        }

        public ResponseHolder build() {
            return new ResponseHolder(this);
        }
    }

    // getters here
}
现在我很困惑,当所有的参数都是强制性的,那么它怎么会有用呢?有没有更好的方法来表示我上面的构建器模式?是否可以对传递到自己类中的参数进行逻辑分组,以减少传递给构建器构造函数的参数数量

虽然使用单独的对象简化了很多事情,但如果不熟悉代码,也会使事情变得有点难以理解。我可以做的一件事是将所有参数移动到它们自己的
addParam(param)
方法中,然后在运行时对
build()
方法中所需的参数执行验证


这里我应该遵循的最佳实践是什么?这里有没有更好的方法可以使用?

当有许多不同的有效参数排列允许您创建对象时,构建器模式会发光。如果没有构建器模式,您将被迫创建许多丑陋而混乱的构造函数来处理所有可能的有效参数组合

但在您的情况下,只有一组有效的参数允许您创建对象。这正是构造函数的用途。在这里使用构建器模式不仅是过分的,而且根本不合适


只需为您的
ResponseHolder
类使用一个普通构造函数。

构建器模式的目的是在构建目标对象之前拥有一个无参数构造函数、许多命名良好的setter方法和一个最终完成方法,该方法验证给定值的组合是否有效

在您的情况下,由于所有值都是必需的,因此构建器模式的主要目的是提供一种形式的命名参数支持

另外,您的目标对象应该有许多arg构造函数,而不是将builder对象作为参数)

因此,构建器应该是(假设不允许空值):

您现在可以这样使用它:

ResponseHolder holder = new ResponseHolder.Builder()
                        .setResponse(response)
                        .setTypeOfId(typeOfId)
                        .setMaskInfo(maskInfo)
                        .setError(error)
                        .setStatus(status)
                        .setIsLinking(isLinking)
                        .setUserTimeInMs(userTimeInMs)
                        .setUserLmdInDays(userLmdInDays)
                        .build();

有一个普通的构造器和一个大的响应线会看起来很难看吗?有没有其他方法可以进行分解?可能是在生成器模式中,也可能是在构造函数中,这样可以使分解变得简单?@david是的,请看我的答案。具有多个参数的构造函数不必看起来难看,这取决于您的代码格式。此时,我的建议是将第一个参数与构造函数放在同一行上,然后将其下的其余参数对齐。这既有助于提高可读性(因为您可以在每个部分之后进行注释),也有助于简化代码,因为您不必向类中添加额外的“构建器”逻辑/代码等。最终用户可以使用IDE的自动完成功能来帮助完成构造函数。)您昨天也提出了同样的问题,我不知道为什么还要再问一次。我甚至不会称之为构建器模式@Andreas的答案是建筑商通常的写作方式。David,如果我的答案不让你满意(指我回答的你之前的问题),你可以对我的答案发表评论,让我更新我的答案以更好地适应你的情况。但你没有对我的回答发表评论,你没有表现出任何关注,然后决定写一个新问题。不是很酷,我看到我们正在执行将在运行时发生的构建方法中的验证检查?我们能在编译时强制执行吗?@david,不,你不能。@Andreas我个人更喜欢从
build()
中提出的更具体的消息,但这可能是一个展示;-)@是的,我也是。这只是构建器模式的一个简单示例。
ResponseHolder holder = new ResponseHolder.Builder()
                        .setResponse(response)
                        .setTypeOfId(typeOfId)
                        .setMaskInfo(maskInfo)
                        .setError(error)
                        .setStatus(status)
                        .setIsLinking(isLinking)
                        .setUserTimeInMs(userTimeInMs)
                        .setUserLmdInDays(userLmdInDays)
                        .build();