Concepts

Adding Data To Objects – Using Builders for Immutable Data

To make data immutable, it must be set the moment the object is created, i.e. in the constructor. However, as we’ve seen in the introduction post, adding the data into the constructor directly comes with problems of its own – having multiple arguments in any function increases complexity and makes things confusing.

In the previous post, we were introduced to the concept of a builder, and showed how to construct the object we wanted in a way where the resulting code was easy to read and understand.

Is there a way to combine the two concepts above so that we can use a Builder to create an object where the fields cannot change their values? YES!

For simplicity, let’s run with the same example as we have seen before. However, in practice bear in mind that this may not be a good candidate as the age and year group will change as Harry gets older.

class Wizard {
    private final DEFAULT_LICENSE_NUMBER = 12345;

    private String name;
    private int age;
    private House house;
    private int yearGroup;
    private int apparitionLicenseNumber;

    public Wizard (Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.house = builder.house;
        this.yearGroup = builder.yearGroup;
        this.apparitionLicenseNumber = builder.apparitionLicenseNumber != null : apparitionLicenseNumber ? DEFAULT_LICENSE_NUMBER;
    }
     …

    static class Builder {
        private String name;
        private int age;
        private House house;
        private int yearGroup;
        private int apparitionLicenseNumber; 

        public static Builder aWizard() {
            return new Builder();
        }

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

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

        public Builder withHouse(House house) {
            this.house = house;
            return this;
        }

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

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

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

This is used when creating the object, in exactly the same way as before:

public class WizardTest {
    …
    Wizard harry = aWizard().withName("Harry Potter")
                            .withAge(14)
                            .withHouse(House.GRYFFINDOR)
                            .withYearGroup(3)
                            .build();
    …
}

And there we have it. Immutable data on an object created through a Builder – and most importantly, pretty code!

Next, we see another builder pattern which allows us to be told instantly if we are missing a mandatory field…

Advertisements

One thought on “Adding Data To Objects – Using Builders for Immutable Data

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s