"Builder Pattern" generator for Java
Tags: java, designpattern, tool
Published: 2019-08-01 01:32:24

---
title: "Builder Pattern" generator for Java
published: true
description: Introduce Java Builder Pattern Generator
tags: java,design pattern,tool
---

# **Introduction**
I want to introduce my web app that can generate "Builder Pattern" source code for Java.
With this tool, you can instantly generate Builder patterns: "Effective Java", "GoF", "Telescoping Constructor", "Lombok", "Mandatory Properties"

https://riversun.github.io/java-builder/

(Made only with HTML / CSS / JS , no server side)

As shown below, if you enter "[Type] [Variable]" in Definition, the generated code will be reflected in real time on the right.

![animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170905/4291ed54-28db-52ff-0efb-26e27e62d684.gif)

When you have finished entering the code, press Copy to Clipboard to copy the code and paste it into your IDE or editor.


# **Example of generated code**

## **Definition**

Just type like as follows and you can get full source code of Builder pattern.

```text
package com.example
class Person
@Required String name
@Required Integer age
@Required String gender
@Required Integer height
String eyeColor
String hairColor
String hobby
```

When **@NotNull** annotation is added to the beginning of the variable definition, it becomes a **Required** parameter and generates a code to check null when building.


## **Generated code example "Effective Java"**

**Person.java**

```java
package com.example;

public class Person {

  private String name;
  private Integer age;
  private String gender;
  private Integer height;
  private String eyeColor;
  private String hairColor;
  private String hobby;

  public static class Builder {
    
    private String name;
    private Integer age;
    private String gender;
    private Integer height;
    private String eyeColor;
    private String hairColor;
    private String hobby;

    public Builder() {    
    }
      
    Builder(String name, Integer age, String gender, Integer height, String eyeColor, String hairColor, String hobby) {    
      this.name = name; 
      this.age = age; 
      this.gender = gender; 
      this.height = height; 
      this.eyeColor = eyeColor; 
      this.hairColor = hairColor; 
      this.hobby = hobby;             
    }
        
    public Builder name(String name){
      this.name = name;
      return Builder.this;
    }

    public Builder age(Integer age){
      this.age = age;
      return Builder.this;
    }

    public Builder gender(String gender){
      this.gender = gender;
      return Builder.this;
    }

    public Builder height(Integer height){
      this.height = height;
      return Builder.this;
    }

    public Builder eyeColor(String eyeColor){
      this.eyeColor = eyeColor;
      return Builder.this;
    }

    public Builder hairColor(String hairColor){
      this.hairColor = hairColor;
      return Builder.this;
    }

    public Builder hobby(String hobby){
      this.hobby = hobby;
      return Builder.this;
    }

    public Person build() {
        if(this.name == null){
          throw new NullPointerException("The property \"name\" is null. "
              + "Please set the value by \"name()\". "
              + "The properties \"name\", \"age\", \"gender\" and \"height\" are required.");
        }
        if(this.age == null){
          throw new NullPointerException("The property \"age\" is null. "
              + "Please set the value by \"age()\". "
              + "The properties \"name\", \"age\", \"gender\" and \"height\" are required.");
        }
        if(this.gender == null){
          throw new NullPointerException("The property \"gender\" is null. "
              + "Please set the value by \"gender()\". "
              + "The properties \"name\", \"age\", \"gender\" and \"height\" are required.");
        }
        if(this.height == null){
          throw new NullPointerException("The property \"height\" is null. "
              + "Please set the value by \"height()\". "
              + "The properties \"name\", \"age\", \"gender\" and \"height\" are required.");
        }

        return new Person(this);
    }
  }

  private Person(Builder builder) {
    this.name = builder.name; 
    this.age = builder.age; 
    this.gender = builder.gender; 
    this.height = builder.height; 
    this.eyeColor = builder.eyeColor; 
    this.hairColor = builder.hairColor; 
    this.hobby = builder.hobby;     
  }

  public void doSomething() {
      // do something
  }
}

```

You you want to use this builder cod,
just write like this.

**AppMain.java**

```java
public static void main(String[] args) {
        new Person.Builder().name("riversun").age(12).gender("male").height(200).build().doSomething();

    }
```


## **Generated code example of "GoF"**

**Person.java**

```java
package org.example;
import java.util.ArrayList;
import java.util.List;

public class Person {

  private String name;
  private int age;
  private String sex;
  private List<String> hobby = new ArrayList<String>();

  public Person() {

  }

  public Person(String name, int age, String sex, List<String> hobby) {
    this.name = name; 
    this.age = age; 
    this.sex = sex; 
    this.hobby = hobby; 
  }

  public Person setName(String name){
    this.name = name;
    return Person.this;
  }

  public String getName(){
    return this.name;
  }

  public Person setAge(int age){
    this.age = age;
    return Person.this;
  }

  public int getAge(){
    return this.age;
  }

  public Person setSex(String sex){
    this.sex = sex;
    return Person.this;
  }

  public String getSex(){
    return this.sex;
  }

  public Person setHobby(List<String> hobby){
    this.hobby = hobby;
    return Person.this;
  }

  public Person addHobby(String hobby){
    this.hobby.add(hobby);
    return Person.this;
  }

  public List<String> getHobby(){
    return this.hobby;
  }

  public void doSomething(){
    System.out.println("Person's properties");
    System.out.println("name="+name);
    System.out.println("age="+age);
    System.out.println("sex="+sex);
    System.out.println("hobby="+hobby);  
  }
}
```

**Builder.java**

```java
package org.example;
import java.util.List;

public interface Builder {

  public void name(String name);
  public void age(int age);
  public void sex(String sex);
  public void hobby(List<String> hobby);

  Person getResult();
}
```

**PersonBuilder.java**

```java
package org.example;
import java.util.List;

public class PersonBuilder implements Builder {
  private Person person;

  public PersonBuilder() {
    this.person = new Person();
  }

  @Override
  public void name(String name) {
    this.person.setName(name);
  }

  @Override
  public void age(int age) {
    this.person.setAge(age);
  }

  @Override
  public void sex(String sex) {
    this.person.setSex(sex);
  }

  @Override
  public void hobby(List<String> hobby) {
    this.person.setHobby(hobby);
  }


  @Override
  public Person getResult() {
  
    if(this.person.getName() == null){
      throw new NullPointerException("The property \"name\" is null. "
          + "Please set the value by \"builder.name()\" at Director class. "
          + "The property \"name\" is required.");
    }

    return this.person;
  }
}

```

**Director.java**

```java
package org.example;

public class Director {

  private Builder builder;

  public Director(Builder builder) {
    this.builder = builder;
  }

  public void construct() {
    builder.name("something"); // required property
    builder.age(0); // optional property
    builder.sex("something"); // optional property
    //builder.hobby(new ArrayList<>());
  }
}
```

**AppMain.java**

```java
package org.example;

public class AppMain {
  
  public static void main(String[] args) {
    
    Builder builder = new PersonBuilder();
    Director director = new Director(builder);
    director.construct();
    Person person = builder.getResult();
    person.doSomething();
    
  }
}
```

## **Generated source code of "Telescoping Constructor"**

**Person.java**

```java
package org.example;
import java.util.ArrayList;
import java.util.List;

public class Person {

  private String name;
  private int age;
  private String sex;
  private List<String> hobby = new ArrayList<String>();

  public Person() {

  }

  public Person(String name, int age, String sex, List<String> hobby) {
    this.name = name; 
    this.age = age; 
    this.sex = sex; 
    this.hobby = hobby; 
  }

  public Person setName(String name) {
    this.name = name;
    return Person.this;
  }

  public String getName() {
    return this.name;
  }

  public Person setAge(int age) {
    this.age = age;
    return Person.this;
  }

  public int getAge() {
    return this.age;
  }

  public Person setSex(String sex) {
    this.sex = sex;
    return Person.this;
  }

  public String getSex() {
    return this.sex;
  }

  public Person setHobby(List<String> hobby) {
    this.hobby = hobby;
    return Person.this;
  }

  public Person addHobby(String hobby){
    this.hobby.add(hobby);
    return Person.this;
  }

  public List<String> getHobby() {
    return this.hobby;
  }

}

```

## **Generated source code of "Lombok"**

**Person.java**

```java
package org.example;
import java.util.ArrayList;
import java.util.List;

public class Person {

  private String name;
  private int age;
  private String sex;
  private List<String> hobby;

  Person(String name, int age, String sex, List<String> hobby) {
  
    if(name == null){
      throw new NullPointerException("The property \"name\" is null. "
          + "Please set the value by \"name()\". "
          + "The property \"name\" is required.");
    }

    this.name = name; 
    this.age = age; 
    this.sex = sex; 
    this.hobby = hobby; 
  }
  
  public static PersonBuilder builder(){
    return new PersonBuilder();
  }  
  public static class PersonBuilder {
    
    private String name;
    private int age;
    private String sex;
    private List<String> hobby = new ArrayList<String>();

    PersonBuilder() {    
    }
      
    public PersonBuilder name(String name){
      this.name = name;
      return PersonBuilder.this;
    }

    public PersonBuilder age(int age){
      this.age = age;
      return PersonBuilder.this;
    }

    public PersonBuilder sex(String sex){
      this.sex = sex;
      return PersonBuilder.this;
    }

    public PersonBuilder hobby(List<String> hobby){
      this.hobby = hobby;
      return PersonBuilder.this;
    }

    public PersonBuilder addHobby(String hobby){
      this.hobby.add(hobby);
      return PersonBuilder.this;
    }

    public Person build() {
      return new Person(this.name, this.age, this.sex, this.hobby);
    }
    @Override
    public String toString() {
      return "Person.PersonBuilder(name=" + this.name + ", age=" + this.age + ", sex=" + this.sex + ", hobby=" + this.hobby + ")";
    }
  }
  
  @Override
  public String toString() {
    return "Person(name=" + this.name + ", age=" + this.age + ", sex=" + this.sex + ", hobby=" + this.hobby + ")";
  }
  
  public void doSomething() {
      // do something
  }
}
```

You you want to use this builder cod,
just write like this.

**AppMain.java**

```java
public class AppMain {
    public static void main(String[] args) {
        System.out.println(Person.builder().name("Tom").age(12).sex("male").build());
    }
}
```

## Generated source code of "Mandatory Properties"

It is a Builder pattern that can set mandatory properties in the correct order.

**Person.java**

```
package com.example;
import java.util.Optional;

public class Person {

  private final String name;// Required
  private final Integer age;// Required
  private final String gender;// Required
  private final Integer height;// Required
  private final Optional<String> eyeColor;// Optional(use Optional<String>)
  private final Optional<String> hairColor;// Optional(use Optional<String>)
  private final Optional<String> hobby;// Optional(use Optional<String>)

  Person(Builder.Builder1 builder) {
    this.name = builder.name; 
    this.age = builder.age; 
    this.gender = builder.gender; 
    this.height = builder.height; 
    this.eyeColor = builder.eyeColor; 
    this.hairColor = builder.hairColor; 
    this.hobby = builder.hobby; 
  }
  public static Builder builder() {
    return new Builder();
  }

  public static final class Builder {
    public Builder1 name(String name) {
      return new Builder1(name);
    }
    public static final class Builder1 {
      final String name;
      Integer age;
      String gender;
      Integer height;
      Optional<String> eyeColor;
      Optional<String> hairColor;
      Optional<String> hobby;

      private Builder1(String name) {
        this.name = name;
      }
      public Builder2 age(Integer age) {
        this.age = age;
        return new Builder2(Builder1.this);
      }
    }
    public static final class Builder2 {
      final Builder1 builder;

      private Builder2(Builder1 builder) {
        this.builder = builder;
      }
      public Builder3 gender(String gender) {
        this.builder.gender = gender;
        return new Builder3(this.builder);
      }
    }
    public static final class Builder3 {
      final Builder1 builder;

      private Builder3(Builder1 builder) {
        this.builder = builder;
      }
      public Builder4 height(Integer height) {
        this.builder.height = height;
        return new Builder4(this.builder);
      }
    }
    public static final class Builder4 {
      final Builder1 builder;

      private Builder4(Builder1 builder) {
        this.builder = builder;
      }
      public Builder4 eyeColor(String eyeColor){
        this.builder.eyeColor = Optional.of(eyeColor);
        return this;
      }
      public Builder4 hairColor(String hairColor){
        this.builder.hairColor = Optional.of(hairColor);
        return this;
      }
      public Builder4 hobby(String hobby){
        this.builder.hobby = Optional.of(hobby);
        return this;
      }
      public Person build() {
        return new Person(this.builder);
      }
    }
  }

  public String name() {
    return this.name;
  }
  public Integer age() {
    return this.age;
  }
  public String gender() {
    return this.gender;
  }
  public Integer height() {
    return this.height;
  }
  public Optional<String> eyeColor() {
    return this.eyeColor;
  }
  public Optional<String> hairColor() {
    return this.hairColor;
  }
  public Optional<String> hobby() {
    return this.hobby;
  }

  @Override
  public String toString() {
    return "Person(name=" + this.name + ", age=" + this.age + ", gender=" + this.gender + ", height=" + this.height + ", eyeColor=" + this.eyeColor + ", hairColor=" + this.hairColor + ", hobby=" + this.hobby + ")";
  }
  
  public void doSomething() {
      // do something
  }
}

```


## **Generator Tips**

The following ideas have been put in place with the aim of typical code output where the generated code can be used as is as possible without setting the details.

### **Effective Java Template**

- For type of **List<>** like as ``List<String> hobby;``, generate code initialized with ``new ArrayList();``
- Also, in the case of ``List``, generate a method like ``addHobby(String hobby)`` so that items can be added individually.

### **GoF Template**
- GoF's Builder pattern is more complicated than other patterns in construction, generate main class named ``AppMain.java``.
- Added temporary code to ``construct()`` method of **Director.java**.

```java
public void construct() {
    builder.name("something");
    builder.age(0);
    builder.sex("something");
    //builder.hobby(new ArrayList<>());
  }
```

I hope it helps.