I am trying to use Builder Pattern for my below class.. Initially I was using constructor of my class to set all the parameters but accidentally I came across Builder pattern an
try this
public final class ModelInput {
...
public static class Builder {
private long userid;
...
public Builder setUserId(long userId) {
this.userId = userId;
}
...
public ModelInput build() {
return new ModelInput(userId,...
}
}
}
I am not familiar with the book you are referencing, but I would suggest reading the post of wikipedia regarding the Builder pattern which is rather straight forward.
An implementation could be:
public final class ModelInput {
...
public static class Builder {
private long userid;
...
public Builder(long userid) {
this.userid = userid;
}
...
public ModelInput build() {
return new ModelInput(this);
}
}
private ModelInput(Builder builder){
this.userid = builder.userid;
this.clientid = builder.clientid;
this.pref = builder.pref;
this.parameterMap = builder.parameterMap;
this.timeout = builder.timeout;
this.debug = builder.debug;
}
...
}
Then when you want to initialize an object, you would call
ModelInput model = new ModelInput.Builder(...).build();
Regarding the validation process, it would be essentially the same as it would be made by checking the values (either in the constructor, or in the build
method).
Hope I helped!
Builder constructor must have the mandatory parameters. So, in your case, if userId, clientId and parameterMap are mandatory, we will have something like that:
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
}
And this is how to use your builder class:
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();
Hope this helps :)
To add to what the others have written:
In order to make your class immutable, you need to make parameterMap variable immutable as well. You can do that when the ModelInput class is instantiated:
private ModelInput(Builder builder){
this.userid = builder.userid;
this.clientid = builder.clientid;
this.pref = builder.pref;
this.parameterMap = Collections.unmodifiableMap(builder.parameterMap);
this.timeout = builder.timeout;
this.debug = builder.debug;
}
Notice the use of Collections.unmodifiablemap();
You'll also need to make your Preference instance immutable, or at least make it known that it is in fact not immutable.