如何检查Builder模式类中的无效输入?

时间:2014-01-11 08:56:12

标签: java builder builder-pattern

以下是我的构建器类,其中两个字段是必填字段userIdclientId

public final class InputKeys {

    private final long userId;
    private final int clientId;
    private final long timeout;
    private final Preference preferences;
    private final boolean debugFlag;
    private final Map<String, String> attributeMap;

    private InputKeys(Builder builder) {
    this.userId = builder.userId;
    this.clientId = builder.clientId;
    this.preferences = builder.preference;
    this.attributeMap = builder.attributeMap;
    this.timeout = builder.timeout;
    this.debugFlag = builder.debugFlag;
    }

    public static class Builder {
    protected final long userId;
    protected final int clientId;
    protected long timeout = 500L;
    protected Preference preference;
    protected boolean debugFlag;
    protected Map<String, String> attributeMap;


    public Builder(long userId, int clientId) {
        this.userId = userId;
        this.clientId = clientId;
    }

    public Builder attributeMap(Map<String, String> attributeMap) {
        this.attributeMap = attributeMap;
        return this;
    }

    public Builder preference(Preference preference) {
        this.preference = preference;
        return this;
    }

    public Builder debugFlag(boolean debugFlag) {
        this.debugFlag = debugFlag;
        return this;
    }

    public Builder timeout(long timeout) {
        this.timeout = timeout;
        return this;
    }

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

    //getters  here
}

现在我将这样调用这个构建器类 -

InputKeys keys = new InputKeys.Builder(12000L, 33L).build();

但是有些人可能会传递错误的输入值,例如他们传递负的userId和负的clientId,负的超时值或空的attributeMap。如何在我的构建器类中处理这种情况?

如果我对if else if block中的每个变量进行IllegalArgumentcheck,那么我的整个Builder类会被IllegalArgumentException检查淹没?

有没有更好的方法呢?

3 个答案:

答案 0 :(得分:1)

制作具有共同逻辑的方法,例如

private void assertNonNegative(long val, String attr) {
    if (val < 0) {
         throw IllegalArgumentException(attr + " cannot be negative");
    }
}

答案 1 :(得分:0)

我建议将所有检查移至构建方法。这种方法没有错。

此外,如果指定字段 a ,则实施类似&#34的约束是典型情况,则字段 b 是强制性的&#34;在构建方法中。

答案 2 :(得分:0)

您需要的是更强大的声明方式来验证参数输入,以避免一次又一次地重复验证代码。

我建议使用java annotations来表示变量应该属于特定范围的值。

如果您使用Java EE或类似Spring的框架,您可以使用java注释并让框架执行值检查。有关使用Java EE进行验证,请参阅thisthis

举例验证Name类的属性:

public class Name {
    @NotNull
    @Size(min=1, max=16)
    private String firstname;

    @NotNull 
    @Size(min=1, max=16)
    private String lastname;
}

java EE将处理所有验证。

希望我帮忙!