블로그에 게시하는 위 글은 전체적인 내용 정리가 아닌
책을 읽으면서 새로 알게된 내용이나 제가 중요하다고 생각하는 내용을 정리한 글입니다.
백기선님의 유튜브와 책을 병행했다.
생성자, 정적 팩토리 메소드 둘 다 매개변수가 많을 때 처리가 어렵다.
예를 들어 식품 영양소 클래스에서 20개가 넘는 영양 정보들 (탄수화물, 지방, 총 칼로리 등 ...)이 들어가지만 정작 사용하는 변수들은 많지 않다.
그렇기 때문에 예전에는 받는 매개변수가 다른 생성자를 각각 만들어 객체를 생성해주었다.
public class Person {
private String name;
private Integer age;
private Integer birth;
public Person(String name, Integer age, Integer birth) {
this.name = name;
this.age = age;
this.birth = birth;
}
// 사용할 생성자 만들기
public Person(String name, Integer age) {
this(name, age, 0);
}
public Person(String name) {
this(name, 0, 0);
}
... (중략) ...
}
기본 생성자로 객체를 생성한 후에, Setter를 호출하여 값을 고정시키는 방법이다.
public class Person {
private String name; // 필수
private Integer age = 0;
private Integer birth = 0;
public Person() {} // 기본 생성자
// setter
public void setName(String name){
this.name = name;
}
... (중략) ...
}
사용할 때에는 아래와 같이 사용한다.
Person me = new Person();
me.setName("fresh");
me.setAge(10);
me.setBirth(100070);
클라이언트에서 필수 매개변수만 가지고 있는 생성자를 호출해서 객체를 만든 후,
필요하면 (빌더에서 제공하는) Setter메소드로 선택 매개변수의 값을 추가한다.
public class Person {
private final String name;
private final Integer age;
private final Integer birth;
private final boolean isStudent = true;
public static class Builder {
// 필수 매개변수
private final String name;
private final Integer age;
// 선택 매개변수
private Integer birth = 000000;
private boolean isStudent = true;
// 필수 매개변수만 받는 생성자 호출
public Builder(String name, Integer age) {
this.name = name;
this.age = age;
}
// setter
public Builder birth(int val){
birth = val;
return this;
}
public Builder isStudent(boolean val){
isStudent = val;
return this;
}
public Person build(){
return new Person(this);
}
}
private Person(Builder builder) {
name = builder.name;
age = builder.age;
birth = builder.birth;
isStudent = builder.isStudent;
}
}
빌더의 setter는 빌더 자기 자신을 호출하기 때문에 메소드를 연속적으로 호출 가능
-> 메소드 연쇄, 플루언트 API
사용할 때에는 아래와 같이 사용한다.
Person me = new Person.Builder("선영", 10) // 필수 인자
.isStudent(false).build(); // 선택 인자
빌더 패턴은 계층적으로 설계된 클래스와 함께 쓰기 좋다.