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 |