我正在尝试为我的班级使用 Builder Pattern..
下面是我按照 Joshua Bloch 在 Effective Java, 2nd Edition 中展示的版本构建的 Builder 类。我们的客户通常会通过userId
,clientId
但其他字段是可选的,他们可能会通过也可能不会通过。这里的 Preference 是一个包含四个字段的 ENUM 类。
public final class InputKeys {
private long userid;
private long clientid;
private long timeout = 500L;
private Preference pref;
private boolean debug;
private Map<String, String> parameterMap;
private InputKeys(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 {
protected final long userId;
protected final long clientId;
protected long timeout;
protected Preference preference;
protected boolean debug;
protected Map<String, String> parameterMap;
public Builder(long userId, long clientId) {
this.userId = userId;
this.clientId = clientId;
}
public Builder parameterMap(Map<String, String> parameterMap) {
this.parameterMap = parameterMap;
return this;
}
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 InputKeys build() {
return new InputKeys(this);
}
}
}
下面是我的枚举类 -
public enum Preference {
PRIMARY,
SECONDARY
}
我正在拨打这样的电话来构造InputKeys
参数 -
InputKeys keys = new InputKeys.Builder(12000L, 33L).build();
System.out.println(keys);
我在这里看到的唯一问题是,如果客户没有传递任何超时值,我需要始终将默认超时值设置为 500,但如果他们传递任何超时值,那么它应该覆盖我的默认超时值。这对我不起作用,因为当我keys
在调试模式下看到我的时,它的超时值始终为 0。
有什么我想念的吗?而且我也试图使这个类不可变和线程安全。这是一个线程安全和不可变版本的 Builder 还是我错过了什么?
更新:-
人们将使用它的特定场景是我们有一个工厂,客户将使用它来调用我们的代码。我们有一个简单的接口,我们的一个类正在实现它,然后我们有一个工厂,我们将通过该工厂调用该实现的某个方法,该方法接受该keys
参数。
所以他们将在应用程序中使用下面的代码进行调用,并且他们可能会在多线程环境中运行应用程序。
InputKeys keys = new InputKeys.Builder(12000L, 33L).build();
IClient client = ClientFactory.getInstance();
client.getData(keys);
然后 InputKeys Builder 可以多次使用来构造键,不是一次。无论他们将获得什么 userId 和 clientId,他们都将再次构造 InputKeys。