Builders are great: I've been putting them into some code recently because we're building an API but don't want to make breaking changes every time we need to modify a constructor. Backwards compatibility FTW.
I'll illustrate with a simple example.
Before builder:
With a PersonBuilder:
Now, if we want to add a nickname paramater to the person constructor, we add a corresponding withNickName(String nickname) on the builder and don't break anybody's existing code. (Saying that, of course we could achieve backwards compatibility with the telescoping pattern but that would be TOO GRIM FOR WORDS. )
I'll illustrate with a simple example.
Before builder:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Person { | |
private String name; | |
private int age; | |
public Person(String name, int age) { | |
this.name = name; | |
this.age =age; | |
} | |
/* | |
* Some random person stuff | |
*/ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Person { | |
/************************** PersonBuilder implementation **********************************/ | |
public static class PersonBuilder { | |
/* | |
* Think about whether or not you want to define defaults here | |
*/ | |
private String name ; | |
private int age; | |
/* | |
* Private constructor: people can call | |
* Person.builder() to return a PersonBuilder | |
*/ | |
private PersonBuilder() {} | |
public PersonBuilder withName(String name) { | |
this.name = name; | |
return this; | |
} | |
public PersonBuilder withAge(int age) { | |
this.age = age; | |
return this; | |
} | |
/* | |
* Person.builder().build() returns a new Person! | |
* Make sure you handle what happens if name and age are null | |
*/ | |
public Person build(){ | |
return new Person(this.name, this.age); | |
} | |
} | |
/******************************** Person implementation *******************************/ | |
/* | |
* Calling Person.builder() returns a PersonBuilder | |
*/ | |
public static PersonBuilder builder(){ | |
return new PersonBuilder(); | |
} | |
private String name; | |
private int age; | |
/* | |
* PRIVATE constructor so people are forced to use the builder | |
*/ | |
private Person(String name, int age) { | |
this.name = name; | |
this.age =age; | |
} | |
/* | |
* Some random person stuff | |
*/ | |
} |