小编典典

如何使用ModelInput类中的Joshua Bloch版本描述的Builder模式?

java

我试图在下面的类中使用Builder模式。最初,我使用类的构造函数来设置所有参数,但是偶然地我碰到了Builder模式,它对我的​​用例非常有用。

下面是我的课程,人们通常会通过userIdclientIdparameterMap总是,但其他字段是可选的,他们可能会或可能不会通过。而且,如果他们没有传递任何超时值,我需要将默认超时值始终设置为500,但是如果他们传递任何超时值,则它应该覆盖我的默认超时值。这里,Preference是一个具有四个字段的ENUM。

public final class ModelInput {

    private long userid;
    private long clientid;
    private long timeout = 500L;
    private Preference pref;
    private boolean debug;
    private Map<String, String> parameterMap;

    public ModelInput(long userid, long clientid, Preference pref, Map<String, String> parameterMap, long timeout, boolean debug) {
        this.userid = userid;
        this.clientid = clientid;
        this.pref = pref;
        this.parameterMap = parameterMap;
        this.timeout = timeout;
        this.debug = debug;
    }

 ... //getters here
}

下面是一个示例,我最初是如何ModelInput通过将参数传递给构造函数来构造对象的。最初,我传递所有参数,但客户端通常会传递userIdclientIdparameterMapalways和其他字段是可选的。

Map<String, String> paramMap = new HashMap<String, String>();
paramMap.put("attribute", "segmentation");

ModelInput input = new ModelInput(109739281L, 20L, Preference.SECONDARY, paramMap, 1000L, true);

我如何将上述代码转换为开始使用Builder模式,就像Bloch在Effective Java中所说的那样,它也是线程安全且不可变的?

以及如何使用Builder模式对此进行验证检查?人们可能会传递与客户端ID和超时相同的map以及与用户ID相同的零或负数。


阅读 196

收藏
2020-11-26

共1个答案

小编典典

Builder构造函数必须具有必需的参数。因此,在您的情况下,如果userId,clientId和parameterMap是强制性的,则我们将得到以下内容:

public final class ModelInput {

    private long userid;
    private long clientid;
    private long timeout = 500L;
    private Preference pref;
    private boolean debug;
    private Map<String, String> parameterMap;

    public ModelInput(Builder builder) {
        this.userid = builder.userId;
        this.clientid = builder.clientId;
        this.pref = builder.preference;
        this.parameterMap = builder.parameterMap;
        this.timeout = builder.timeout;
        this.debug = builder.debug;
    }

    public static class Builder {
        private long userId;
        private long clientId;
        private Preference preference;
        private boolean debug;
        private Map<String, String> parameterMap;

        public Builder(long userId, long clientId, Map<String, String> parameterMap) {
            this.userId = userId;
            this.clientId = clientId;
            this.parameterMap = parameterMap;
        }

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

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

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

        ...

        public ModelInput build() {
            return ModelInput(this);
        }
    }

    // ModelInput getters / setters
}

这是如何使用构建器类的方法:

String paramMap = new HashMap<String, String>();
paramMap.put("attribute", "segmentation");

ModelInput.Builder builder = new ModelInput.Builder(109739281L, 20L, paramMap);
builder.preference(Preference.SECONDARY).timeout(1000L).debug(true);

ModelInput modelInput = builder.build();

希望这可以帮助 :)

2020-11-26