생성자와 수정자로 구현된 다음과 같은 User 클래스를 바탕으로
왜 생성자나 수정자보다 Builder를 사용해야하는지 이해해보도록 하자
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
private int height;
private int iq;
}
- 필요한 데이터만 설정할 수 있음
- 유연성을 확보할 수 있음
- 가독성을 높일 수 있음
- 불변셩을 확보할 수 있음
User user = User.builder()
.name("배털")
.height(185)
.iq(150)
.build();
예를 들어 User객체를 생성해야하는데 age라는 파라미터가 필요없는 상황이라고 가정하자.
생성자나 정적 메소드를 이용하는 경우라면 우리는 age에 더미 값을 넣어주거나 age가 없는 생성자를 새로 만들어주어야한다.
이렇게 필요한 데이터만 설정할 수 있는 빌더의 장점은 생성자 또는 정적 메소드와 비교하여 테스트용 객체를 생성할 때 용이하게 해주고, 불필요한 코드의 양을 줄이는 등의 이점을 안겨준다.
예를 들어 User클래스에 몸무게를 나타내는 새로운 변수
weight
를 추가해야한다고 하자.
하지만 이미 다음과 같이 생성자로 객체를 만드는 코드가 있다고 하자.
// ASIS
User user = new User("망나니개발자", 28, 180, 150)
// TOBE
User user = new User("망나니개발자", 28, 180, 150, 75)
그러면 우리는 새롭게 추가되는 변수 때문에 기존의 코드를 수정해야 하는 상황에 직면하게 된다.
기존에 작성된 코드의 양이 방대하다면 감당하기 어려울 수 있다.
하지만 빌더 패턴을 이용하면 새로운 변수가 추가되는 등의 상황에 직면하여도 기존의 코드에 영향을 주지 않을 수 있다.
만약 위와 같이 User 객체를 생성하는 코드가 100개 있다면 모든 로직을 수정해주거나 생성자를 따로 추가하는 등의 불필요한 조치를 해주어야 할 것이다.
하지만 빌더 패턴를 기반으로 코드가 작성되어 있다면 기존의 코드는 수정할 필요가 없다.
왜냐하면 빌더 패턴은 유연하게 객체의 값을 설정할 수 있도록 도와주기 때문이다.
빌더패턴을 사용하면 매개변수가 많아져도 가독성을 높일 수 있다.
생성자로 객체를 생성하는 경우에는 매개변수가 많이질수록 코드 리딩이 급격하게 떨어진다.
많은 개발자들이 수정자 패턴(Setter)를 흔히 사용한다.
하지만 Setter를 구현한다는 것은 불필요하게 확장 가능성을 열어두는 것이다.
이는 Open-Closed 법칙
에 위배되고, 불필요한 코드 리딩 등을 유발한다.
그렇기 때문에 클래스 변수를 final
로 선언하고 객체의 생성은 빌더에게 맡기는 것이 좋다
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
private final String name;
private final int age;
private final int height;
private final int iq;
}
그렇게 되면 위의 User 클래스를 다음과 같이 수정할 수 있다.
다른 사람과 협업을 하거나 변경에 대한 요구 사항이 많은 경우라면 빌더패턴을 사용해야 하는 이유를 더욱 극명하게 느낄 수 있을 것이다.