Skip to content

Instantly share code, notes, and snippets.

@genderquery
Created February 12, 2017 00:03
Show Gist options
  • Save genderquery/d0572015485b0e8627312df9dc96437a to your computer and use it in GitHub Desktop.
Save genderquery/d0572015485b0e8627312df9dc96437a to your computer and use it in GitHub Desktop.
package com.example;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
class Usage {
void use() {
String name = "Avery";
Date dateOfBirth = new GregorianCalendar(1987, Calendar.SEPTEMBER, 24).getTime();
String gender = null;
final MutableBuilderInnerClassPerson mutableBuilderInnerClassPerson =
new MutableBuilderInnerClassPerson.Builder(name) // required
.dateOfBirth(dateOfBirth) // optional
.gender(gender) // optional
.build(); // required
final ImmutableBuilderInnerClassPerson immutableBuilderInnerClassPerson =
new ImmutableBuilderInnerClassPerson.Builder(name) // required
.dateOfBirth(dateOfBirth) // optional
.gender(gender) // optional
.build(); // required
final ImmutableMutationPerson immutableMutationPerson =
new ImmutableMutationPerson(name) // required
.withDateOfBirth(dateOfBirth) // optional
.withGender(gender); // optional
}
}
/**
* Pros: builder pattern is implemented in inner class
* mutations do not create a new object each time
* private empty constructor could aid (de)serialization
*
* Cons: fields are not completely immutable
*
*/
public final class MutableBuilderInnerClassPerson {
private String mName;
private Date mDateOfBirth;
private String mGender;
private MutableBuilderInnerClassPerson() {}
// name is required
public MutableBuilderInnerClassPerson(final String name) {
this(name, null, null);
}
public MutableBuilderInnerClassPerson(final String name, final Date dateOfBirth) {
this(name, dateOfBirth, null);
}
public MutableBuilderInnerClassPerson(final String name, final Date dateOfBirth,
final String gender) {
mName = name;
mDateOfBirth = dateOfBirth;
mGender = gender;
}
public String getName() {
return mName;
}
public Date getDateOfBirth() {
return mDateOfBirth;
}
public String getGender() {
return mGender;
}
public static class Builder {
private MutableBuilderInnerClassPerson mPerson;
// name is required
public Builder(String name) {
mPerson = new MutableBuilderInnerClassPerson(name);
}
public Builder dateOfBirth(Date dateOfBirth) {
mPerson.mDateOfBirth = dateOfBirth;
return this;
}
public Builder gender(String gender) {
mPerson.mGender = gender;
return this;
}
public MutableBuilderInnerClassPerson build() {
return mPerson;
}
}
}
/**
* Pros: fields are completely immutable
* builder pattern is implemented in inner class
* mutations do not create a new object each time
*
* Cons: fields are defined twice
* lack of private empty constructor could make (de)serialization difficult
*/
public final class ImmutableBuilderInnerClassPerson {
private final String mName;
private final Date mDateOfBirth;
private final String mGender;
// name is required
public ImmutableBuilderInnerClassPerson(final String name) {
this(name, null, null);
}
public ImmutableBuilderInnerClassPerson(final String name, final Date dateOfBirth) {
this(name, dateOfBirth, null);
}
public ImmutableBuilderInnerClassPerson(final String name, final Date dateOfBirth,
final String gender) {
mName = name;
mDateOfBirth = dateOfBirth;
mGender = gender;
}
public String getName() {
return mName;
}
public Date getDateOfBirth() {
return mDateOfBirth;
}
public String getGender() {
return mGender;
}
public static class Builder {
private String mName;
private Date mDateOfBirth;
private String mGender;
// name is required
public Builder(String name) {
mName = name;
}
public Builder dateOfBirth(Date dateOfBirth) {
mDateOfBirth = dateOfBirth;
return this;
}
public Builder gender(String gender) {
mGender = gender;
return this;
}
public ImmutableBuilderInnerClassPerson build() {
return new ImmutableBuilderInnerClassPerson(mName, mDateOfBirth, mGender);
}
}
}
/**
* Pros: fields are completely immutable
* fields are only defined once
*
* Cons: each mutation creates a new object
* lack of private empty constructor could make (de)serialization difficult
* builder pattern is intermixed with class
*/
public final class ImmutableMutationPerson {
private final String mName;
private final Date mDateOfBirth;
private final String mGender;
// name is required
public ImmutableMutationPerson(final String name) {
this(name, null, null);
}
public ImmutableMutationPerson(final String name, final Date dateOfBirth) {
this(name, dateOfBirth, null);
}
public ImmutableMutationPerson(final String name, final Date dateOfBirth,
final String gender) {
mName = name;
mDateOfBirth = dateOfBirth;
mGender = gender;
}
public ImmutableMutationPerson withDateOfBirth(final Date dateOfBirth) {
return new ImmutableMutationPerson(mName, dateOfBirth, mGender);
}
public ImmutableMutationPerson withGender(final String gender) {
return new ImmutableMutationPerson(mName, mDateOfBirth, gender);
}
public String getName() {
return mName;
}
public Date getDateOfBirth() {
return mDateOfBirth;
}
public String getGender() {
return mGender;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment