Builder 어노테이션 왜 궁금했을까 ❓
- Spring boot 교재에서 Builder를 사용하고 Error Handling을 하기 위해 다른 사람들이 게시글을 참고하는 과정에서 대부분 Builder Annotiation을 사용하는 것을 발견했다.
- 생성자가 존재함에도 불구하고 Builder Annotation을 쓰는 이유가 궁금했고 알아보려고 한다.
@Builder Annotation
@Builder Annotation은 lombok 라이브러리에서 지원하며 Builder Pattern으로 객체를 생성해주는 Annotation
- 객체를 생성하는 여러 가지 방법에 대해서 알아보고 @Builder와 비교해보겠다.
생성자를 이용한 객체 생성
public class Chanhong {
private final String name;
private final boolean sex;
private final double weight;
private final double height;
public Chanhong(String name, boolean sex, double weight, double height) {
this.name = name;
this.sex = sex;
this.weight = weight;
this.height = height;
}
}
Chanhong test = new Chanhong("박찬홍", false, 79.1, 176.2);
- 생성자를 이용할 경우 매개변수의 순서가 중요해지며 모든 데이터가 생성자에 맞게 전달되어야 한다.
- 매개변수가 달라지면 이에 맞는 생성자를 모두 생성해줘야 하므로 번거롭다.
Setter를 이용한 객체 생성
public class Chanhong {
private final String name;
private final boolean sex;
private final double weight;
private final double height;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public boolean getSex() {
return sex;
}
public void setWeight(double weight) {
this.weight = weight;
}
public double getWeight() {
return weight;
}
public void setHeight(double height) {
this.height = height;
}
public double getHeight() {
return height;
}
}
Chanhong test = new Chanhong();
test.setName("박찬홍");
test.setSex(false);
test.setWeight(79.1);
test.setHeight(176.2);
- 객체 생성 시 인자를 전달할 필요가 없고 순서 또한 중요하지 않게 되어 여러 개의 생성자를 만들 필요가 없어진다.
- 하지만, Setter와 Getter를 생성해야 하고 Setter를 지속적으로 호출이 가능하여 데이터의 불변성을 보장할 수 없다.
Builder Pattern을 활용한 객체 생성
public class Chanhong {
private final String name;
private final boolean sex;
private final double weight;
private final double height;
public Chanhong(Builder builder) {
this.name = builder.name;
this.sex = builder.sex;
this.weight = builder.weight;
this.height = builder.height;
}
public static class Builder {
private final String name;
private final boolean sex;
private final double weight;
private final double height;
public Builder name(String name){
this.name = name;
return this;
}
public Builder sex(int sex){
this.sex = sex;
return this;
}
public Builder weight(double weight){
this.weight = weight;
return this;
}
public Builder height(double height){
this.height = height;
return this;
}
public Chanhong build(){
return new Chanhong(this);
}
}
}
Chanhong test = new Chanhong.Builder()
.name("박찬홍")
.sex(false)
.weight(79.1)
.height(176.2).build();
- Builder Pattern을 통해 다른 객체 생성 방식들의 단점을 보완할 수 있다.
lombok 라이브러리를 활용한 Builder의 객체 생성
@Builder
public class Chanhong {
private final String name;
private final boolean sex;
private final double weight;
private final double height;
}
Chanhong test = new Chanhong.Builder().name("박찬홍")
.sex(false)
.weight(79.1)
.height(176.2).build();
- lombok의 builder annotation을 사용하게 되면 직접 내장 class인 builder와 생성자를 작성할 필요가 없어진다.