I recently started using the builder pattern in one of my projects:
public final class DataKey {
private final long userId;
private final String uuid;
private final String deviceId;
private final int clientId;
private final long timeout;
private final FlowEnum flow;
private DataKey(Builder builder) {
this.userId = builder.userId;
this.uuid = builder.uuid;
this.deviceId = builder.deviceId;
this.clientId = builder.clientId;
this.timeout = builder.timeout;
if (userId == 0 && uuid != null && uuid.isEmpty() && deviceId != null
&& deviceId.isEmpty()) {
throw new IllegalStateException("You have to pass at least one"
+ " of the following: userId, uuid or deviceId");
}
if (userId != 0) {
this.flow = FlowEnum.USERFLOW;
}
else {
this.flow = FlowEnum.DEVICEFLOW;
}
}
public static class Builder {
protected long userId;
protected String uuid;
protected String deviceId;
protected final int clientId;
protected long timeout = 200L;
public Builder(int clientId) {
this.clientId = clientId;
}
public Builder setUserId(long userId) {
this.userId = userId;
return this;
}
public Builder setUuid(String uuid) {
this.uuid = uuid;
return this;
}
public Builder setDeviceId(String deviceId) {
this.deviceId = deviceId;
return this;
}
public DataKey build() {
return new DataKey(this);
}
}
public long getUserId() {
return userId;
}
public String getUuid() {
return uuid;
}
public String getdeviceId() {
return deviceId;
}
public FlowEnum getFlow() {
return flow;
}
public int getclientId() {
return clientId;
}
public long getTimeout() {
return timeout;
}
}
I also have an enum
which determines whether userId
or uuid
/deviceId
is being used. If userId
is present, then the flow type is USERFLOW
, otherwise it's DEVICEFLOW
.
public enum FlowEnum {
USERFLOW, DEVICEFLOW
}
While making keys using the Builder
class, I will always pass clientId
will pass at least one ID key from these - userId
, uuid
and deviceId
. If by any chance, all the ID keys are missing, then I need to throw an illegal state exception.
I need to prioritize the IDs as well if we are passing multiple IDs instead of one then userId
takes the priority first, then uuid
and then deviceId
.
Can a validation check be done in the build()
method? Also, is it thread-safe?
DataKey keys = new DataKey.Builder(100).setUserId(1234L).setUuid("aaaa").setDeviceId("sssss").addTimeout(100L).build();
System.out.println(keys.getFlow());
final
fields outside of the initializer/constructor. Does this compile? \$\endgroup\$