Design Pattern/생성 패턴

Builder Pattern

Builder Pattern

빌더 패턴은 객체 생성을 깔끔하고 유연하게 하기 위한 기법

  • 각 인자가 어떤 의미인지 알기 쉽다.
  • setter 메소드가 없으므로 변경 불가능 객체를 만들 수 있다.
  • 한 번에 객체를 생성하므로 객체 일관성이 깨지지 않는다.
  • build() 함수가 잘못된 값이 입력되었는지 검증하게 할 수도 있다.
public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

    public static class Builder {
        // Required parameters(필수 인자)
        private final int servingSize;
        private final int servings;

        // Optional parameters - initialized to default values(선택적 인자는 기본값으로 초기화)
        private int calories      = 0;
        private int fat           = 0;
        private int carbohydrate  = 0;
        private int sodium        = 0;

        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings    = servings;
        }

        public Builder calories(int val) {
            calories = val;
            return this;    // 이렇게 하면 . 으로 체인을 이어갈 수 있다.
        }
        public Builder fat(int val) {
            fat = val;
            return this;
        }
        public Builder carbohydrate(int val) {
            carbohydrate = val;
            return this;
        }
        public Builder sodium(int val) {
            sodium = val;
            return this;
        }
        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
    }

    private NutritionFacts(Builder builder) {
        servingSize  = builder.servingSize;
        servings     = builder.servings;
        calories     = builder.calories;
        fat          = builder.fat;
        sodium       = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }
}
public class BuilderPatternDemo {
    public static void main(String[] args) {
        NutritionFacts nutritionFacts = new NutritionFacts
                .Builder(240, 8) // 필수 인자
                .calories(100)
                .sodium(35)
                .carbohydrate(27)
                .build();
    }
}

 

Lombok @Builder

앞선 코드에서 보듯 Builder패턴을 적용하기 위해서 많은 양의 코드를 작성해야한다. 각 엔티티가 모두 사용한다고 한다면 ... 후 상상만해도 끔찍하다.

하지만 롬복을 사용한다면  @Builder 어노테이션을 이용해서 해결할 수 있다.

롬복의 @Builder는 두 위치에서 사용할 수 있는데 클래스와 생상자이다. 

클래스에 적용하면 모든 멤버변수를 포함해서 빌더 패턴을 만들게 됩니다.

@Builder
public class Skill {
    ...
}

생성자에 만들면 해당 생성자에 매개변수만으로 빌더 패턴을 만들게 됩니다. 

public class Skill {

    ...

    @Builder
    public Skill(Long id, String skillName, Integer skillLevel, int level,
                 FileInfo fileInfo, Member member) {
        this.id = id;
        this.skillName = skillName;
        this.skillLevel = skillLevel;
        this.level = level;
        this.fileInfo = fileInfo;
        if(member != null) {
            changeProfile(member);
        }
    }
    
	...
}

'Design Pattern > 생성 패턴' 카테고리의 다른 글

prototype pattern  (0) 2021.04.13
Singleton Pattern  (0) 2021.04.12
Abstract Factory Pattern  (0) 2021.04.12
Factory Pattern  (0) 2021.04.12