Photo by Bagus Pangestu on Pexels

DESIGN PATTERNS IN JAVA SERIES

Design Patterns in Java/Android — Builder

Explanations, Caveats, Examples from Android Framework & Java Libraries, Writing our own Builder

Suryakant Bharti
Android Saga
Published in
5 min readMar 13, 2022

--

This series on Software Design Patterns will introduce some common design patterns that we use in app development.

  1. Singleton
  2. Builder ← we are here
  3. Factory
  4. Prototype
  5. Adapter
  6. Facade
  7. Observer
  8. Command

Here, we will take examples of existing design patterns in Android framework & Java Libraries and also write our own patterns in Java.

Introduction to Design Patterns

Software Design Patterns are time-tested, reusable solutions to recurring software problems. They define a common language that helps our team communicate more efficiently.

Design patterns usually deals with objects. The patterns differ by their complexity, reusability, purpose and scale of application in the system. All patterns an be categorized mainly into 3 categories based on their purpose:

  • Creational patterns: How the objects are created.
    Eg. Singleton pattern, Builder pattern, Factory pattern
  • Structural patterns: How the objects are composed (assembling objects into larger structures).
    Eg. Adapter pattern, Facade pattern, Decorator pattern
  • Behavioral patterns: How the objects coordinate (communication and assignment of responsibilities between objects).
    Eg. Observer pattern, Strategy pattern, Command pattern

Builder Design Pattern

The Builder is one of the most common design pattern. It is a simple creational design pattern, which allows constructing complex objects step by step. This pattern helps in the construction/building of objects where the object is made of various parts but all the parts are not compulsory to create the object. In this way, the same assembly process can create objects of the same class with different properties. We can think of an example of buying Pizza in a restaurant/app, we get to choose the various ingredients of the Pizza, so similarly, builder pattern provides a list of options to choose from for creating an object.

Toys are being assembled part-by-part by using Builder Pattern (Image from refactoring.guru)

Examples of Builder from Android Framework & Java Libraries

In a standard Android app, many times we may need to create a class where the every object of that lass may not have all the properties. We use Builder Pattern at the time. Examples of Builder patterns in Android Framework and Libraries are: Locale builder, Calendar builder, Gson builder, OkHttp builder, Notification builder, AlertDialog builder, Guava MapMaker builder, etc.

Locale Builder

Locale is an example from Java 7

Calendar Builder

Calendar is an example from Java 8

Gson Builder

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object.

OkHttpClient Builder

OkHttp is an HTTP client for Android and Java applications. We are using OkHttpClient.Builder() to create a shared instance with custom settings below.

Android Notification Builder

NotificationCompat builder is used to construct Notification objects. Provides a good way to set the various fields of a Notification and generate content views using the platform’s notification layout template.

Android AlertDialog Builder

  • AlertDialog is subclass of Dialog that can display 1–3 buttons with a message.AlertDialog builder is used to construct AlertDialog objects.

Android Toasts (Not Builder, but similar Fluent Interface Design)

Fluent Interface is a Pattern (Object Oriented API) which relies on Method Chaining. A toast provides simple feedback about an operation in a small popup.

Writing our own Builder in Java

The app/project will become complex & messy if we create a subclass for every possible configuration of an object, so better way is to use Builder Pattern (Image from refactoring.guru)

Let us create our own Builder Pattern now.

Unlike other creational patterns, Builder doesn’t require products to have a common interface. That makes it possible to produce different products using the same construction process. Sometimes we need to have such class. Let’s see how to implement such a class. If we have a good understanding of static inner class and access modifiers, achieving this should not be a difficult task.

1. Configurable classes using Multiple Constructors

Normally, if we require a classes with optional fields/properties, we would write a POJO using constructors with various combinations as shown above.

In this way we end up having exponentially huge number of contractors as the number of fields increase. This makes the code size unmanageable and a big mess.

2. Configurable classes using Method Chaining

Method Chaining is used to invoke multiple methods on the same object which occurs as a single statement. Method-chaining is implemented by a series of methods that return the ‘this’ reference for a class instance.

Method chaining is a useful design pattern but however if accessed concurrently, a thread may observe some fields to contain inconsistent values. Although all setter methods in above example are atomic, but calls in the method chaining can lead to inconsistent object state when the object is modified concurrently. Hence, this design is not thread safe.

-> Running our Method Chaining

This code can be used to run the code of Method Chaining given above.

3. Configurable classes using Builder Pattern

To solve this issues faced in above designs, we can use Builder Design Pattern as shown below.

Here, we have a inner static class named Builder inside our Server class with instance fields for that class and also have a method to return an new instance of Builder class on every invocation.

As we can see above (in the Builder pattern), to create a classes with optional fields/properties, it doesn’t need to make exponentially huge number of constructors, methods or anything else. So, our problem is solved. This design is manageable and atomic (thus, thread safe).

-> Running our Builder Pattern

This code can be used to run the code of Builder Pattern given above.

This article is supposed to serve as a beginner’s guide for the above design pattern.

Give a clap if you liked the article or a leave a comment for any suggestion/discussion/dispute. Thank you!

--

--

Suryakant Bharti
Android Saga

Android Developer (Kotlin, Java, OOPS, Data Structures, Algorithms, Design Patterns) github.com/Suryakant-Bharti