Design Patterns
Builder Pattern
Pros: increase usability and readability. Another advantage of the Builder approach is the ability to acquire an object in a single statement and state without the object in multiple states problem presented by using "set" methods. It is important in a multi-core world.
Cons: number of lines of code increases.
public final class Address
{
private final StreetAddress streetAddress;
private final City city;
private final State state;
//make the constructor of Address private will force people to use ClassBuilder
private Address(final StreetAddress newStreetAddress, final City newCity, final State newState)
{
this.streetAddress = newStreetAddress;
this.city = newCity;
this.state = newState;
}
public StreetAddress getStreetAddress()
{
return this.streetAddress;
}
public City getCity()
{
return this.city;
}
public State getState()
{
return this.state;
}
@Override
public String toString()
{
return this.streetAddress + ", " + this.city + ", " + this.state;
}
//this have to be public inner class to allow people to call it for building the class
public static class AddressBuilder
{
private StreetAddress nestedStreetAddress;
private final City nestedCity;
private final State nestedState;
public AddressBuilder(final City newCity, final State newState)
{
this.nestedCity = newCity;
this.nestedState = newState;
}
public AddressBuilder streetAddress(final StreetAddress newStreetAddress)
{
this.nestedStreetAddress = newStreetAddress;
return this;
}
public Address createAddress()
{
return new Address(nestedStreetAddress, nestedCity, nestedState);
}
}
}
new Address.AddressBuilder(
new City("Hazzard"), State.GA).createAddress())
Static Factory Constructor
One advantage of static factory methods is that, unlike constructors, they have names.
A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked.
String.valueOf(i);
RandomIntGenerator.between(10,20) instead of new RandomIntGenerator(10,20)
Singleton
//Notice the private inner static class that contains the instance of the singleton class.
//When the singleton class is loaded, SingletonHelper class is not loaded into memory
//and only when someone calls the getInstance method, this class gets loaded and creates the Singleton class instance.
//Calling getInstance() references the inner class, triggering the JVM to load & initialize it.
//This is thread-safe, since classloading uses locks.
//For subsequent calls, the JVM resolves our already-loaded inner class & returns the existing singleton. Thus — a cache.
//And thanks to the magic of JVM optimizations, a very very efficient one.
class SingletonInnerStatic {
private SingletonInnerStatic(){}
private static class SingletonHelper {
private static final SingletonInnerStatic INSTANCE = new SingletonInnerStatic();
}
public static SingletonInnerStatic getInstance(){
return SingletonHelper.INSTANCE;
}
}