DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Design Pattern: What You Need to Know to Improve Your Code Effectively
  • Prototype Pattern in JavaScript
  • Object Relational Behavioral Design Patterns in Java
  • Distribution Design Patterns in Java - Data Transfer Object (DTO) And Remote Facade Design Patterns

Trending

  • OpenAPI From Code With Spring and Java: A Recipe for Your CI
  • Why AI-Generated Code Breaks Your Testing Assumptions
  • Why Pass/Fail CI Pipelines Are Insufficient for Enterprise Release Decisions
  • Lambda-Driven API Design: Building Composable Node.js Endpoints With Functional Primitives
  1. DZone
  2. Coding
  3. Languages
  4. Creational Design Patterns: Builder Pattern

Creational Design Patterns: Builder Pattern

Want to learn more about creational design patterns? Here's how to use the Builder design pattern to create complex objects with multiple dependencies.

By 
Emmanouil Gkatziouras user avatar
Emmanouil Gkatziouras
DZone Core CORE ·
Jun. 26, 18 · Tutorial
Likes (17)
Comment
Save
Tweet
Share
55.1K Views

Join the DZone community and get the full member experience.

Join For Free

Previously, we had a look at the factory and the abstract factory pattern. These patterns serve their purpose and can be really useful. However, there are several use cases where we have to create a very complex object, which requires different steps and actions for each one. In such cases, the Builder design pattern can be really useful.

The Builder design pattern is a creational design pattern and can be used to create complex objects step by step.

Supposing we have an object with many dependencies and need to acquire each one of these dependencies, certain actions have to be issued. In such cases, we can use the Builder pattern in order to:

  • Encapsulate, create, and assemble the parts of a complex object in a separate Builder object.
  • Delegate the object creation to a Builder object instead of creating the objects directly.

Imagine the scenario of a backend system that has to compose and send emails.
Creating an email might be a complex procedure. You have to specify the title, set the recipients, add a greeting, and add a closing statement. You might also want to use mustache instead. Needless to say, there is a wide range of options.

Having one class for all the actions needed to create an email might make our class bloated and loose its original purpose.

So, we will start with the class responsible for sending the email.

package com.gkatzioura.design.creational.builder;

public class Email {

    private final String title;
    private final String recipients;
    private final String message;

    public Email(String title, String recipients, String message) {
        this.title = title;
        this.recipients = recipients;
        this.message = message;
    }

    public String getTitle() {
        return title;
    }

    public String getRecipients() {
        return recipients;
    }

    public String getMessage() {
        return message;
    }

    public void send() {

    }
}


As you can see, the class contains only three string fields and there is no extra processing on them. So, we shall create a builder class that will handle the message formatting, the recipient representation, and the creation of the Email   class.

package com.gkatzioura.design.creational.builder;

import java.util.HashSet;
import java.util.Set;

public class EmailBuilder {

    private Set recipients = new HashSet();
    private String title;
    private String greeting;
    private String mainText;
    private String closing;

    public EmailBuilder addRecipient(String recipient) {
        this.recipients.add(recipient);
        return this;
    }

    public EmailBuilder removeRecipient(String recipient) {
        this.recipients.remove(recipient);
        return this;
    }

    public EmailBuilder setTitle(String title) {
        this.title = title;
        return this;
    }

    public EmailBuilder setGreeting(String greeting) {
        this.greeting = greeting;
        return this;
    }

    public EmailBuilder setMainText(String mainText) {
        this.mainText = mainText;
        return this;
    }

    public EmailBuilder setClosing(String closing) {
        this.closing = closing;
        return this;
    }

    public Email create() {

        String message = greeting+"\n"+mainText+"\n"+closing;
        String recipientSection = commaSeparatedRecipients();

        return new Email(title,recipientSection,message);
    }

    private String commaSeparatedRecipients() {

        StringBuilder sb = new StringBuilder();
        for(String recipient:recipients) {
            sb.append(",").append(recipient);
        }

        return sb.toString().replaceFirst(",","");
    }

}


The next step is to make the email creation more strict so that creating an email would only be possible through the EmailBuilder.

package com.gkatzioura.design.creational.builder;

import java.util.HashSet;
import java.util.Set;

public class Email {

    private final String title;
    private final String recipients;
    private final String message;

    private Email(String title, String recipients, String message) {
        this.title = title;
        this.recipients = recipients;
        this.message = message;
    }

    public String getTitle() {
        return title;
    }

    public String getRecipients() {
        return recipients;
    }

    public String getMessage() {
        return message;
    }

    public void send() {

    }

    public static class EmailBuilder {

        private Set recipients = new HashSet();
        private String title;
        private String greeting;
        private String mainText;
        private String closing;

        public EmailBuilder addRecipient(String recipient) {
            this.recipients.add(recipient);
            return this;
        }

        public EmailBuilder removeRecipient(String recipient) {
            this.recipients.remove(recipient);
            return this;
        }

        public EmailBuilder setTitle(String title) {
            this.title = title;
            return this;
        }

        public EmailBuilder setGreeting(String greeting) {
            this.greeting = greeting;
            return this;
        }

        public EmailBuilder setMainText(String mainText) {
            this.mainText = mainText;
            return this;
        }

        public EmailBuilder setClosing(String closing) {
            this.closing = closing;
            return this;
        }

        public Email build() {

            String message = greeting+"\n"+mainText+"\n"+closing;
            String recipientSection = commaSeparatedRecipients();

            return new Email(title,recipientSection,message);
        }

        private String commaSeparatedRecipients() {

            StringBuilder sb = new StringBuilder();
            for(String recipient:recipients) {
                sb.append(",").append(recipient);
            }

            return sb.toString().replaceFirst(",","");
        }

    }
}


The end result of using the Builder pattern for creating an email will look like this:

Email email = new Email.EmailBuilder()
    .addRecipient("[email protected]")
    .setMainText("Check the builder pattern")
    .setGreeting("Hi John!")
    .setClosing("Regards")
    .setTitle("Builder pattern resources")
    .build();


To summarize, by using the Builder design pattern, we were able to create a complex object and its complex parts.

You can find the source code on GitHub. 

Builder pattern Design Object (computer science)

Published at DZone with permission of Emmanouil Gkatziouras. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Design Pattern: What You Need to Know to Improve Your Code Effectively
  • Prototype Pattern in JavaScript
  • Object Relational Behavioral Design Patterns in Java
  • Distribution Design Patterns in Java - Data Transfer Object (DTO) And Remote Facade Design Patterns

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook