Alternate implementation of Builder Pattern. Anything wrong with this?

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:

  • it can only make a single instance
  • once the builder has "finished" it can continue to interact with the object as it still holds a reference to it.
  • its very tightly coupled to the product it is "building".
  • the fact that the person class has to expose a lot of properties as mutable for the builder, which you might want to not be mutable elsewhere in the code.

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

  • IConfigurablePerson which includes the setters
  • IPerson which includes the getters

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).