소주캉
동일한 프로세스를 거쳐 다양한 구성의 인스턴스를 만드는 방법
- 클라이언트는 객체를 직접 만들지 않고 필수 매개변수만으로 생성자(정적 팩토리 메서드)를 호출해
빌더
객체를 얻는다. 빌더
객체가 제공하는 메서드들로 원하는 선택 매개변수를 설정한다.- 매개변수가 없는 `build``메서드를 호출해 일반적으로 불변 객체를 얻는다.
빌더
는 일반적으로 생성할 클래스 안에 정적 멤버 클래스로 둔다.
객체의 생성자나 정적 팩토리 메서드가 매개변수가 많고 복잡하다면, 객체를 만드는 프로세스를 독립적으로 분리할 필요가 있다. 이때 빌더 패턴을 사용해볼 수 있다.
public static void main(String[] args) {
Stream.Builder<String> builder = Stream.builder();
List<String> result = builder.add("이름은")
.add("포비")
.add("미래소년")
.build()
.collect(Collectors.toList());
System.out.println(result);
}
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
String builtString = builder.append(500)
.append("원의 ")
.append(0.01)
.append("%는 ")
.append("원")
.insert(13, 5)
.toString();
System.out.println(builtString);
}
- 생성자로 받는 경우
DecideLunch(int price, int distance, float meanStarScore, String restaurantName, String menuName) {
this.price = price;
this.distance = distance;
this.meanStarScore = meanStarScore;
this.restaurantName = restaurantName;
this.menuName = menuName;
}
빌더
패턴 적용할 경우
class DecideLunchWithBuilder {
private int price;
private int distance;
private float meanStarScore;
private String restaurantName;
private String menuName;
static class Builder {
// 필수 매개변수
private final int price;
private final int distance;
// 선택 매개변수
private float meanStarScore;
private String restaurantName;
private String menuName;
Builder(int price, int distance) {
this.price = price;
this.distance = distance;
}
Builder meanStarScore(float meanStarScore) {
this.meanStarScore = meanStarScore;
return this;
}
Builder restaurantName(String restaurantName) {
this.restaurantName = restaurantName;
return this;
}
Builder menuName(String menuName) {
this.menuName = menuName;
return this;
}
DecideLunchWithBuilder build() {
return new DecideLunchWithBuilder(this);
}
}
private DecideLunchWithBuilder(Builder builder) {
price = builder.price;
distance = builder.distance;
meanStarScore = builder.meanStarScore;
restaurantName = builder.restaurantName;
menuName = builder.menuName;
}
}
- 사용
public static void main(String[] args) {
DecideLunchWithBuilder.Builder builder = new DecideLunchWithBuilder.Builder(18000, 3);
DecideLunchWithBuilder decideLunchWithBuilder =
builder
.meanStarScore(4.3f)
.restaurantName("우아한 식당")
.menuName("치킨")
.build();
}
- 만들기 복잡한 객체를 순차적으로 만들 수 있다.
- 복잡한 객체를 만드는 구체적인 과정을 숨길 수 있다.
- 동일한 프로세스를 통해 각기 다르게 구성된 객체를 만들 수도 있다.
- 불완전한 객체를 사용하지 못하도록 방지할 수 있다.
- 원하는 객체를 만들려면 빌더부터 만들어야 한다.
- 구조가 복잡해진다. (Trade-off)