Spring
빌더 패턴(Builder Pattern) / 빌더 어노테이션(@Builder)
kyungeeee
2022. 11. 23. 23:16
" 복합 객체의 생성 과정과 표현 방법을 분리하고 동일한 프로세스를 거쳐 다양한 구성의 인스턴스를 만드는 방법 "
- 생성과 관련된 디자인 패턴 👉 빌더 패턴(Builder Pattern)
- 복잡한 인스턴스를 조립하여 만드는 구조
- 복잡한 것을 만들 때는 전체를 한번에 만드는것 보다 작게 분리하여 만든 후 조립하여 합치는 것이 편리
- 객체를 생성하는 과정 / 객체를 구현하는 방법 이 2가지로 분리
📌 빌더 패턴의 장점
- 인스턴스 생성 시 인자를 선택적으로 가독성 좋게 넘길 수 있음
- 필요한 데이터만 넘길 수 있음
- 인자의 순서가 상관 없음
- 불필요한 생성자를 만들지 않음
- 유연성을 확보할 수 있음
- 불변성을 확보할 수 있음
📌 Builder 사용
" 생성자의 매개변수가 많은 경우 @Builder를 사용해 볼 수 있다. "
1) 매개변수가 있는 생성자 사용
👀 문제 발견!
매개변수를 넘길 때 순서에 맞게 값을 넘겨줘야하고, 불필요한 필드가 있더라도 꼭 넘겨줘야한다.
보통 기본값인 '0'이나 'null'로 넘겨주긴 하는데 이렇게 되면 어떤 필드가 필요한건지 불필요한건지 알기 어렵다.
즉, 가독성이 매우 떨어지게 된다.
public class SupperMarket {
private int milk;
private int apple;
private int ice;
private int water;
public SupperMarket(int milk, int apple, int ice, int water) {
this.milk = milk;
this.apple = apple;
this.ice = ice;
this.water = water;
}
public static void main(String[] args) {
SupperMarket sm = new SupperMarket(2,3,5,6);
}
}
2) 매개변수가 없는 생성자에 Setter를 사용
👀 문제 발견!
코드가 길어지고, 최종적인 인스턴스를 만들기까지 여러번의 호출을 거쳐야 되기 때문에 자바빈이 중간에 사용되는 경우 안정적이지 않은 상태로 사용될 여지가 있음
public class SupperMarket {
private int milk;
private int apple;
private int ice;
private int water;
public void setMilk(int milk) {
this.milk = milk;
}
public void setApple(int apple) {
this.apple = apple;
}
public void setIce(int ice) {
this.ice = ice;
}
public void setWater(int water) {
this.water = water;
}
public static void main(String[] args) {
SupperMarket sm = new SupperMarket();
sm.setMilk(2);
sm.setApple(3);
sm.setIce(5);
sm.setWater(6);
}
}
3) 빌더 사용
- 생성자, Setter 사용 시 장점을 모두 취할 수 있음
- 생성자의 '신축성', 자바빈에서의 '가독성'
- 필요한 객체를 직접 생성하는 대신, 먼저 필수적인 인자들을 생성자에 전부 전달하여 빌더 객체를 만든다.
그리고 선택 인자들은 가독성이 좋은 코드로 인자를 넘길 수 있다.
Setter가 없으므로 객체 일관성을 유지하여 불변 객체로 생성할 수 있다.
@Builder 어노테이션
- Lombok 기능 중 하나로 자동으로 해당 클래스에 빌더를 추가
- @AllargsConstructor, @NoArgsConstructor 어노테이션과 함께 사용
- 넘겨야할 인자 값이 많은 경우 생성자 대신 사용
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Board {
private Long id;
private String title;
private String userName;
private String content;
Board board = Board.builder()
.id(this.id)
.title(this.title)
.userName(this.userName)
.content(this.content)
.build();
}