Tutorial

Builder Design Pattern in Java

Published on August 3, 2022
author

Pankaj

Builder Design Pattern in Java

Today we will look into Builder pattern in java. Builder design pattern is a creational design pattern like Factory Pattern and Abstract Factory Pattern.

Builder Design Pattern

builder pattern in java, builder design pattern, builder pattern Builder pattern was introduced to solve some of the problems with Factory and Abstract Factory design patterns when the Object contains a lot of attributes. There are three major issues with Factory and Abstract Factory design patterns when the Object contains a lot of attributes.

  1. Too Many arguments to pass from client program to the Factory class that can be error prone because most of the time, the type of arguments are same and from client side its hard to maintain the order of the argument.
  2. Some of the parameters might be optional but in Factory pattern, we are forced to send all the parameters and optional parameters need to send as NULL.
  3. If the object is heavy and its creation is complex, then all that complexity will be part of Factory classes that is confusing.

We can solve the issues with large number of parameters by providing a constructor with required parameters and then different setter methods to set the optional parameters. The problem with this approach is that the Object state will be inconsistent until unless all the attributes are set explicitly. Builder pattern solves the issue with large number of optional parameters and inconsistent state by providing a way to build the object step-by-step and provide a method that will actually return the final Object.

Builder Design Pattern in Java

Let’s see how we can implement builder design pattern in java.

  1. First of all you need to create a static nested class and then copy all the arguments from the outer class to the Builder class. We should follow the naming convention and if the class name is Computer then builder class should be named as ComputerBuilder.
  2. Java Builder class should have a public constructor with all the required attributes as parameters.
  3. Java Builder class should have methods to set the optional parameters and it should return the same Builder object after setting the optional attribute.
  4. The final step is to provide a build() method in the builder class that will return the Object needed by client program. For this we need to have a private constructor in the Class with Builder class as argument.

Here is the sample builder pattern example code where we have a Computer class and ComputerBuilder class to build it.

package com.journaldev.design.builder;

public class Computer {
	
	//required parameters
	private String HDD;
	private String RAM;
	
	//optional parameters
	private boolean isGraphicsCardEnabled;
	private boolean isBluetoothEnabled;
	

	public String getHDD() {
		return HDD;
	}

	public String getRAM() {
		return RAM;
	}

	public boolean isGraphicsCardEnabled() {
		return isGraphicsCardEnabled;
	}

	public boolean isBluetoothEnabled() {
		return isBluetoothEnabled;
	}
	
	private Computer(ComputerBuilder builder) {
		this.HDD=builder.HDD;
		this.RAM=builder.RAM;
		this.isGraphicsCardEnabled=builder.isGraphicsCardEnabled;
		this.isBluetoothEnabled=builder.isBluetoothEnabled;
	}
	
	//Builder Class
	public static class ComputerBuilder{

		// required parameters
		private String HDD;
		private String RAM;

		// optional parameters
		private boolean isGraphicsCardEnabled;
		private boolean isBluetoothEnabled;
		
		public ComputerBuilder(String hdd, String ram){
			this.HDD=hdd;
			this.RAM=ram;
		}

		public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
			this.isGraphicsCardEnabled = isGraphicsCardEnabled;
			return this;
		}

		public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
			this.isBluetoothEnabled = isBluetoothEnabled;
			return this;
		}
		
		public Computer build(){
			return new Computer(this);
		}

	}

}

Notice that Computer class has only getter methods and no public constructor. So the only way to get a Computer object is through the ComputerBuilder class. Here is a builder pattern example test program showing how to use Builder class to get the object.

package com.journaldev.design.test;

import com.journaldev.design.builder.Computer;

public class TestBuilderPattern {

	public static void main(String[] args) {
		//Using builder to get the object in a single line of code and 
                //without any inconsistent state or arguments management issues		
		Computer comp = new Computer.ComputerBuilder(
				"500 GB", "2 GB").setBluetoothEnabled(true)
				.setGraphicsCardEnabled(true).build();
	}

}

Builder Design Pattern Video Tutorial

Recently I uploaded a YouTube video for Builder Design Pattern. I have also explained why I think the builder pattern defined on WikiPedia using Director classes is not a very good Object Oriented approach, and how we can achieve the same level of abstraction using different approach and with one class. Note that this is my point of view, I feel design patterns are to guide us, but ultimately we have to decide if it’s really beneficial to implement it in our project or not. I am a firm believer of KISS principle. https://www.youtube.com/watch?v=D5NK5qMM14g If you like the video, please do share it, like it and subscribe to my channel. If you think I am mistaken or you have any comments or feedback so that I can improve my videos in future, please let me know through comments here or on YouTube video page.

Builder Design Pattern Example in JDK

Some of the builder pattern example in Java classes are;

  • java.lang.StringBuilder#append() (unsynchronized)
  • java.lang.StringBuffer#append() (synchronized)

That’s all for builder design pattern in java.

You can download the example code from my GitHub Repository.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Pankaj

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
February 2, 2014

Good article. Simple, lucid & very specific. Brings all the initialization complexity to inner class, which keeps you outer class clean, love this pattern. Is it like builder pattern cannot be implemented on those class whose attributes keep shifting from mandatory to optional and vice-versa, unless its designed to take every attributes thru the setter method of inner class.

- HIMANSU NAYAK

JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
February 2, 2014

Yes if the attributes keep on changing from mandatory to optional and vice versa, we will have to change the inner class that will break the pattern. So implementation should be done based on clear requirements.

- Pankaj

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    July 8, 2014

    Good article. Why does below functions needs to return “this” when setting parameter? can you please give pointer on this?

    - M

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    July 8, 2014

    return this; is used to return the current object, this is how Builder pattern works and it’s key for that. Otherwise new Computer.ComputerBuilder("500 GB", "2 GB").setBluetoothEnabled(true).setGraphicsCardEnabled(true).build(); will not work.

    - Pankaj

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      August 13, 2014

      Hello Pankaj i have Question Why u have used only static nested class why not normal/regular inner class…i knw differences but in this example why we have used static nested clas only…plz reply…!

      - Amritpal Singh

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      August 25, 2014

      The primary usage of the Static Nested Inner class here is to create an inner class object without instantiating the enclosing outer class. Instead of creating multiple overload constructors and/or various setters for the Computer class and try to construct an object in multiple steps (Object created this might be inconsistent till all the needy fields are set!), we try to construct the computer object by using the static nested inner class ComputerBuilder.

      - Surya

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        September 9, 2014

        Hi Pankaj, There is still an issue with this approach. We are still expecting the client code to invoke the setters explicitly to ensure that the object state is consistent before the finally created object is returned upon invocation of build() method. We could have invoked the build method without even calling the setters and the boolean variables would have been initialized to false by default and still the object creation would have been successful with the consistent state. I think the another approach could be to provide a series of overloaded constructors with various combinations of optional parameters which invoke them in sequence until all the parameters are set and then the final object is created. In this case, we would not require to have even a build method. Please comment.

        - Ashish

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        September 9, 2014

        You can easily avoid that by using Boolean rather than primitive type boolean. Object default value is NULL. Also you should have a constructor with all the mandatory parameters so that client is forced to provide values for them. Creating multiple constructor with optional parameters will not help and you will not be using Builder pattern then.

        - Pankaj

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          October 5, 2014

          Can you please share/post UML design for the same as explain above Thanks Ashakant

          - Ashakant

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            January 6, 2015

            What is a need of getter and setter methods for outer class in above example if we are providing private constructor and no outer world can access the outer class?

            - Rishi Naik

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            December 8, 2015

            That’s correct as per my knowledge as well. There is no need to have getter and setter methods in the outside class.

            - Ketki

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            January 23, 2016

            Rishi: There are no setters in the outer class only getters. Secondly you do need those getter methods, otherwise how are you going to utilize the properties set in the Outer class By having just private constructor doesn’t mean you cannot access the outer class Computer comp = new Computer.ComputerBuilder(“500 GB”, “2 GB”).setBluetoothEnabled(true) .setGraphicsCardEnabled(true).build(); //This is creating the outer object System.out.println(comp.isBluetoothEnabled()) //This is use of getter method

            - Pratap Shinde

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              May 5, 2015

              By this way, we can also create the object. Can you please explain the difference in using return this and the way below : public class TestBuilderPattern { public static void main(String[] args) { // Using builder to get the object in a single line of code and // without any inconsistent state or arguments management issues Computer.ComputerBuilder comp = new Computer.ComputerBuilder(“500 GB”, “2 GB”); comp.setBluetoothEnabled(true); comp.setGraphicsCardEnabled(true); comp.build(); System.out.println(comp); } public void setGraphicsCardEnabled(boolean isGraphicsCardEnabled) { this.isGraphicsCardEnabled = isGraphicsCardEnabled; // return this; } public void setBluetoothEnabled(boolean isBluetoothEnabled) { this.isBluetoothEnabled = isBluetoothEnabled; // return this; } }

              - vijay

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                April 14, 2016

                This blog was really nicely articulated and helpful. Thanks …

                - Arijit Medya

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  July 8, 2016

                  Builder pattern described here is completely different from what other websites implementations. Here it shows with static inner class but others its not. Not sure which one is correct.

                  - Prabhakaran

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    July 8, 2016

                    I have one question that we are returning this in set() I know it is very important to return this in Builder pattern. But, Can you tell me what is the actual meaning when we return this and how it is actually executed. I have some confusions that how complier deal when we have used set() method of different fields for multiple times in same line of code while creating object and who will pick up this references of object before build().

                    - Kishan

                      JournalDev
                      DigitalOcean Employee
                      DigitalOcean Employee badge
                      September 10, 2016

                      This is not the definition of Builder pattern described in GoF. However, it’s a good solution for the problem mentioned at the beginning of the article which was addressed in Effective Java book.

                      - Maliox

                        JournalDev
                        DigitalOcean Employee
                        DigitalOcean Employee badge
                        September 19, 2016

                        It seems the only problem addressed here is when there are lot of input arguments to the constructor and all of them are not necessary. The above specified solution is just one of the use case of builder pattern. Don’t know if it is correct. Please refer to effective Java for the above specified problem. Chapter 2 Item 2.

                        - naval jain

                          JournalDev
                          DigitalOcean Employee
                          DigitalOcean Employee badge
                          October 14, 2016

                          Very nice article for Design Patterns!! SPOC blog for all design patterns for beginners.

                          - Hari

                            JournalDev
                            DigitalOcean Employee
                            DigitalOcean Employee badge
                            November 23, 2016

                            Please correct this syntax which is using in Builder factory pattern example. Your Code: Computer comp = new Computer.ComputerBuilder( “500 GB”, “2 GB”).setBluetoothEnabled(true) .setGraphicsCardEnabled(true).build(); call statement is wrong “new Computer.ComputerBuilder”

                            - Saurabh Tiwari

                              JournalDev
                              DigitalOcean Employee
                              DigitalOcean Employee badge
                              December 16, 2016

                              I see Builder Pattern being used in Spring Security (Something like this) . This is reference for Pattern being used ? public final class HttpSecurity extends AbstractConfiguredSecurityBuilder implements SecurityBuilder, HttpSecurityBuilder { its too complex to me to grasp easily in spring custom class . However this tutorial example is clear to understand the basic idea of using this Builder Pattern and implement. @Override public void configure(HttpSecurity http) throws Exception { http. anonymous().disable() .requestMatchers().antMatchers(“/user/**”) .and().authorizeRequests() .antMatchers(“/user/**”).access(“hasRole(‘ADMIN’)”) .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); } Thank you Pankaj /Jounaldev

                              - Venu

                                JournalDev
                                DigitalOcean Employee
                                DigitalOcean Employee badge
                                January 6, 2017

                                Well explained.

                                - PK

                                  JournalDev
                                  DigitalOcean Employee
                                  DigitalOcean Employee badge
                                  March 14, 2017

                                  https://stackoverflow.com/questions/5238007/stringbuilder-and-builder-pattern he Append method of StringBuilder simply adds more characters to the existing string. There are no new objects created (basic function of the builder pattern) and there is no design pattern involved. It’s a single method call to a single object instance. Please correct it.

                                  - Vinoth

                                    JournalDev
                                    DigitalOcean Employee
                                    DigitalOcean Employee badge
                                    June 15, 2017

                                    Builder pattern requires a Director, I don’t see it here. just because you are calling a build() in the end will not make it a builder pattern.

                                    - ravi

                                      JournalDev
                                      DigitalOcean Employee
                                      DigitalOcean Employee badge
                                      November 1, 2017

                                      Font is too big to Read. pls make one unit small to boost Readability.

                                      - kathiravan

                                        JournalDev
                                        DigitalOcean Employee
                                        DigitalOcean Employee badge
                                        March 8, 2018

                                        A question regarding “We should follow the naming convention and if the class name is Computer then builder class should be named as ComputerBuilder”: Since our builder is a nested class, it will usually be addressed by something like ContainingClass.NestedClass, right? For example ClassToBeBuilt.Builder. Why does the convention suggest to use ClassToBeBuilt.ClassToBeBuiltBuilder instead?

                                        - yaccob

                                          JournalDev
                                          DigitalOcean Employee
                                          DigitalOcean Employee badge
                                          September 10, 2016

                                          This is not the definition of Builder pattern described in GoF. However, it’s a good solution for the problem mentioned at the beginning of the article which was addressed in Effective Java book.

                                          - Maliox

                                            JournalDev
                                            DigitalOcean Employee
                                            DigitalOcean Employee badge
                                            September 19, 2016

                                            It seems the only problem addressed here is when there are lot of input arguments to the constructor and all of them are not necessary. The above specified solution is just one of the use case of builder pattern. Don’t know if it is correct. Please refer to effective Java for the above specified problem. Chapter 2 Item 2.

                                            - naval jain

                                              JournalDev
                                              DigitalOcean Employee
                                              DigitalOcean Employee badge
                                              October 14, 2016

                                              Very nice article for Design Patterns!! SPOC blog for all design patterns for beginners.

                                              - Hari

                                                JournalDev
                                                DigitalOcean Employee
                                                DigitalOcean Employee badge
                                                November 23, 2016

                                                Please correct this syntax which is using in Builder factory pattern example. Your Code: Computer comp = new Computer.ComputerBuilder( “500 GB”, “2 GB”).setBluetoothEnabled(true) .setGraphicsCardEnabled(true).build(); call statement is wrong “new Computer.ComputerBuilder”

                                                - Saurabh Tiwari

                                                  JournalDev
                                                  DigitalOcean Employee
                                                  DigitalOcean Employee badge
                                                  December 16, 2016

                                                  I see Builder Pattern being used in Spring Security (Something like this) . This is reference for Pattern being used ? public final class HttpSecurity extends AbstractConfiguredSecurityBuilder implements SecurityBuilder, HttpSecurityBuilder { its too complex to me to grasp easily in spring custom class . However this tutorial example is clear to understand the basic idea of using this Builder Pattern and implement. @Override public void configure(HttpSecurity http) throws Exception { http. anonymous().disable() .requestMatchers().antMatchers(“/user/**”) .and().authorizeRequests() .antMatchers(“/user/**”).access(“hasRole(‘ADMIN’)”) .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); } Thank you Pankaj /Jounaldev

                                                  - Venu

                                                    JournalDev
                                                    DigitalOcean Employee
                                                    DigitalOcean Employee badge
                                                    January 6, 2017

                                                    Well explained.

                                                    - PK

                                                      JournalDev
                                                      DigitalOcean Employee
                                                      DigitalOcean Employee badge
                                                      March 14, 2017

                                                      https://stackoverflow.com/questions/5238007/stringbuilder-and-builder-pattern he Append method of StringBuilder simply adds more characters to the existing string. There are no new objects created (basic function of the builder pattern) and there is no design pattern involved. It’s a single method call to a single object instance. Please correct it.

                                                      - Vinoth

                                                        JournalDev
                                                        DigitalOcean Employee
                                                        DigitalOcean Employee badge
                                                        June 15, 2017

                                                        Builder pattern requires a Director, I don’t see it here. just because you are calling a build() in the end will not make it a builder pattern.

                                                        - ravi

                                                          JournalDev
                                                          DigitalOcean Employee
                                                          DigitalOcean Employee badge
                                                          November 1, 2017

                                                          Font is too big to Read. pls make one unit small to boost Readability.

                                                          - kathiravan

                                                            JournalDev
                                                            DigitalOcean Employee
                                                            DigitalOcean Employee badge
                                                            March 8, 2018

                                                            A question regarding “We should follow the naming convention and if the class name is Computer then builder class should be named as ComputerBuilder”: Since our builder is a nested class, it will usually be addressed by something like ContainingClass.NestedClass, right? For example ClassToBeBuilt.Builder. Why does the convention suggest to use ClassToBeBuilt.ClassToBeBuiltBuilder instead?

                                                            - yaccob

                                                              JournalDev
                                                              DigitalOcean Employee
                                                              DigitalOcean Employee badge
                                                              September 10, 2016

                                                              This is not the definition of Builder pattern described in GoF. However, it’s a good solution for the problem mentioned at the beginning of the article which was addressed in Effective Java book.

                                                              - Maliox

                                                                JournalDev
                                                                DigitalOcean Employee
                                                                DigitalOcean Employee badge
                                                                September 19, 2016

                                                                It seems the only problem addressed here is when there are lot of input arguments to the constructor and all of them are not necessary. The above specified solution is just one of the use case of builder pattern. Don’t know if it is correct. Please refer to effective Java for the above specified problem. Chapter 2 Item 2.

                                                                - naval jain

                                                                  JournalDev
                                                                  DigitalOcean Employee
                                                                  DigitalOcean Employee badge
                                                                  October 14, 2016

                                                                  Very nice article for Design Patterns!! SPOC blog for all design patterns for beginners.

                                                                  - Hari

                                                                    JournalDev
                                                                    DigitalOcean Employee
                                                                    DigitalOcean Employee badge
                                                                    November 23, 2016

                                                                    Please correct this syntax which is using in Builder factory pattern example. Your Code: Computer comp = new Computer.ComputerBuilder( “500 GB”, “2 GB”).setBluetoothEnabled(true) .setGraphicsCardEnabled(true).build(); call statement is wrong “new Computer.ComputerBuilder”

                                                                    - Saurabh Tiwari

                                                                      JournalDev
                                                                      DigitalOcean Employee
                                                                      DigitalOcean Employee badge
                                                                      December 16, 2016

                                                                      I see Builder Pattern being used in Spring Security (Something like this) . This is reference for Pattern being used ? public final class HttpSecurity extends AbstractConfiguredSecurityBuilder implements SecurityBuilder, HttpSecurityBuilder { its too complex to me to grasp easily in spring custom class . However this tutorial example is clear to understand the basic idea of using this Builder Pattern and implement. @Override public void configure(HttpSecurity http) throws Exception { http. anonymous().disable() .requestMatchers().antMatchers(“/user/**”) .and().authorizeRequests() .antMatchers(“/user/**”).access(“hasRole(‘ADMIN’)”) .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); } Thank you Pankaj /Jounaldev

                                                                      - Venu

                                                                        JournalDev
                                                                        DigitalOcean Employee
                                                                        DigitalOcean Employee badge
                                                                        January 6, 2017

                                                                        Well explained.

                                                                        - PK

                                                                          JournalDev
                                                                          DigitalOcean Employee
                                                                          DigitalOcean Employee badge
                                                                          March 14, 2017

                                                                          https://stackoverflow.com/questions/5238007/stringbuilder-and-builder-pattern he Append method of StringBuilder simply adds more characters to the existing string. There are no new objects created (basic function of the builder pattern) and there is no design pattern involved. It’s a single method call to a single object instance. Please correct it.

                                                                          - Vinoth

                                                                            JournalDev
                                                                            DigitalOcean Employee
                                                                            DigitalOcean Employee badge
                                                                            June 15, 2017

                                                                            Builder pattern requires a Director, I don’t see it here. just because you are calling a build() in the end will not make it a builder pattern.

                                                                            - ravi

                                                                              JournalDev
                                                                              DigitalOcean Employee
                                                                              DigitalOcean Employee badge
                                                                              November 1, 2017

                                                                              Font is too big to Read. pls make one unit small to boost Readability.

                                                                              - kathiravan

                                                                                JournalDev
                                                                                DigitalOcean Employee
                                                                                DigitalOcean Employee badge
                                                                                March 8, 2018

                                                                                A question regarding “We should follow the naming convention and if the class name is Computer then builder class should be named as ComputerBuilder”: Since our builder is a nested class, it will usually be addressed by something like ContainingClass.NestedClass, right? For example ClassToBeBuilt.Builder. Why does the convention suggest to use ClassToBeBuilt.ClassToBeBuiltBuilder instead?

                                                                                - yaccob

                                                                                  Try DigitalOcean for free

                                                                                  Click below to sign up and get $200 of credit to try our products over 60 days!

                                                                                  Sign up

                                                                                  Join the Tech Talk
                                                                                  Success! Thank you! Please check your email for further details.

                                                                                  Please complete your information!

                                                                                  Become a contributor for community

                                                                                  Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                                                                                  DigitalOcean Documentation

                                                                                  Full documentation for every DigitalOcean product.

                                                                                  Resources for startups and SMBs

                                                                                  The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                                                                                  Get our newsletter

                                                                                  Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                                                                                  New accounts only. By submitting your email you agree to our Privacy Policy

                                                                                  The developer cloud

                                                                                  Scale up as you grow — whether you're running one virtual machine or ten thousand.

                                                                                  Get started for free

                                                                                  Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                                                                                  *This promotional offer applies to new accounts only.