Builders in action
In this video we experiment with creating a simple builder class.
$ git clone https://github.com/serenity-dojo/vet-clinic.git
$ cd vet-clinic
$ git fetch
$ git checkout -b kata/builder/start remotes/origin/kata/builder/start
You can also find sample solutions in the kata/builder/* tags (kata/builder/step-1, kata/builder/step-2 and so on).
Import this project into your IDE. It should contain an empty project structure.
Step 1 - Creating a Dog with a name
First of all we need a place to store our domain model. Create a package called `domain` in the `serenitylabs.tutorials.vetclinic` package, in both `src/main/java` and `src/test/java`.
- First, add new class called `WhenWeCreateANewDog` in the `serenitylabs.tutorials.vetclinic.model` package under `src/test/java`.
- Next, create a new test called a_new_dog_should_have_a_name(), that demonstrates how you can create a new Dog instance with a given name. Use a constructor with a single field `name` with a getter method.
Step 2 - Adding a date of birth
Add a 'date-of-birth' field to the Dog class, by refactoring your test and the Dog class to use a constructor that takes two parameters: `name` and `dateOfBirth`.
Step 3 - Adding a breed
Now we need to cater for the breed of the dog. We can do this by simply adding another field called 'breed'. We could add a third parameter to the constructor, and a fourth, and so on, but the constructor would start to get hard to read, and it would be easy to mix up the parameter order.
We need a more readable way of creating a dog, where the person using the Dog API can easily see what attributes are available, and a person reading the code can easily see what attributes were used to create a particular dog.
We'll do this using what's known as the Builder Pattern. The Builder Pattern is basically a fancy way of saying that you write a class whose job it is to build instances of another class.Start by writing the builder expression that we would like to see as a user of our API. Try to make it as readable as possible. For example:
Dog fido = Dog.called("Fido").ofBreed("Labrador").bornOn(THE_FOURTH_OF_JULY);
- Generate the
called("Fido)method and make it return a new instance of the
- Create the
DogBreederclass with a single
- Add the
DogBreederclass and make it return the current
- Add the
bornOn()method that creates a new instance of
Dogusing a constructor with the three parameters,
- Add the
breedfield to the