on
[Effective Java 요약] 객체 생성과 파괴 - 2. 생성자에 매개변수가...
[Effective Java 요약] 객체 생성과 파괴 - 2. 생성자에 매개변수가...
2. 생성자에 매개변수가 많다면 빌더를 고려하라.
정적 팩토리와 생성자에는 똑같은 제약이 하나 있다. 선택적 매개변수가 많을 때 적절히 대응하기 어렵다는 점이다.
점층적 생성자 패턴(Telescoping Constructor Pattern)
public class Member { private final String name; // 필수 private final String email; // 필수 private final int age; // 선택 private final String gender; // 선택 public Member(String name, String email) { this(name, email, 0); } public Member(String name, String email, int age) { this(name, email, age, 0); } public Member(String name, String email, int age, String gender) { this.name = name; this.email = email; this.age = age; this.gender = geder; } }
위와 같은 점층적 생성자 패턴은 사용은 가능하지만, 매개변수의 개수가 많아지만 클라이언트 코드를 작성하거나 읽기가 어렵다.
자바 빈즈패턴(JavaBeans Pattern)
public class Member { private final String name; // 필수 private final String email; // 필수 private final int age; // 선택 private final String gender; // 선택 public Member() {} public setName(String name) {this.name = name;} public setEmail(String email) {this.email = email;} public setAge(int age) {this.age = age;} public setGender(String gender) {this.gender = gender;} } // 사용 public class Test { public Member createMember() { Member member = new Member(); member.setName("철수"); member.setEmail("[email protected]"); member.setAge(30); member.setGender("남성"); return member; } }
자바 빈즈 패턴에서는 객체 하나를 만들려면 메서드를 여러 개 호출해야 하고, 객체가 완전히 생성되기 전까지는 일관성(Consistency)이 무너진 상태에 놓이게 된다.
자바 빈즈 패턴에서는 클래스를 불변으로 만들 수 없으며, 스레드 안전성을 얻으려면 개발자가 추가 작업을 해줘야만 한다.
빌터 패턴
public class Member { private final String name; private final String email; private final int age; private final String gender; public static class Builder { // 필수 매개변수 private final String name; private final String email; // 선택 매개변수 - 기본값으로 초기화한다. public int age = 0; public String gender = ""; public Builder(String name, String email) { this.name = name; this.email = email; } public Builder age(int age) { this.age = age; return this; } public Builder email(String email) { this.email = email; return this; } public Builder build() { return new Member(this); } } private Member(Builder builder) { this.name = builder.name; this.email = builder.email; this.age = builder.age; this.gender = builder.gender; } }
빌터 패턴은 점층적 생성자 패턴과 자바 빈즈 패턴의 장점만 취했다.
빌더 패턴은 명명된 선택적 매개변수(Named Optional Parameter)를 흉내 낸 것이다. (코틀린에서는 Named Argument )
) 빌터 패턴 사용 중 잘못된 점이 발견되면 IlleagalArgumentException을 던지면 된다.
생성자나 정적 팩토리가 처리해야 할 매개변수가 많다면 빌더 패턴을 선택하는 게 더 낫다. 매개변수 중 다수가 필수가 아니거나 같은 타입이면 더욱 그렇다.
빌더는 점층적 생성자보다 클라이언트 코드를 읽고 쓰기가 훨씬 간결하고 자바 빈즈보다 훨씬 안전하다.
Reference
이펙티브 자바 3/E - 인사이트
from http://daniel-blog.tistory.com/50 by ccl(A) rewrite - 2021-12-14 03:02:12