Most of the implementations of Builder pattern I have seen are along these lines:
https://github.com/Design-pattrns/Builder-Pattern/blob/master/src/Computer.java
Basically the nested builder class needs to mirror all the attributes of the class that we need to build objects of and then provide methods to set the said attributes and an additional build() method inside the builder class.
When I tried to implement builder on my own, I came up with this (I use an instance of Person object inside builder instead of copying all the attributes of the Person class)
public class Person {
private String firstName;
private String lastName;
public static class PersonBuilder{
private Person person = new Person();
public PersonBuilder firstName(String firstName){
person.firstName = firstName;
return this;
}
public PersonBuilder lastName(String lastName){
person.lastName = lastName;
return this;
}
public Person build(){
return person;
}
}
}
Benefits:
1). No need to repeat the attributes of the class we want to instantiate
2). build method is simplified, just need to return the person object.
3). The Person class need not have a constructor which takes the Builder object as argument
4). More easily "updatable". If new attributes are added to person class, all we need to do is add the set method inside the builder class if needed. No need to create another attribute.
Cons:
1). The person object is eager initialised?
So are there any issues with this implementation?
I would say the example above is "simpler" but it has none of the advantages a builder offers and its probably better to just use the new keywords where you need the object and adding the properties to the constructor. Id say the drawbacks compared to the builder are as follows:
Its actually more of a configurator, I would not advise this pattern however you could pass the object to be configured into the constructor. In which case I would create two interfaces
Give the configurator IConfigurablePerson to its constructor, so it can access the setters then give other classes IPerson with only the getters. The advantage this offers is that it can work with multiple implementations of IConfigurablePerson without needing to know the class its working with (decoupling).