3 minute read

Overview

@Builder

  • Builder pattern is used to build the object step-by-step and provide a method that will actually return the final Object.

    What is the use of @builder in spring boot?

  • Lombok’s @Builder is a helpful mechanism for using the Builder pattern without writing boilerplate code. We can apply this annotation to a Class or a constructor or a method.
  • Lombok creates a builder class containing only the constructor parameters.
  • @Builder needs an @AllArgsConstructor

class level Builder

Employee class

@Data @AllArgsConstructor @NoArgsConstructor @ToString @Builder
public class Employee{
private String name;
private int age;
}

EmployeeData class

public class EmployeeData{
public static void main(String[] args){
    Employee
    .builder()
    .name("deepthi")
    .age(24)
    .build();
    
    Employee e = Employee
    .builder()
    .build()
    System.out.println(e.getName() + " " + e.getAge())
    }
}
  • e gives result as null 0 which are the default values of String anf integer since we did not provide any values to the name and age constructor.

Constructor level Builder

Chocolate class

@Data @AllArgsConstructor @NoArgsConstructor @ToString @Builder
public class Chocolate{
private String name;
private Double price;
private Boolean isAvailable;

// creating constructor for class Chocolate for name and price variables
@Builder
public Chocolate(String name, Double price){
this.name = name;
this.price = price;
}
}

ChocolateData class

public class ChocolateData{
public static void main(String[] args){
   Chocolate c = Chocolate
    .builder()
    .name("Kitkat")
    .price(10.0)
    .build();
   
    System.out.println(c.getName() + " " + c.getPrice() + " " + c.getIsAvailable())
    }
}
  • c gives result as Kitkat 10 false.
  • since the constructor is not created for boolean isAvailable variable it gave result as false as it is the default value of boolean.
  • we can restrict the builder using constructors.

Method level Builder

Books class

@Data @AllArgsConstructor @NoArgsConstructor @ToString @Builder
public class Books{
private String author;
private Integer pages;
private Boolean isAvailable;

// creating constructor for class Books for author, pages and isAvailable variables
public Books(String author, Integer pages, Boolean isAvailable){
this.author = author;
this.pages = pages;
this.isAvailable = isAvailable;
}

// creating a  instance method BooksInstance(object of this class)
@Builder
private static Books BooksInstance(String author, Integer pages){
  return new Books(author, pages, true); // creating object of Books class
}

BooksData class

public class BooksData{
public static void main(String[] args){
   Books c = Books
    .builder()
    .author("Dr Joseph Murphy")
    .pages(270)
    .build();
   
    System.out.println(c.getAuthor() + " " + c.getPages() + " " + c.getIsAvailable())
    }
}
  • Since builder is applied at the method level we dont have to call the method explicitly. builder calls the method.
  • The result will be Dr Joseph Murphy 270 true. isAvailable is true since it is declared as true statically.

Example: CodeSample

@Data @AllArgsConstructor @NoArgsConstructor @ToString @Builder
public class FluidBloodPressure{
private List<Sections> sections;
}
@Data @AllArgsConstructor @NoArgsConstructor @ToString @Builder
public Sections{
private String patient;
private List<Treatment> treatment;
}
public Interface report{
getReport(fluidBloodPressure);
}
private Interface getReport(FluidBloodPressure fluidBloodPressure){
    FluidBloodPressure fbp = FluidBloodPressure
    .builder()
    .sections(fluidBloodPressure.getSections()
    .stream()
    .map(listItem -> FluidBloodPressure.builder()
    .patient(listItem.getPatient())
    .treatment(listItem.getTreatment())
    .build())
    .collect(Collections.toList()))
    .build();
return fbp;
}

@Builder.Default

  • We can set default values to the fields By using @Builder.Default using Builder in the lombok builder design pattern.

Without @Builder.Default

@ToString @Data @AllArgsConstructor @NoArgsConstructor
@Builder
public class BuilderWithoutDefaultValue{
  private Long id;
  private String name = "Deepthi";
  private Boolean merit;
}
public class Test{
public static void main (String[] args){
    BuilderWithoutDefaultValue result = BuilderWithoutDefaultValue.builder().build();
    System.out.println(result);
  }
}
  • The result will be as null null false as null is default value of Long, String and false is default value of boolean

With @Builder.Default

@ToString @Data @AllArgsConstructor @NoArgsConstructor
@Builder
public class BuilderWithDefaultValue{
  private Long id;
  @Default
  private String name = "Deepthi";
  @Builder.Default
  private Boolean merit = true;
}
public class Test{
public static void main (String[] args){
    BuilderWithDefaultValue result = BuilderWithDefaultValue.builder().build();
    System.out.println(result);
  }
}
  • The result will be as null Deepthi true.
  • @Builder.Default can be used at field level as shown in above example.

Advantages of Builder Design Pattern

  • 1) The parameters to the constructor are reduced and are provided in highly readable method calls.
  • 2) Builder design pattern also helps in minimizing the number of parameters in the constructor and thus there is no need to pass in null for optional parameters to the constructor.
  • 3) Object is always instantiated in a complete state
  • 4) Immutable objects can be built without much complex logic in the object building process.

Disadvantages of Builder Design Pattern

  • 1) The number of lines of code increases at least to double in builder pattern, but the effort pays off in terms of design flexibility and much more readable code.
  • 2) Requires creating a separate ConcreteBuilder for each different type of Product.