avatarEmanuel Trandafir

Summary

This article discusses the use of Lombok's @Builder annotation in Java and its advantages and drawbacks, suggesting an alternative approach using Lombok's fluent setters for a more straightforward implementation.

Abstract

Lombok is a Java library that generates boilerplate code, and its @Builder annotation implements the builder design pattern. However, configuring Lombok for specific scenarios can be complex due to its "invisible magic." The article demonstrates the difficulty of implementing a mandatory field and calculating the value of a field based on another mandatory field using @Builder. It then introduces Lombok's fluent setters as a more straightforward alternative, allowing chaining of setters and providing a cleaner, easier-to-understand implementation.

Bullet points

  • Lombok is a Java library that generates boilerplate code, including the builder design pattern using the @Builder annotation.
  • Configuring Lombok for specific scenarios can be complex and hard to understand.
  • Implementing a mandatory field and calculating the value of a field based on another mandatory field using @Builder is difficult.
  • Lombok's fluent setters provide a more straightforward alternative, allowing chaining of setters and a cleaner implementation.
  • Fluent setters return the instance itself after assigning a value, enabling the creation of a Student instance by providing the mandatory field for the constructor and then chaining other attributes.
  • The implementation using fluent setters is cleaner and easier to understand than using @Builder.
  • Lombok should be used responsibly, keeping implementations simple and easy to understand.

You Might Stop Using Lombok’s @Builder After Reading This

Photo by Tobias Wilden on Unsplash

1. Overview

Lombok is a Java library that can generate known patterns of code for us, allowing us to reduce the boilerplate code. For instance, we can leverage Lombok to generate all the getters and setters for a class.

In this article, we’ll discuss Lombok’s @Builder annotation, which implements the builder design pattern for us. We’ll see its advantages and some of the drawbacks it can bring.

After that, we’ll use Lombok’s configuration to achieve the same functionality in a more straightforward manner.

2. @Builder and Lombok’s Magic

Let’s start by looking into a simple use-case where the @Builder annotation can come in handy.

For the code examples in this article, we’ll use the Student data model:

Because our class is annotated with @Builder, we can instance a Student using syntax associated with the builder design pattern:

This feature is great for simple data classes with many fields. Though, if we need something more specific, things can get tricky really fast.

One of Lombok’s biggest complaints is the “invisible magic” it performs. In order to configure it for more specific scenarios, we first need to understand how Lombok works and what it generates.

3. Having a Mandatory Field

Let’s assume the firstName field is mandatory when instantiating a Student. This is a very simple and reasonable scenario.

One of the most recommended solutions to achieve this with Lombok is to:

  • annotate the field with lombok.NonNull
  • provide a different name for the method returning Lombok’s builder
  • manually implement the builder() method and invoke Lombok’s builder by passing the firstName

As a result, we can create the Student builder only if we provide the firstName:

We haven’t added a lot of extra code. Nonetheless, the result is a bit ambiguous and hard to understand, especially if you are not very familiar with Lombok.

But wait, it gets even worst…

Photo by Tim Mossholder on Unsplash

4. Calculate The Value of a Field Based On Another Mandatory Field

For this example, let’s assume we want to manually generate a studentId based on the mandatory firstName field.

Even though the requirement is not complex, the suggested implementation is very hard to understand.

  • we’ll need a private constructor with all the fields, except the one that is calculated.
  • we’ll annotate set all the fields here and calculate the studentId
  • then, we’ll annotate this with @Builder and give it a custom name, following the steps from section 3 (to ensure firstName is NonNull)

We can think of other scenarios, such as adding inheritance, default values... But I believe this is already too much. We’ve got the point, we need a different solution.

Photo by Ryan Snaadt on Unsplash

5. Lombok’s Fluent Setters

We can configure Lombok to allow chaining the setters. This simply means the setters will return the instance itself after assigning a value.

This will allow us to build a Student instance using this syntax:

Student student = new Student().setFirstName("John").setYear(2);

Furthermore, Lombok allows us to rename the setters, to get a more fluent API for building the object:

Student student = new Student().firstName("John").lastName("Doe");

We can configure these properties at a class level, using the @Accessors annotation. Let’s use this approach for the scenario described in the previous section:

We are now exposing the fluent setters. As a result, we can now create a Student instance by providing the mandatory field for the constructor and then chain the other attributes:

Student student = new Student("John").lastName("Doe").year(2);

6. Conclusion

If we compare the two implementations, we can all agree that the one with fluent setters is much cleaner and easier to understand.

This is mostly because we are using Lombok to generate some simple setters instead of using it to implement the builder design pattern.

Consequently, it’s easier to visualize the code that is being generated and understand what Lombok is doing.

If you want to read more about Lombok, I recommend you this article about best practices when it comes to Lombok and JPA entities encapsulation.

In my opinion, Lombok is a great tool, but it has to be used responsibly. When using it, try to Keep It Stupid Simple! :)

Photo by Tim Mossholder on Unsplash

Thank You!

Thanks for reading the article and please let me know what you think! Any feedback is welcome.

If you want to read more about clean code, design, unit testing, functional programming, and many others, make sure to check out my other articles.

If you like my content, consider following or subscribing to the email list.

Finally, if you consider becoming a Medium member and supporting my blog, here’s my referral.

Happy Coding!

Java
Software Development
Software Engineering
Spring Boot
Programming
Recommended from ReadMedium