프로젝트/아카이뷰

[Spring boot] @Builder 어노테이션

cks._.hong 2024. 1. 5. 10:56

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와 생성자를 작성할 필요가 없어진다.