필요한 객체를 생성한 후, Setter
메서드를 통해, 생성한 객체의 필드를 할당하는 방식이다.
User user = new User();
user.setName("kim");
user.setAge(23);
Setter
메서드 마다, 어떤 속성을 정의하는지 명확하다. set + 필드
(이는 곧, 코드의 가독성을 높인다.)Setter
는 객체의 속성을 직접적으로 변경하는 메서드이므로, 예상치 못한 Setter
메서드 호출로 인해 객체의 불변성을 보장하기 어렵다. 흔히 객체의 불변성을 위해, final
을 적용하기도 하는데, Setter
메서드는 final
과 함께 사용하는 경우 오류가 발생한다.불변 객체 : 한 번 생성된 후 내부 상태를 변경할 수 없는 객체. 객체가 변경할 수 없다는 것이 정해져 있으므로, 예측이 가능하고 안정적이기 때문에, 코드의 복잡성을 줄이고, 버그를 방지할 수 있다는 장점이 있다.
Setter
메서드를 통해 필드에 대한 값을 할당하기 때문에, 객체가 생성된 시점에서는 일관성을 유지했다고 보기 어렵다. 하물며, 만약 개발자가 반드시 적용해야 하는 Setter
메서드 호출을 깜빡하는 경우에는, 자칫 큰 문제로 이어질 수 있다.컴파일 단계에서 해당 오류를 잡아주지 않으며, 런타임 환경에서 나타나더라도 원인이 무엇인지 파악하기 어렵다.
JPA
엔티티의 경우 Setter
메서드 사용을 지양하는데, 값을 생성하는 것인지, 변경하는지 의도를 파악하기 어려우며, Setter
메서드는 기본적으로 public
으로 적용되기 때문에, 의도치 않게 속성 값을 변경할 수 있기 때문이다.생성자를 활용하여, 객체 생성 시 필드를 바로 할당하는 방식이다.
User user = new User("kim", 23);
Setter
기반 객체 생성과는 다르게, 객체를 생성하는 순간 필드의 값을 할당하기 때문에 생성 시점에서 이미 객체의 일관성을 유지한다.객체를 생성하는 디자인 패턴 중 하나로, 클래스의 일관성을 유지하면서도 필드별 유연한 객체 생성이 가능하여, 실무 협업에서 흔히 사용하는 패턴이다.
내부에 Builder
라는 새로운 static
클래스를 생성한 후, 필드에 필요한 값을 할당할 때 마다 객체 자기 자신을 반환하여, 체이닝을 이루는 것이 빌더 패턴의 특징이라고 할 수 있다.
class User {
private String name;
private int age;
static public class Builder {
private String name;
private int age;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public User build() {
return new User(name,age);
}
}
}
User user = new User.Builder()
.name("kim")
.age(23)
.build();
빌더 패턴을 활용하면, 각 데이터가 어떤 목적으로 활용되는지 한 눈에 알 수 있고, 객체를 생성할 때를 제외하고는 필드에 대한 업데이트를 원천 봉쇄하기 때문에 불변 객체를 유지할 수 있다. 그리고, 생성하는 객체별로 필요한 값만 설정할 수 있는 유연한 특성을 지니며, build()
를 호출해야만 Builder
클래스에서 해당 객체가 생성되는 것이므로, 클래스의 일관성을 지킬 수 있다.
빌더 패턴은 생성자 기반 객체 생성과 Setter
기반 객체 생성의 장점을 모두 살린 유용한 디자인 패턴이지만, 클래스별로 Builder
클래스를 반복적으로 생성하는데는 불편함이 있다.
이를 해결할 방법으로 Lombok
의 @Builder
를 클래스에 적용시키면, 주어진 클래스의 필드를 기반으로 빌더 패턴을 자동으로 생성한다.
@Builder
를 사용하면 불변성을 유지하기 용이하나, 필드에 final
키워드까지 자동으로 적용해주지는 않는다.builderMethodName
설정을 통해 이름을 변경하는 것이 가능하다.참고
디자인패턴 빌더 - 곽동운 | 백엔드 데브코스 2기 | 백둥이Deview 220406
[JPA] Entitiy에서 왜 Setter를 사용하지 말라고 할까?
💠 빌더(Builder) 패턴 - 완벽 마스터하기