我正在嘗試爲我的班級使用生成器模式..如何在構建器模式中使用默認值(如果該值未通過並且使線程安全?
下面是我的Builder類,我按照Joshua Bloch版本構建,正如他在Effective Java,2nd Edition中所展示的。我們的客戶將主要通過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.
有什麼我不見了?而且我正在試圖讓這個類不可變和線程安全..這是一個線程安全和不可變的生成器或我已經錯過了一些東西?
更新: - 當人們將使用該
具體情形是,我們有一個工廠,客戶會使用,使我們的代碼的調用。我們有一個簡單的接口,我們的一個類正在實現它,然後我們有一個工廠,我們將通過該工廠調用該實現的某個方法,該方法接受此參數keys
。
因此,他們將使用下面的代碼在那裏的應用程序進行調用,它可能會在多線程環境中運行在那裏的應用程序。
InputKeys keys = new InputKeys.Builder(12000L, 33L).build();
IClient client = ClientFactory.getInstance();
client.getData(keys);
然後InputKeys Builder可以多次使用來構建的鑰匙,這不是一次。不管userId和clientId他們會得到他們將再次構建InputKeys。
謝謝。我應該從'InputKeys'類中移除它。正確?那麼不變性和線程安全呢?它看起來不錯嗎? – AKIWEB
我現在沒有理由在'InputKeys'類中擁有'500'。爲了不變性,我會使'InputKeys'變量'final'。這不是必要的,但它清楚地表明價值觀不應改變。如果您決定在'InputKeys'中實現getter,則返回'parameterMap'或'Collections.unmodifiableMap(parameterMap)'的副本,以防止修改地圖對象。至於線程安全性,我不知道在多線程中共享「Builder」的情況。 – rgettman
謝謝。不知何故,當我試圖實例化InputKeys類時,Collections.unmodifiableMap(parameterMap)給了我NPE,所以我刪除了它。此外,我也更新了我的問題。 – AKIWEB