How to use the Builder Pattern in Java – 035


Hi everyone! In the last lesson we talked
about chaining constructors to give ourselves more options for creating instances of our
classes. While chaining constructors helped us in some ways, it introduced a problem where
we needed a specific order to create our instance, so in this lesson I want to show you another
technique for creating instances in Java using the builder pattern. We’ll also discuss a
bit about what patterns are, and some good techniques for designing your class builders.
That’s coming up. First, what are design patterns? We’ll cover
design patterns in depth later in another series, but for now the quick 60 second version
is patterns are a standard way of addressing common programming problems with an identified
solution. The solution is based on the experience of other developers before us, and is usually
recognized a good solution to a known common problem. The beauty is, when we say builder pattern,
everyone should know we’re talking about a specific solution and they should already
have a good idea for how it works. Patterns are a common language we use to communicate
with other programmers. This makes it easier to talk to others about how a section of our
code functions. What is the builder pattern?
So what does the builder pattern do? The builder pattern is a pattern that allows us to separate
the construction of a more complex class, from the representation of the class. Basically
that means we’re creating a class who’s sole purpose in life is to create the class we
want. Imagine we’re asking someone to make a PC
for us. We would tell them the amount of RAM to use, the hard drive size, the CPU speed,
and so on. The person building our computer would take our list of specifications, and
turn that into a computer to hand back to us. The builder would also tell us when we’ve
asked for something that can’t be built. Like if we specify a SCSI hard drive, and a SATA
controller. That’s how it would work in real life. Here’s how it works in software. We create
a class that contains all the state variables we need to set to create a functioning object. We have a setter for each of these values.
You’ll notice we drop the “set” word from the method name. This is a departure from
how we normally do getters and setters. It’s because the builder uses the Fluent Interface
idiom. The Fluent Interface idiom just makes the code more readable when you’re using the
class. The interesting part is the setter returns
a builder object holding the value, and any other previously set values. This allows us
to chain our calls together. When we’re done, we call the build() method on the builder.
That returns us an instance of the object we want, with everything configured. If the builder can’t build our instance, it
should error out and not create the instance. In Java the standard way of doing this is
to throw an exception. Exceptions are a longer topic we’ll cover in depth. For now we’ll just throw exceptions using
this code. IllegalStateException is the exception we throw when someone is trying to create
our class in an illegal state. Exceptions are a longer topic we’ll cover in depth in
a later lesson. Just know this is causing an error, and prevents the instance from getting
created. How does this help?
Well for starters, order is no longer important. We can specify our attributes in any order.
In our football game, we can specify the home team, then the stadium, then the starting
position, and then the away team. Or we can specify them in another order. In
the end, our builder will give us a usable instance or an error. We’d use this over chaining constructors because
we can mix around the order of our state. It also allows us to prevent object creation
in an inconsistent state. We can’t create a game instance where only one team is specified.
We can’t forget to position the ball on the 35 yard line. The builder will not return
an instance until it has all the information needed to create the instance in a usable
state. The builder pattern would be overkill if you
have only a few attributes to set. For example, we probably would not use a builder pattern
to create an object with three attributes. Chaining is a simpler solution for simple
classes. The builder pattern is for larger, more complex class construction. Implementing the builder pattern
Let’s create a builder for our football game. We’ll create the class with all the parameters
we need for the game class. If we want to give any of these attributes default values,
we’ll do it in the builder. Each setter sets the value, then returns the GameBuilder instance. Then we provide a builder method. This method
first checks we have all the information we need to build the instance. If we cannot create
the instance in a useable state, we’ll throw an IllegalStateException. Finally we’ll create the instance in one go,
and return the result. We will also create a single constructor for our class that accepts
the builder as a parameter. This makes sure users of our class use the builder, one way
or another. You can create an instance of your class with
this code. This calls the build() method on the builder. This is the preferred way to
use the builder pattern. Another way to do it, is to populate a builder,
and then pass that to the class. This way is less desirable, because it’s harder to
read. The only reason you can do it this way is
because we need to create a single constructor for our game object. This enforces object
creation through the builder. The constructor with a builder argument should be the only
way to create your instances. This prevents sneaky developers from trying to create instances
without using the builder. We really want anyone using our class to use the builder. In order to completely prevent instance creation
without using the builder, we need make the builder part of the class. We can define a
class inside a class. So our builder would be a static class inside our class. In this
case, you’d make the constructor private. This way we can only create new instances
from the builder. There is no constructor exposed. Thanks for watching! That was a longer lesson,
so if you have any questions let me know in the comments. New lessons come out every week,
so make sure you subscribe. You don’t want to miss a video! And with that, I’ll see you in the next
tutorial!

Leave a Reply

Your email address will not be published. Required fields are marked *