Automatic Refactoring to Builder Pattern in Java

KonfHub
2 min readOct 19, 2019

Large constructors suck! With IntelliJ IDEA, you can automagically refactor the large constructor to a builder.

Here is an example. Consider this Device class:

class Device {
private UUID deviceId;
private String name;
private boolean status;
private LocalDateTime startDateTime;
private double generatedPower;

public Device(UUID deviceId, String name, boolean status,
LocalDateTime startDateTime, double generatedPower) {
this.deviceId = deviceId;
this.name = name;
this.status = status;
this.startDateTime = startDateTime;
this.generatedPower = generatedPower;
}

@Override
public String toString() {
return "Device{" +
"deviceId=" + deviceId +
", name='" + name + '\'' +
", status=" + status +
", startDateTime=" + startDateTime +
", generatedPower=" + generatedPower +
'}';
}
}

There are five fields and that makes the constructor parameter list long. When you create an object, the problem is obvious:

var device = new Device(UUID.randomUUID(), "FSF11", false, LocalDateTime.now(), 0);

We are already lost with what is false here and what is 0!

Fortunately, refactoring it is quite easy — what you need to do is select Refactor and Select the option to convert the constructor to a Builder class.

This results in this code:

import java.time.LocalDateTime;
import java.util.UUID;

public class DeviceBuilder {
private UUID deviceId;
private String name;
private boolean status;
private LocalDateTime startDateTime;
private double generatedPower;

public DeviceBuilder setDeviceId(UUID deviceId) {
this.deviceId = deviceId;
return this;
}

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

public DeviceBuilder setStatus(boolean status) {
this.status = status;
return this;
}

public DeviceBuilder setStartDateTime(LocalDateTime startDateTime) {
this.startDateTime = startDateTime;
return this;
}

public DeviceBuilder setGeneratedPower(double generatedPower) {
this.generatedPower = generatedPower;
return this;
}

public Device createDevice() {
return new Device(deviceId, name, status, startDateTime, generatedPower);
}
}

Now you go back and check your code that was creating a Device object using constructor, it would be automagically converted to using the DeviceBuilder class!

var device = new DeviceBuilder().setDeviceId(UUID.randomUUID())
.setName("FSF11")
.setStatus(false)
.setStartDateTime(LocalDateTime.now())
.setGeneratedPower(0)
.createDevice();

That’s much more readable and better, isn’t it?!

You can check this YouTube video that shows this refactoring visually here: https://youtu.be/fmoS15bnwBk

--

--

KonfHub

KonfHub is the one-stop platform to create and host tech events. Create the event in under 30 seconds, gamify & amplify for audience engagement!