Minborg

Minborg
Minborg
Showing posts with label Builder Pattern. Show all posts
Showing posts with label Builder Pattern. Show all posts

Thursday, December 1, 2016

Day 2, Java Holiday Calendar 2016, Composition

2. Favor Composition Over Inheritance



Today's tips is to avoid inheritance. For good reasons, there can only be one super class for any given Java class. Furthermore, exposing abstract or base classes in your API that are supposed to be inherited by client code is a very big and problematic API commitment. Avoid API inheritance altogether, and instead consider providing static interface methods that take one or several lambda parameters and apply those given lambdas to a default internal API implementation class.

This also creates a much clearer separation of concerns. For example, instead of inheriting from a public API class AbstractReader and overriding abstract void handleError(IOException ioe), it is better to expose a static method or a builder in the Reader interface that takes a Consumer<IOException> and applies it to an internal generic ReaderImpl.

Do This:

Reader reader = Reader.builder()
    .withErrorHandler(IOException::printStackTrace)
    .build();

Don't Do This:

Reader reader = new AbstractReader() {

    @Override
    public void handleError(IOException ioe) {
        ioe.printStackTrace();
    }
};

Read more in the original article at https://dzone.com/articles/the-java-8-api-design-principles

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Saturday, March 5, 2016

Java 8: A Type Safe Map Builder Using Alternating Interface Exposure

Expose Your Classes Dynamically

Duke and Spire exposing another look... 
When I was a Java newbie, I remember thinking that there should be a way of removing or hiding methods in my classes that I did not want to expose. Like overriding a public method with a private or something like that (which of corse cannot and should not be possible). Obviously today, we all know  that we could achieve the same goal by exposing an interface instead.

By using a scheme named Alternating Interface Exposure, we could view a class' methods dynamically and type safe, so that the same class can enforce a pattern in which it is supposed to to be used.

Let me take an example. Let's say we have a Map builder that can be called by successively adding keys and values before the actual Map can be built. The Alternating Interface Exposure scheme allows us to ensure that we call the key() method and the value() exactly the same number of times and that the build() method is only callable (and seen, for example in the IDE) when there are just as many keys as there are values.

The Alternating Interface Exposure scheme is used in the open-source project Speedment that I am contributing to. In Speedment, the scheme is for example used when building type-safe Tuples that subsequently will be built after adding elements to a TupleBuilder. This way, we can get a typed Tuple2<String, Integer> = {"Meaning of Life", 42}, if we write TupleBuilder.builder().add("Meaning of Life).add(42).build().

Using a Dynamic Map Builder

I have written about the Builder Pattern several times in some of my previous posts (e.g. here) and I encourage you to revisit an article on this issue, should you not be familiar with the concept, before reading on.

The task at hand is to produce a Map builder that dynamically exposes a number of implementing methods using a number of context dependent interfaces. Furthermore, the builder shall "learn" its key/value types the first time they are used and then enforce the same type of keys and values for the remaining entries.

Here is an example of how we could use the builder in our code once it is developed:
    public static void main(String[] args) {

        // Use the type safe builder
        Map<Integer, String> map = Maps.builder()
                .key(1)                 // The key type is decided here for all following keys
                .value("One")           // The value type is decided here for all following values
                .key(2)                 // Must be the same or extend the first key type
                .value("Two")           // Must be the same type or extend the first value type
                .key(10).value("Zehn'") // And so on...
                .build();               // Creates the map!

        // Create an empty map
        Map<String, Integer> map2 = Maps.builder()
                .build();
        
        
    }

}

In the code above, once we start using an Integer using the call key(1), the builder only accepts additional keys that are instances of Integer. The same is true for the values. Once we call value("one"), only objects that are instances of String can be used. If we try to write value(42) instead of value("two") for example, we would immediately see the error in our IDE. Also, most IDE:s would automatically be able to select good candidates when we use code completion.

Let me elaborate on the meaning of this:

Initial Usage

The builder is created using the method Maps.builder() and the initial view returned allows us to call:
  1. build() that builds an empty Map (like in the second "empty map" example above)
  2. key(K key) that adds a key to the builder and decides the type (=K) for all subsequent keys (like key(1) above)

Once the initial key(K key) is called, another view of the builder appears exposing only:
  1. value(V value) that adds a value to the builder and decides the type (=V) for all subsequent values (like value("one"))

Note that the build() method is not exposed in this state, because the number of keys and values differ. Writing Map.builder().key(1).build(); is simply illegal, because there is no value associated with key 1.

Subsequent Usage

Now that the key and value types are decided, the builder would just alternate between two alternating interfaces being exposed depending on if key() or value() is being called. If key() is called, we expose value() and if value() is called, we expose both key() and build().

The Builder

Here are the two alternating interfaces that the builder is using once the types are decided upon:
public interface KeyBuilder<K, V> {

        ValueBuilder<K, V> key(K k);
        
        Map<K, V> build();
    
}

public interface ValueBuilder<K, V> {

    KeyBuilder<K, V> value(V v);

}

Note how one interface is returning the other, thereby creating an indefinite flow of alternating interfaces being exposed. Here is the actual builder that make use of the alternating interfaces:
public class Maps<K, V> implements KeyBuilder<K, V>, ValueBuilder<K, V> {

    private final List<Entry<K, V>> entries;
    private K lastKey;

    public Maps() {
        this.entries = new ArrayList<>();
    }

    @Override
    public ValueBuilder<K, V> key(K k) {
        lastKey = k;
        return (ValueBuilder<K, V>) this;
    }

    @Override
    public KeyBuilder<K, V> value(V v) {
        entries.add(new AbstractMap.SimpleEntry<>(lastKey, v));
        return (KeyBuilder<K, V>) this;
    }

    @Override
    public Map<K, V> build() {
        return entries.stream()
                .collect(toMap(Entry::getKey, Entry::getValue));
    }

    public static InitialKeyBuilder builder() {
        return new InitialKeyBuilder();
    }

}

We see that the implementing class implements both of the alternating interfaces but only return one of them depending on if key() or value() is called. I have "cheated" a bit by created two initial help classes that take care about the initial phase where the key and value types are not yet decided. For the sake of completeness, the two "cheat" classes are also shown hereunder:
public class InitialKeyBuilder {

    public <K> InitialValueBuilder<K> key(K k) {
        return new InitialValueBuilder<>(k);
    }
    
    public <K, V> Map<K, V> build() {
        return new HashMap<>();
    }

}

public class InitialValueBuilder<K> {
    
    private final K k;

    public InitialValueBuilder(K k) {
        this.k = k;
    }
    
    public <V> KeyBuilder<K, V> value(V v) {
        return new Maps<K, V>().key(k).value(v);
    }

}

These latter classes work in a similar fashion as the main builder in the way that the InitialKeyBuilder returns a InitialValueBuilder that in turn, creates a typed builder that would be used indefinitely by alternately returning either a KeyBuilder or a ValueBuilder.

Conclusions

The Alternating Interface Exposure scheme is useful when you want a type safe and context aware model of your classes. You can develop and enforce a number of rules for your classes using this scheme. These classes will be much more intuitive to use, since the context sensitive model and its types propagate all the way out to the IDE. The schema also gives more robust code, because potential errors are seen very early in the design phase. We will see potential errors as we are coding and not as failed tests or application errors.

Wednesday, December 10, 2014

Java 8, Initializing Maps in the Smartest Way

Background

Create maps
Illustration: Elis Minborg
When I was a kid, I was taught that, in the Swedish language, one should write out numbers using their text representation in the range from zero to twelve, otherwise one should use their number representation. For example, one should write "There are two birds and 21 flowers" (but in Swedish then of course).

In Java, we are likely to use Maps to perform such translations. The question in this post is: How does one initialize Maps in the best way? What are the alternatives and what are their pros and cons?


Objective

The objective in this post is to write a method that returns a Map with a translation from an Integer to a String. The Map shall be Unmodifiable, because we might want to reuse the Map in several places in our code and we want to be sure that is has not been tampered with. The Map shall contain the mapping pairs (or Entries as they are called in Java): 0->"zero", 1->"one", 2->"two", ... , 12->"twelve".

The Imperative Way

The straight forward solution is to declare a Map and then just put() entries into the Map. After that is done, we return an Unmodifiable view of the newly created map like this:
protected static Map<Integer, String> imperative() {
        final Map<Integer, String> numMap = new HashMap<>();
        numMap.put(0, "zero");
        numMap.put(1, "one");
        numMap.put(2, "two");
        numMap.put(3, "three");
        numMap.put(4, "four");
        numMap.put(5, "five");
        numMap.put(6, "six");
        numMap.put(7, "seven");
        numMap.put(8, "eight");
        numMap.put(9, "nine");
        numMap.put(10, "ten");
        numMap.put(11, "eleven");
        numMap.put(12, "twelve");
        return Collections.unmodifiableMap(numMap);
    }
In this solution, as opposed to the other solutions that are shown later in this post, we have to declare an intermediate result variable (numMap). We then have to reference this result variable over and over again for each put() operation , which is disturbing. There is a risk that this result variable can "leak", effectively rendering the Unmodifiable map modifiable, because the Collections.unmodifiableMap() method just provides a view of the provided Map. So if we retain a reference to the provided Map, we can still change it.

Double Brace Initialization

The Double Brace Initialization Idiom firsts appears as very appealing. In the beginning, I liked it and started to use it frequently in my code. This is how it works:
    @SuppressWarnings("serial")
    protected static Map<Integer, String> doubleBracket() {

        return Collections.unmodifiableMap(new HashMap<Integer, String>() {
            {
                put(0, "zero");
                put(1, "one");
                put(2, "two");
                put(3, "three");
                put(4, "four");
                put(5, "five");
                put(6, "six");
                put(7, "seven");
                put(8, "eight");
                put(9, "nine");
                put(10, "ten");
                put(11, "eleven");
                put(12, "twelve");
            }
        });
    }
There is actually no magic with it at all. The first pair of braces will create an anonymous class and the second pair of braces will create an instance initializer block that is run when the anonymous inner class is instantiated. In any class, you can have such brackets containing code that will be run when your create instances of your class (or when the class is used the first time, if you precede the brackets with the keyword static). This looks much better because now you do not have to create an intermediate result and you do not have to reference a variable each time you call put().

However, there are a number of snags with this scheme that is not immediately apparent. As previously stated, when you declare a class with double braces, an anonymous class will be created. Because the anonymous class is not static, it will also hold a reference (this$0) to its containing class (if defined within another class, which is the most normal case). This means that the containing instance (this$0) can not be garbage-collected as long as your Map is alive. A big concern according to my view.

Another disadvantage is that you must provide the types of the Map explicitly, because the compiler is not able to infer the types using the diamond (<>) operator. Also, the new anonymous class does not define a serialVersionUID variable, so we must suppress the resulting warning using the @SuppressWarnings("serial") annotation if you want it to compile nicely. You should really think twice before you use the Double Brace Idiom.

The Builder Pattern

This is one of my favorites and you can read more about this pattern in my previous posts "Creating Objects Using The Builder Pattern" and "The Interface Builder Pattern". The idea here is to create a Builder that has methods that returns the Builder itself again and again (like the StringBuilder does). This way the Builder can be called several time until the final build() method is called and the result is returned. I have created builders that can be used to create instance of Map and ConcurrentMap and placed them in a utility class called Maps:
public class Maps {

    private Maps() {
    }

    public static <K, V> MapBuilder<K, V> builder() {
        return builder(HashMap::new);
    }

    public static <K, V> MapBuilder<K, V> builder(Supplier<Map<K, V>> mapSupplier) {
        return new MapBuilder<>(mapSupplier.get());
    }

    public static <K, V> ConcurrentMapBuilder<K, V> concurrentBuilder() {
        return concurrentBuilder(ConcurrentHashMap::new);
    }

    public static <K, V> ConcurrentMapBuilder<K, V> concurrentBuilder(Supplier<ConcurrentMap<K, V>> mapSupplier) {
        return new ConcurrentMapBuilder<>(mapSupplier.get());
    }

    private static class BaseBuilder<M extends Map<K, V>, K, V> {

        protected final M map;

        public BaseBuilder(M map) {
            this.map = map;
        }

        public BaseBuilder<M, K, V> put(K key, V value) {
            map.put(key, value);
            return this;
        }

        public M build() {
            return map;
        }

    }

    public static class MapBuilder<K, V> extends BaseBuilder<Map<K, V>, K, V> {

        private boolean unmodifiable;

        public MapBuilder(Map<K, V> map) {
            super(map);
        }

        @Override
        public MapBuilder<K, V> put(K key, V value) {
            super.put(key, value);
            return this;
        }

        public MapBuilder<K, V> unmodifiable(boolean unmodifiable) {
            this.unmodifiable = unmodifiable;
            return this;
        }

        @Override
        public Map<K, V> build() {
            if (unmodifiable) {
                return Collections.unmodifiableMap(super.build());
            } else {
                return super.build();
            }
        }

    }

    public static class ConcurrentMapBuilder<K, V> extends BaseBuilder<ConcurrentMap<K, V>, K, V> {

        public ConcurrentMapBuilder(ConcurrentMap<K, V> map) {
            super(map);
        }

        @Override
        public ConcurrentMapBuilder<K, V> put(K key, V value) {
            super.put(key, value);
            return this;
        }

    }

}
For the sake of completeness, I have also included methods to create concurrent maps and also two builder()  methods that takes a map Provider, allowing any type of Map to be created using the Builder. Using the support methods, we can now create maps easily like this:

    protected static Map<Integer, String> builderPattern() {
        return Maps.<Integer, String>builder().
                put(0, "zero").
                put(1, "one").
                put(2, "two").
                put(3, "three").
                put(4, "four").
                put(5, "five").
                put(6, "six").
                put(7, "seven").
                put(8, "eight").
                put(9, "nine").
                put(10, "ten").
                put(11, "eleven").
                put(12, "twelve").
                unmodifiable(true).
                build();
    }

Although we must enter the generic types of the Map (i.e. <Integer, String>) it looks much better. We can avoid all the other disadvantages that the Double Brace Idiom had. Note the Builder method unmodifiable() that sets a flag, controlling if the build() method shall return a normal Map or an unmodifiable Map. Very convenient! Another advantage is that this pattern works with older Java versions and that no extra objects are created during map creation.

The Java 8 Way

Java 8 has a number of features that can be used to create and initialize maps. Take a look at this method:      

    protected static Map<Integer, String> stdJava8() {

        return Collections.unmodifiableMap(Stream.of(
                new SimpleEntry<>(0, "zero"),
                new SimpleEntry<>(1, "one"),
                new SimpleEntry<>(2, "two"),
                new SimpleEntry<>(3, "three"),
                new SimpleEntry<>(4, "four"),
                new SimpleEntry<>(5, "five"),
                new SimpleEntry<>(6, "six"),
                new SimpleEntry<>(7, "seven"),
                new SimpleEntry<>(8, "eight"),
                new SimpleEntry<>(9, "nine"),
                new SimpleEntry<>(10, "ten"),
                new SimpleEntry<>(11, "eleven"),
                new SimpleEntry<>(12, "twelve"))
                .collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())));
    }

Here we create a Stream of map entries. At least two implementations of Entry already exists in the standard Java libraries and here I have used SimpleEntry. After the Stream is constructed, we collect all the entries and creates a Map by splitting up each Entry in a key and a value. It is important to include the diamond operator for each SimpleEntry or else the toMap() method will not be able to infer the types of the Entry.

As can be seen, many intermediate objects need to be created before the final Map can be constructed. This can be a disadvantage if many instances are created rapidly. One advantage with this method is that it is using a standard Java 8 stream pattern, so it is very easy to start out with this pattern and then modify it to do something else.

The Java 8 Way Simplified  

We can further simplify the process of creating maps the Java 8 way, by adding a small number of support methods to our Maps class like this:      

    public static <K, V> Map.Entry<K, V> entry(K key, V value) {
        return new AbstractMap.SimpleEntry<>(key, value);
    }

    public static <K, U> Collector<Map.Entry<K, U>, ?, Map<K, U>> entriesToMap() {
        return Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue());
    }

    public static <K, U> Collector<Map.Entry<K, U>, ?, ConcurrentMap<K, U>> entriesToConcurrentMap() {
        return Collectors.toConcurrentMap((e) -> e.getKey(), (e) -> e.getValue());
    }



 Now we can create the desired Map using this method:  

    protected static Map<Integer, String> extJava8() {
        return Collections.unmodifiableMap(Stream.of(
                entry(0, "zero"),
                entry(1, "one"),
                entry(2, "two"),
                entry(3, "three"),
                entry(4, "four"),
                entry(5, "five"),
                entry(6, "six"),
                entry(7, "seven"),
                entry(8, "eight"),
                entry(9, "nine"),
                entry(10, "ten"),
                entry(11, "eleven"),
                entry(12, "twelve")).
                collect(entriesToMap()));
    }

Do not forget to import the support methods statically. Now, this looks much nicer than the previous attempt because is is much shorter and does not contain so much boiler plate code.

Conclusion

There are many ways to create and initialize a Map. The choice is really up to you. Personally, I like the Builder Pattern best because it is very efficient, flexible and straight forward to use. The Java 8 pattern is also nice. A final warning on using the Double Brace Idiom should also be made.

How do we do the actual translation of text using the Map we have created using any of the various methods in this post? One nice way of doing it is to use Java 8's Map method getOrDefault() like this:

     public static String toText(Map<Integer, String> map, int val) {
         return map.getOrDefault(val, Integer.toString(val));
     }
    
     final Map<Integer, String> map = imperative();
     System.out.println("There are " + toText(map, 2) + " birds and " + toText(map, 21) + " flowers.");


   "There are two birds and 21 flowers."

UPDATE: Learn how you can implement a type safe dynamic Map builder in this newer post.

Sunday, September 14, 2014

The Interface Builder Pattern, a Follow-up Post on the Builder Pattern

Background

In my previous post, I talked about creating objects using the Builder Pattern. I recommend that you read that article first, unless you are already familiar with the Builder Pattern.

The Interface Builder Pattern

At the end of that post, I pointed out some areas of improvement and after experimenting a bit, I want to share a variant of the Builder Pattern with several advantages over the previously presented solutions that I call the Interface Builder Pattern. In the previous post, we had a Car that was built using the Builder Pattern where the Car was a concrete class. Now, if we instead let Car be an interface (or for that matter an abstract class) we can gain some important benefits:
  1. The Car.Builder can select between many different implementations of Cars depending on what  is appropriate at build() time.
  2. We can have one or several internal base classes implementing Cars that we can extend, both for the Builder itself and different implementations of Cars
  3. We can have cached Cars that we can provide instantly at build() time.
This adds a lot of flexibility to your Builder as can be seen in this example:

public interface Car {

    String getBrand();

    String getType();

    int getPower();

    int getTorque();

    int getGears();

    String getColor();

    static class Hidden {

        protected static class DefaultCar implements Car {

            // Required parameters
            private final String brand;
            private final String type;

            // Optional parameters
            protected int power;
            protected int torque;
            protected int gears;
            protected String color;

            private DefaultCar(String brand, String type) {
                this.brand = brand;
                this.type = type;
            }

            protected DefaultCar(Builder builder) {
                this(builder.getBrand(), builder.getType());
                this.power = builder.power;
                this.torque = builder.torque;
                this.gears = builder.gears;
                this.color = builder.color;
            }

            @Override
            public String getBrand() {
                return brand;
            }

            @Override
            public String getType() {
                return type;
            }

            @Override
            public int getPower() {
                return power;
            }

            @Override
            public int getTorque() {
                return torque;
            }

            @Override
            public int getGears() {
                return gears;
            }

            @Override
            public String getColor() {
                return color;
            }

        }

        private static class ToyotaAvensisCarImpl implements Car {

            private final String color;

            public ToyotaAvensisCarImpl(String color) {
                this.color = color;
            }

            @Override
            public String getBrand() {
                return "Toyota";
            }

            @Override
            public String getType() {
                return "Avensis";
            }

            @Override
            public int getPower() {
                return 108;
            }

            @Override
            public int getTorque() {
                return 180;
            }

            @Override
            public int getGears() {
                return 6;
            }

            @Override
            public String getColor() {
                return color;
            }

        }

        private static Car TOYOTA_AVENSIS_WHITE = new Hidden.ToyotaAvensisCarImpl("White");

    }

    public static class Builder extends Hidden.DefaultCar {

        public Builder(String brand, String type) {
            super(brand, type);
        }

        public Builder power(int power) {
            this.power = power;
            return this;
        }

        public Builder torque(int torque) {
            this.torque = torque;
            return this;
        }

        public Builder gears(int gears) {
            this.gears = gears;
            return this;
        }

        public Builder color(String color) {
            this.color = color;
            return this;
        }

        public Car build() {
            if ("toyota".equalsIgnoreCase(getBrand()) && "Avensis".equalsIgnoreCase(getType())) {
                if ("White".equals(getColor())) {
                    return Hidden.TOYOTA_AVENSIS_WHITE;
                } else {
                    return new Hidden.ToyotaAvensisCarImpl(getColor());
                }
            } else {
                return new Hidden.DefaultCar(this);
            }
        }

    }

}

Advantages

First, we define our Car interface with the getters that it shall provide and expose. All the Cars that we Build shall implement this interface but we are free to choose the implementation! This is a major advantage. We may, as shown above, create static pre-built Cars (like TOYOTA_AVENSIS_WHITE) that we can return instantly (remember that a Car is immutable and can be reused over and over again) whenever we deem possible. We can also create specially tailored implementations of Cars like the ToyotaAvensisCarImpl where we only hold a single bean property for the color. All the other getters always return the same value and thus, we do not need to hold member variables for these. Now, imagine that we create millions of Toyotas and further imagine how much memory we can save.

Because all things are public in an interface, I have created an (inherently public) class named Hidden. In this inner class, I can decide the visibility of the things I put in here even though Hidden itself is visible from the outside. In the Hidden class I have defined a DefaultCar that implements the Car interface. This class can then be reused, both for the Builder and for any other implementation of the Car interface like the DefaultCar. This way, we do not have to declare variables several times (one for the Builder and one for each implementing class).

A small disadvantage is that the optional parameters are not final in the implementing class, so you need to take care, not to set the variables in any way. If you want them final, you can always refrain from extending DefaultCar at the cost of being forced to define them directly again in the implementing classes. The choice is yours.

I think the Interface Builder Pattern provides a number of important advantages over the normal Builder Pattern with concrete classes.

Happy coding!




Sunday, August 31, 2014

Creating objects using the Builder Pattern


Creating objects using the Builder Pattern


There are several patterns you can use when you want to create objects. In this post we will elaborate on some of them and we will learn the benefits of the builder pattern and discover how this pattern can be used, both in base and extended Java classes. Before we talk about the builder pattern we will first talk about some other means of creating and instantiating objects.

The Short Overview

Using the builder pattern you can create classes like this:
    Car toyota = new Car.Builder("Toyota", "Avensis").power(108).torque(180).gears(6).build();

instead of using the bean pattern like this:
    Car toyota = new Car("Toyota", "Avensis");
    toyota.setPower(108);
    toyota.setTorque(180);
    toyota.setGears(6);

or instead of using the telescope pattern like this:
    Car Toyota = new Car("Toyota", "Avensis", 108, 180, 6);

The builder pattern is more scalable and more robust than the other patterns as we will learn below.


The Bean Pattern

The traditional bean pattern relies on invoking an object's constructor (for example with its mandatory parameters) and then use the object's setters to initialize any optional parameters you might have. This sounds simple and robust, but, as we are about to see, this is more often than not a bad way to go about.

The following class outlines a Car class implemented using the bean pattern with the mandatory parameters "brand" and "type". There are also a bunch of additional optional parameters that we can set such as engine power and torque, the number of gears and the color of the car. Since we have not mention any specific units for the optional parameters, we assume that they are all in SI units. For example, power is measured in kW and torque in Nm.

public class Car {

    // Required parameters
    private final String brand;
    private final String type;

    // Optional parameters
    private int power;
    private int torque;
    private int gears;
    private String color;

    public Car(String brand, String type, int power, int torque, int gears, String color) {
        this.brand = brand;
        this.type = type;
        this.power = power;
        this.torque = torque;
        this.gears = gears;
        this.color = color;
    }

    public Car(String brand, String type) {
        this(brand, type, 0, 0, 0, null);
    }

    public String getBrand() {
        return brand;
    }

    public String getType() {
        return type;
    }

    public int getPower() {
        return power;
    }

    public void setPower(int power) {
        this.power = power;
    }

    public int getTorque() {
        return torque;
    }

    public void setTorque(int torque) {
        this.torque = torque;
    }

    public int getGears() {
        return gears;
    }

    public void setGears(int gears) {
        this.gears = gears;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

}

Now, if we want to create a new Car we can do it like this:

        final Car toyota = new Car("Toyota", "Avensis");
        toyota.setPower(108);
        toyota.setTorque(180);
        toyota.setGears(6);

As can be seen, an object of the Car type can not be created without the mandatory parameters "brand" and "type" (without "cheating" using reflection or similar methods at least). Furthermore, the mandatory parameters can not be changed after object instantiation, which is desirable most times.

However, there are several problems with the bean pattern. Apparently, the Car can be observed from outside while it is being instantiated (for example, by inserting code between the setPower() and the setTorque() method calls), allowing a partially instantiated Car to be exposed, possibly to another Thread. This may potentially lead to hard-to-find bugs. Another problem is that there is no logical point of asserting the validity of the parameters and their relation. Suppose, for example, that you know that Toyota does not manufacture any car with a power output less than 80 kW if the car has 5 gears or more. How and when will you add that check?

However, the most prominent drawback, according to my view, is that the bean pattern excludes the use of immutable objects. Many of Java's built-in objects like String and Integer are immutable and there are good reasons for that. An immutable class is, by definition, thread safe and many of its methods, like hashCode() and toString() can be optimized so that they are calculated only once. Furthermore, if all the member variables are final, you ensure their invariants and the compiler also generates an error if you forget to initialize such a variable. Mutable classes can be a real nightmare when used as keys in HashMaps or HashSets because, if the key is changed once it has been hashed into the Map/Set, it can never be found again, but will still remain in the Map/Set more or less as a dormant "zombie"!

The Telescope Pattern

Instead of using setters, we can have all the variables being initialized directly using one or several constructors. However, when you create new objects that have a sizable amount of member variables, some of which are optional, you will often end up with a considerable amount of constructors or static creation methods. For example, the well known telescope constructor pattern can be used where one typically provides a single constructor with the mandatory parameters followed by an entourage of constructor variants with one, two, .., N of additional optional parameters. This likely leads to a silly amount of constructors that are hard to manage and overview. Also, each time you override such an object, you typically have to duplicate all the constructors to expose them in the new extending class and add even more constructors to cover the new members introduced in the extending class.

If some parameters have the same type, like "power" and "torque" which both are int, it will also prevent us from having separate constructors with these parameters, since these constructors will have the same signature. It would, for example, be impossible to define both public Car(String brand, String type, int power) and public Car(String brand, String type, int torque) at the same time, because they both are Car(String, String, int).

Consider the following Car class that can be created using a traditional telescope constructor pattern:

public class Car {

     // Required parameters
    private final String brand;
    private final String type;

     // Optional parameters
    private final int power;
    private final int torque;
    private final int gears;
    private final String color;

    // Constructor will mandatory parameters    
    public Car(String brand, String type) {
        this(brand, type, 0);
    }

    // Constructor will mandatory parameters and 1 optional parameter
    public Car(String brand, String type, int power) {
        this(brand, type, power, 0);
    }

    // Constructor will mandatory parameters and 2 optional parameters
    public Car(String brand, String type, int power, int torque) {
        this(brand, type, power, torque, 0);
    }

    // Constructor will mandatory parameters and 3 optional parameters
    public Car(String brand, String type, int power, int torque, int gears) {
        this(brand, type, power, torque, gears, null);
    }

    // Constructor will all parameters
    public Car(String brand, String type, int power, int torque, int gears, String color) {
        this.brand = brand;
        this.type = type;
        this.power = power;
        this.torque = torque;
        this.gears = gears;
        this.color = color;
    }

    public String getBrand() {
        return brand;
    }

    public String getType() {
        return type;
    }

    public int getPower() {
        return power;
    }

    public int getTorque() {
        return torque;
    }

    public int getGears() {
        return gears;
    }

    public String getColor() {
        return color;
    }
}
It becomes apparent why the pattern is called the telescope pattern when we consider what happens if we invoke the constructor Car(String brand, String type). It will call the constructor Car(String brand, String type, int power) which, in turn progressively will call constructors with more and more parameters until the constructor with all parameter finally is invoked.

We might now, for example, create a new Car using this statement:
  final Car toyota = new Car("Toyota", "Avensis", 108, 180, 6);

Now, we have obtained an immutable object, which is a big improvement over the previous Car class created using the bean pattern. Despite this, we are still suffering from the other drawbacks associated with the bean pattern as described above. This is where the builder pattern comes in.

The Builder Pattern

The builder pattern comes with a price of some coding overhead, but brings many advantages over the previous patterns. Here is how the Car class can look like when accompanied with an inner Builder class:

public class Car {

    // Required parameters
    private final String brand;
    private final String type;

    // Optional parameters
    private final int power;
    private final int torque;
    private final int gears;
    private final String color;

    public static class Builder {

        // Required parameters
        private final String brand;
        private final String type;

        // Optional parameters
        private int power;
        private int torque;
        private int gears;
        private String color;

        public Builder(String brand, String type) {
            this.brand = brand;
            this.type = type;
        }

        public Builder power(int power) {
            this.power = power;
            return this;
        }

        public Builder torque(int torque) {
            this.torque = torque;
            return this;
        }

        public Builder gears(int gears) {
            this.gears = gears;
            return this;
        }

        public Builder color(String color) {
            this.color = color;
            return this;
        }

        public Car build() {
            return new Car(this);
        }

    }

    private Car(Builder builder) {
        this.brand = builder.brand;
        this.type = builder.type;
        this.power = builder.power;
        this.torque = builder.torque;
        this.gears = builder.gears;
        this.color = builder.color;
    }

    public String getBrand() {
        return brand;
    }

    public String getType() {
        return type;
    }

    public int getPower() {
        return power;
    }

    public int getTorque() {
        return torque;
    }

    public int getGears() {
        return gears;
    }

    public String getColor() {
        return color;
    }

}
The neat thing with this is that now you can create a Car simply by first creating its Builder and then secondly invoking any number of its "setters" (in arbitrary order) finally followed with the build() method. It looks like this:
final Car toyota = new Car.Builder("Toyota","Avensis").power(108).torque(180).gears(6).build();
As can be seen, it is much easier to read and understand what is going on. The pattern gives you the impression that you can use named optional parameters even though this is not intrinsically supported by the Java language. There is only one constructor and there is also a very good spot where you can check the validity of the parameters, namely in the build() method. When the latter method is called, you know all the parameters that has been set and if you detect any inconsistencies, you can elect to throw an IllegalStateException telling what is wrong. The build() method can also be made to derive or compute default values for unset parameters.

One obvious drawback with this solution is that you can not change the Car once you build() it, so rebuilding is impossible. You have to re-create the Car from scratch if you want to change anything. In the next section we will learn how we can get around this limitation.

Obtaining New Immutables Using an Improved Builder Pattern

By definition, an immutable object can not be changed. But what can we do if we want to create a new object using an existing object that supports the builder pattern as described above? One very convenient way of doing this is to let our class implement a toBuilder() method that will return a Builder similar to the old Builder, but not only using the constructor, but rather with all the values copied back from the already existing immutable class itself. To achieve this, we only need to add the following lines to our previous Car class:
   public Builder toBuilder() {
        return new Builder(getBrand(), getType()).
            power(getPower()).torque(getTorque()).gears(getGears()).color(getColor());
    }
And now we can create new mutable Builders form existing immutable Car classes like this:
    // This is the Car type that I can order at the car reseller
    final Car toyota = new Car.Builder("Toyota", "Avensis").
            power(108).torque(180).gears(6).build();

    // I want a Black Car!
    final Car myNewCar = toyota.toBuilder().color("Black").build();
The toBuilder() and build() methods provide a means to switch between immutable and mutable objects seamlessly!

Extending  Classes With Builders

Once you become familiar with the builder concept and start using the pattern, you will quickly encounter the challenge of extending builder pattern classes. How can we do this in an efficient and appealing way? I will provide one solution here. First, we will have to modify the Car class slightly to make it a bit more easily to extend.
public class Car {

    // Required parameters
    private final String brand;
    private final String type;

    // Optional parameters
    private final int power;
    private final int torque;
    private final int gears;
    private final String color;

    public static class Builder {

        // Required parameters
        private final String brand;
        private final String type;

        // Optional parameters
        private int power;
        private int torque;
        private int gears;
        private String color;

        public Builder(String brand, String type) {
            this.brand = brand;
            this.type = type;
        }

        public Builder power(int power) {
            this.power = power;
            return this;
        }

        public Builder torque(int torque) {
            this.torque = torque;
            return this;
        }

        public Builder gears(int gears) {
            this.gears = gears;
            return this;
        }

        public Builder color(String color) {
            this.color = color;
            return this;
        }

        public Car build() {
            return new Car(this);
        }

    }

    // Changed to protected
    protected Car(Builder builder) {
        this.brand = builder.brand;
        this.type = builder.type;
        this.power = builder.power;
        this.torque = builder.torque;
        this.gears = builder.gears;
        this.color = builder.color;
    }

    public String getBrand() {
        return brand;
    }

    public String getType() {
        return type;
    }

    public int getPower() {
        return power;
    }

    public int getTorque() {
        return torque;
    }

    public int getGears() {
        return gears;
    }

    public String getColor() {
        return color;
    }

    // New methods below
    protected Builder newBuilder() {
        return new Builder(getBrand(), getType());
    }

    protected Builder decorate(Builder builder) {
        return builder.power(getPower()).torque(getTorque()).
            gears(getGears()).color(getColor());
    }

    public Builder toBuilder() {
        return decorate(newBuilder());
    }
}
Note that the Car's constructor now is protected instead of private, allowing overriding classes to invoke it. We have also added and/or changed three new methods:

  • newBuilder(), simply creates a new Builder that can be used to create the desired class, in this example a Car.
  • decorate(), takes a Builder and "decorates" it with all the parameters it knows from the existing invariants.
  • toBuilder(), now just simply decorates() a newBuilder(), resulting in a Builder with all parameters set from the corresponding invariants.

Note that we use getters whenever we refer to the parameters. This way, if we override one or several getters, we will get the correct result reflected in the new Builder.

Now, suppose that I want to create an ElectricCar class by extending the existing Car class. The new class will have a new optional parameter called batteryCapacity. In the example below I will show one possible way of implementing the new class:
public class ElectricCar extends Car {

    private final int batteryCapacity; // Capacity in kWh

    public static class Builder extends Car.Builder {

        private int batteryCapacity;

        public Builder(String brand, String type) {
            super(brand, type);
        }

        public Builder batteryCapacity(int batteryCapacity) {
            this.batteryCapacity = batteryCapacity;
            return this;
        }

        @Override
        public Builder color(String color) {
            return (Builder) super.color(color);
        }

        @Override
        public Builder gears(int gears) {
            return (Builder) super.gears(gears);
        }

        @Override
        public Builder power(int power) {
            return (Builder) super.power(power);
        }

        @Override
        public Builder torque(int torque) {
            return (Builder) super.torque(torque);
        }

        @Override
        public ElectricCar build() {
            return new ElectricCar(this);
        }

    }

    protected ElectricCar(Builder builder) {
        super(builder);
        this.batteryCapacity = builder.batteryCapacity;
    }

    public int getBatteryCapacity() {
        return batteryCapacity;
    }

    @Override
    protected Builder newBuilder() {
        return new Builder(getBrand(), getType());
    }

    protected Builder decorate(Builder builder) {
        super.decorate(builder);
        return builder.batteryCapacity(getBatteryCapacity());
    }

    @Override
    public Builder toBuilder() {
        return (Builder) super.toBuilder();
    }
}
We observe that the build() method in the new Builder class now creates an ElectricCar rather then just a Car. The new Builder will inherit from the old Car.Builder but all its optional "setters" now returns a Builder that builds ElectricalCars, however their bodies just calls the Car.Builder's old existing methods. Looking at the ElectricCar class itself, we see that it now has a new method called newBuilder() that, unsuprisingly, returns a new Builder that builds ElectricalCars instead of Cars and a new decorate() method that does everything that the Car.decorate() method did, plus decorating the new Builder with the getBatteryCapacity(). The toBuilder() method body is unchanged but
it is cast so that it now returns a Builder that builds ElecticalCars.

Now you can use the new ElectricalCar class as shown below:
   final ElectricCar tesla = new ElectricCar.Builder("Tesla", "S").
           power(310).torque(600).gears(1).batteryCapacity(60).build();

   final ElectricCar myNewCar = tesla.toBuilder().color("White").batteryCapacity(85).build();
As you can see, my new car is a white electrical car with an upgraded battery package!

Future Improvement Potential When Inheriting Builder Classes

As can be seen, the optional "setter" methods in the Builder all need to be overridden, creating seemingly unnecessary statements in our Builder. It would be interesting to see if the overriding builder pattern shown above could be implemented using generics for the Builder, so that the optional "setter" methods in the extended Builder could be inherited directly from the base Builder without having to be overridden and cast.

Another point of improvement would be to let the Car class itself use generics too, so that we do not have to override the toBuilder() method.

Apparently, both the Builder and the main base class (i.e. Car and ElectricalCar) contain the same member fields. Perhaps a new pattern can be found, that eliminate dual declaration of these
fields by letting one of the classes inherit them from the other class.

Read my follow up post on the Interface Builder Pattern how to make the Builder Pattern even better!

Conclusion

The builder pattern has many advantages over the bean pattern and the telescope pattern, but requires a bit more coding. Code readability and robustness is improved substantially and we may work with immutable classes. Classes are created using the Builder's build() method. By implementing a corresponding  toBuilder() method, we can easily switch back and forth between immutable and mutable classes combining the best of two worlds. Classes using the builder pattern can relatively easy be extended indefinitely. There are still some potential to improve the patterns depicted in this article.

If you want to read more on the subject, I recommend reading chapter 2 in the book "Effective Java", second edition, by Joshua Bloch. I think it is a very good book.

Feel free to comment and improve on the examples above that I have shown in this post.

Happy object creation!