Skip to content

Latest commit

 

History

History
145 lines (114 loc) · 4.34 KB

02.매개변수가 많으면, 빌더로 효율적이고 안전하게 생성할 수 있다.md

File metadata and controls

145 lines (114 loc) · 4.34 KB

소주캉

빌더🧱 패턴이란🤔?

동일한 프로세스를 거쳐 다양한 구성의 인스턴스를 만드는 방법

  1. 클라이언트는 객체를 직접 만들지 않고 필수 매개변수만으로 생성자(정적 팩토리 메서드)를 호출해 빌더 객체를 얻는다.
  2. 빌더 객체가 제공하는 메서드들로 원하는 선택 매개변수를 설정한다.
  3. 매개변수가 없는 `build``메서드를 호출해 일반적으로 불변 객체를 얻는다.
  4. 빌더는 일반적으로 생성할 클래스 안에 정적 멤버 클래스로 둔다.

왜 사용할까?

객체의 생성자나 정적 팩토리 메서드가 매개변수가 많고 복잡하다면, 객체를 만드는 프로세스를 독립적으로 분리할 필요가 있다. 이때 빌더 패턴을 사용해볼 수 있다.

실 사용 예시🔧

자바 8 Stream.Builder API

    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);
        }

StringBuilder

    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)

참고