Как использовать значение по умолчанию в шаблоне компоновщика, если это значение не передается, а также сделать потокобезопасным?
Я пытаюсь использовать шаблон Builder для своего класса..
Ниже приведен мой класс Builder, который я построил, следуя версии Джошуа Блоха, как он показал в Effective Java, 2nd Edition. Наш клиент в основном пройдетuserId
, clientId
всегда, но другие поля являются необязательными, и они могут передавать или не передавать его. Здесь предпочтение-это класс 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 можно использовать несколько раз, чтобы построить ключи, это не один раз. Независимо от идентификатора пользователя и идентификатора ClientID они будут получать, они будут снова строить InputKeys.
2 ответа:
Просто инициализируйте тайм-аут до 500 в
Builder
. Методtimeout
перезапишет это значение, если его вызвать.protected long timeout = 500L;
Вы можете инициализировать значение таймаута в конструкторе
Builder
(или при объявлении переменной), напримерpublic Builder(long userId, long clientId) { this.userId = userId; this.clientId = clientId; this.timeout = 500L; }
Таким образом, если вы не вызываете метод
timeout()
, он будет иметь значение по умолчанию, в противном случае он будет установлен на значение, переданное черезtimeout()
.Что касается потокобезопасности, если конструктор
Builder
используется только для создания нового объектаInputKeys
(как в сценарии, описанном в вопросе), без какой-либо другой области кода, имеющей доступ к этому объектуInputKeys
, не существует нужно применить какую-то дополнительную защиту.