The Builder Design Pattern8:46 with Chris Ramacciotti
As a step away from Hibernate, this lesson demonstrates a popular design pattern in coding called the **builder** design pattern. This pattern is used to write *readable* code that creates and configures an object.
Design Pattern Resources
- Overview & description of patterns: https://sourcemaking.com
- Code samples for patterns: https://github.com/iluwatar/java-design-patterns
Using Github With This Course
You can complete this course entirely using code created by you on your local machine. However, if you choose to use the code I've made available to you, you have two options:
- Use the project files linked at the bottom of this page, or
- Use the Github repository I've made available (recommended)
If you choose the recommended option of using the Github repository, it can be found at
To utilize Github with this course, you can download the Github desktop client for your system or use the command line interface provided with Git.
Clone this repository to your machine using the Github desktop client, or using the following command:
git clone firstname.lastname@example.org:treehouse/contactmgr-hibernate.git
To update your local repository to match a video's starting point, you can use the
git checkout ... command in combination with the stage and video number. For example, to update your local repository to match the starting point of Stage 5, Video 4, you'd use the following:
git checkout -f s5v4
Notice the use of the -f option. This forces Git to override all local changes, so be aware: this will cause any changes you made to be lost.
During the last video, we used a design pattern to build a service registry and 0:00 I mentioned that we'd circle back to it. 0:05 Well, here we are. 0:06 This pattern, called the Builder Pattern, is used to address a few common pit falls. 0:08 Mainly, the one of classes that have many fields. 0:14 Creating an object is accomplished by calling the classes constructor. 0:17 But, if the class has five instance feilds, like ours does. 0:21 We might end up with a constructor that has five perameters. 0:25 But the code that we type to instantiate an object with 0:29 five perimeters isn't that readable. 0:31 And what if we want to be able to create an object, 0:34 while specifying only a couple field values? 0:36 Well, I guess we need a constructor, but 0:39 the order of that parameter list may not be so obvious either. 0:42 So, we arrive at the builder pattern. 0:46 Using this pattern, 0:48 we're able to create readable code that's intuitive and easy to use. 0:49 To see how this is done, let's do this for our contact class now. 0:53 To demonstrate what we'd like to avoid, I'll use similar code here. 0:58 It's what we used earlier in the course to construct a sample contact object. 1:01 So, I'll create a contact, I'll name it contact. 1:06 And I will call a constructor that doesn't really exist but 1:09 let's pretend that it does. 1:12 I'll pass my first name, last name, email address. 1:13 And a phone number 773-555-6666. 1:21 Now if we had coded this 1:22 constructor in a contact class, as we did in workspaces earlier in the course. 1:28 We might remember the order of our four parameters or 1:32 we could pop open the source code to see. 1:35 Still, this would require an extra step that draws attention to the fact that our 1:37 code isn't as readable as it should be. 1:41 Even more, what if the contact class came from a jar file we've included in our 1:43 project and we don't have access to the source code? 1:47 For those reasons and 1:50 others, many developers choose the builder pattern to address concerns. 1:51 Wouldn't it be much more intuitive and 1:55 readable if our code coud look like this instead? 1:57 So, I'll create a contact and 2:01 builder object to specify something that we feel our users would know. 2:03 The first name and the last name and then, I'll put this on a separate line for 2:08 readability. 2:12 On that object, I could call a withEmail method and specify my email address. 2:13 And with that return value, I could call a withPhone method and 2:22 specify the phone number. 2:26 And that should be a long, not a string. 2:31 And finally, I'd call a build method to build my final contact object. 2:34 And actually, without too much effort, our code could look like this. 2:40 So, let's head over to contact.java to see how we can accomplish this. 2:45 The first thing we'll need to do is, add a contact builder class. 2:51 And though we could create this in a separate file, 2:54 we can also embed a static class in the contact class. 2:56 So for simplicity here in this course, that's what we'll do and 2:59 I will do this at the bottom. 3:03 Public, static, class, contact, builder. 3:05 We'll need a field in this class for 3:12 each of the contact fields we want our builder to configure. 3:14 So let's add those now. 3:17 I'll scroll up, and copy and paste the four that I'm interested in. 3:18 From above, so I'm interested in these four, right here. 3:22 So, I'll paste those right here and I'll remove my JPA annotations. 3:27 Great, now the contact builder constructor will contain 3:39 the two fields that are required. 3:42 And then, we might assume everyone will get right away, the first name and 3:44 the last name. 3:48 Of course, this assumption could certainly be up for debate. 3:49 Let's create that constructor now, public contactBuilder. 3:52 And in there, I'll specify the first name and the last name. 3:59 And this like any other constructor, will initialize its fields. 4:05 And now, we get to add those handy readable methods that we so desired. 4:15 Here is the withEmail method. 4:19 I going to declare it as a public ContactBuilder method withEmail and 4:22 as a parameter, we specify the email address. 4:27 Now this method is sort of like a setter, in that, 4:32 we set a field using a given parameter value. 4:35 But, there's one glaring difference, which makes this builder pattern so 4:38 attractive and that is the return value. 4:43 Notice that we're returning a contact builder object here and 4:46 the return value is this. 4:50 The object on which the method was called, a contact builder object. 4:53 This is the part that allows us to chain method calls. 4:57 If I pop back over to application.java, I see these chain method calls. 5:00 I create a contact builder and on that builder, I create with email and 5:05 I chain that to a withPhone call and finally a buildCall. 5:09 So in a similar fashion, let's now code the withPhone method. 5:17 So below the withEmail, I'll create a public ContactBuilder method. 5:22 Call it withPhone, and as a parameter, I'll include a long 5:27 and again, like a setter, we will set the field using the parameter value. 5:33 Except that we, as opposed to a setter, 5:39 will return a contact builder object, this. 5:42 Now the final method we need to create in this class, is the build method. 5:46 So to do that, 5:50 this one will create the contact object that we are after in the end. 5:51 I'll call this build and we'll return a new contact object and 5:56 give the contact constructor a reference to this object. 6:02 And I can't forget to create the object by using the new keyword. 6:07 Now, since we don't have a constructor that accepts a contact builder 6:12 object as a parameter, we need to create that as well. 6:15 So, we'll scroll up here and create that. 6:18 I'll do that after my default constructor that I listed here. 6:21 Public contact and this will accept a contact builder object here. 6:24 I'll just name it builder as the parameter name. 6:29 And in this constructor, 6:32 we'll initialize all the contact fields with the builder field values. 6:33 So to do that, I'll start with this.firstName pools builder.firstName, 6:38 this.lastName Equals builder.lastname. 6:46 This.email equals builder.email, and 6:51 this.phone equals builder.phone and there you have it. 6:56 If you want to prove this works in application.java, 7:03 you can print the contact object to standard out and run the application. 7:06 Now, I see that I'm missing an import statement here, so I'll go ahead and 7:10 import that. 7:14 If you get this prefix of Contact.ContactBuilder, 7:15 that is because ContactBuilder is a static class in the contact class. 7:19 If you don't want your code to look like this, 7:25 you can simply alter the import statement above. 7:28 You can, in addition to importing this class, 7:31 you can import ContactBuilder explicitly. 7:35 So below this initialization of the contact object, 7:40 I can simply display the contact object. 7:44 Which willll call that objects to string method, which we included in our class. 7:47 Before I run this, I'm going to comment out the session factor. 7:53 Since we don't want to initialize all that hibernating functionality quite yet. 7:56 So with that commented out, I'm going to right click application and 8:02 choose run and let's see what our output contains. 8:06 There are the results of the Contact's two string method, I see I got an ID of zero. 8:11 That will be the default value of that long field. 8:16 As well as a first name, last name, email address and phone number that I specified. 8:20 It looks like our builder pattern worked. 8:25 Now you've seen the builder pattern. 8:30 Which is often used for objects that involve complex and 8:32 otherwise, unintuitive configuration. 8:35 For more on Java design patterns, check the teacher's notes. 8:38 But now back to our regularly scheduled hibernate program. 8:42
You need to sign up for Treehouse in order to download course files.Sign up