Create Your Own Builder Pattern in Kotlin from Scratch

Design patterns are an essential part of software development. Among these, the Builder Pattern stands out for its ability to create complex objects step-by-step. While Kotlin provides powerful features like apply, with, and named arguments that often eliminate the need for classic patterns, implementing the Builder Pattern from scratch is still an excellent exercise to understand object creation and design principles.

In this blog, we'll build our own version of the Builder Pattern in Kotlin. Let's dive in!

What is the Builder Pattern?

The Builder Pattern is a creational design pattern used to construct complex objects step-by-step. Instead of creating the object in a single constructor call, the Builder Pattern allows us to build it incrementally, setting various properties along the way.

Key Characteristics:

  1. Step-by-step construction: Build the object one piece at a time.

  2. Immutability: The final object is often immutable once built.

  3. Fluent Interface: Methods return the builder itself, allowing for a chainable API.

When to Use the Builder Pattern?

The Builder Pattern is useful when:

  • You need to construct an object with many optional or configurable parameters.

  • The object initialization logic is complex.

  • You want to make your code more readable and flexible.

Step-by-Step Implementation

Let's take the example of building a RajasthanTrip class with properties like destination, duration, activities, and luxuryAccommodation.

1. Define the Target Class

First, define the RajasthanTrip class with properties:

class RajasthanTrip private constructor(
    val destination: String,
    val duration: Int, // in days
    val activities: List<String>,
    val luxuryAccommodation: Boolean
) {  

override fun toString(): String {
        return "RajasthanTrip(destination='$destination', duration=$duration days, activities=$activities, luxuryAccommodation=$luxuryAccommodation)"
    }
}

2. Create a Builder Class

This is where we define mutable properties and methods to configure the RajasthanTrip object step-by-step.

companion object {
        // A function to easily create a RajasthanTrip using a DSL
        fun create(
            destination: String = "Jaipur",
            duration: Int = 3,
            luxuryAccommodation: Boolean = false,
            buildActivities: MutableList<String>.() -> Unit = {}
        ): RajasthanTrip {
            val activities = mutableListOf<String>().apply(buildActivities)
            return RajasthanTrip(destination, duration, activities, luxuryAccommodation)
        }
    }

3. Use the Builder Class

Now, let's use the builder to construct a RajasthanTrip object:

fun main() {
    // Using the DSL-style builder for easy construction
    val trip = RajasthanTrip.create(
        destination = "Udaipur",
        duration = 5,
        luxuryAccommodation = true
    ) {
        add("Visit City Palace")
        add("Lake Pichola Boat Ride")
    }

    println(trip)
}

Output:

RajasthanTrip(destination='Udaipur', duration=5 days, activities=[Visit City Palace, Lake Pichola Boat Ride], luxuryAccommodation=true)

Kotlin's apply and Builder Pattern

Kotlin's apply and named arguments often eliminate the need for a traditional Builder Pattern. For example, the same RajasthanTrip object could be constructed using:

val trip = RajasthanTrip(
    destination = "Udaipur",
    duration = 5,
    activities = listOf("Visit City Palace", "Lake Pichola Boat Ride"),
    luxuryAccommodation = true
)

However, the Builder Pattern becomes invaluable when dealing with more complex object creation logic or when maintaining backward compatibility in large codebases.

Why Write Your Own Builder?

  1. Customization: You can add specific validation rules during object creation.

  2. Readability: A fluent, chainable API improves code clarity.

  3. Code Maintenance: Decouples the construction logic from the main class.

Advanced: Add Validation

You can enhance the builder with validation logic. For instance, ensuring a RajasthanTrip has at least one activity:

fun build(): RajasthanTrip {
    if (activities.isEmpty()) {
        throw IllegalArgumentException("RajasthanTrip must have at least one activity")
    }
    return RajasthanTrip(destination, duration, activities, luxuryAccommodation)
}

Conclusion

The Builder Pattern is a classic design pattern that provides a structured and readable way to construct objects. While Kotlin's features often simplify the need for traditional patterns, implementing the Builder Pattern from scratch gives you insights into object creation and design principles.

Try creating your own builder for another class and see how it transforms your code! Let me know your thoughts or share your implementation in the comments below.

Akshay Nandwana
Founder AndroidEngineers

You can connect with me on:


Book 1:1 Session here
Click Here

Join our upcoming classes
https://www.androidengineers.in/courses

Love from our past students

Excellent list of questions really helped me to coverup all the topics before interview.

Saiteja Janjirala

10th Oct, 2024

I had an exceptional experience with the 1:1 mentorship session. Akshay was incredibly friendly and provided invaluable guidance on focusing on long-term goals. They also gave great interview tips, including a thorough resume review. Additionally, the discussion on Data Structures and Algorithms (DSA) was insightful and practical. Highly recommended for anyone looking to advance their career!

Nayab khan

11th Sep, 2024

Cleared my major points for what I am missing in the resume and also suggested what I can work on for further growth in the career.

Ketan Chaurasiya

7th Aug, 2024

What impressed me most was his personalized approach and practical tips that I could immediately apply. Akshay’s guidance not only improved my technical skills but also boosted my confidence in navigating my career path. His insights and encouragement have been a game-changer for me. I highly recommend Akshay’s mentorship to anyone looking to advance their Android development career.

Hardik Kubavat

5th Aug, 2024

2025© Made with   by Android Engineers.