class 내부에 static class Builder
가 정의된다.
Builder
클래스 내부에는 class의 매개변수들이 선언되는데 필수 매개변수는 final
이 선언되어야 하고, 선택 매개변수는 기본값을 설정한다.
Builder 생성자에는 필수 매개변수들이 파라미터로 들어가게 된다.
public Builder(servingSize, servings) {}
선택 매개변수들은 method 이름으로 하나씩 정의한다.
public Builder calories(int val) {
this.calories = val;
return this;
}
public Builder fat(int val) {
this.fat = val;
return this;
}
클래스를 리턴하는 build() 함수를 정의한다.
public NutritionFacts build() {
return new NutritionFacts(this);
}
class 에 Builder 를 파라미터로 받는 생성자를 작성한다.
public NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
public class NutritionFacts {
private final int servingSize; // 필수 매개변수
private final int servings; // 필수 매개변수
private final int calories; // 선택 매개변수
private final int fat; // 선택 매개변수
private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
}
public static class Builder {
private final int servingSize; // 필수 매개변수는 반드시 final 을 선언한다.
private final int servings; // 필수 매개변수는 반드시 final 을 선언한다.
// 선택 매개변수는 기본값으로 설정한다.
private int calories = 0; // 선택 매개변수
private int fat = 0; // 선택 매개변수
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val) {
this.calories = val;
return this;
}
public Builder fat(int val) {
this.fat = val;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
}
// 이 경우는 필수값 servingSize, servings 중 하나의 값이 비었으므로 컴파일에러가 난다.
new NutritionFacts.Builder(10).fat(1000).calories(1220).build();
// 옵셔널 한 값을 필수로 셋팅하지 않아도 된다.
new NutritionFacts.Builder(10, 10).build();
// 옵셔널 한 값은 다음처럼 사용될 수 있다
new NutritionFacts.Builder(10, 10).fat(1000).calories(1220).build();
new NutritionFacts.Builder(10, 10).fat(10000).build();
@Builder
를 사용하는 방법은 class
위에 선언하는 방법, constructor
에 선언하는 방법이 있다.NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
}
public static NutritionFactsBuilder builder() {
return new NutritionFactsBuilder();
}
}
constructor
위에 @Builder
를 선언한다.public class NutritionFacts {
private int servingSize;
private int servings;
private int calories;
private int fat;
public NutritionFacts(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = 0;
this.fat = 0;
}
public static NutritionFacts.NutritionFactsBuilder builder() {
return new NutritionFacts.NutritionFactsBuilder();
}
public static class NutritionFactsBuilder {
private int servingSize;
private int servings;
private int calories;
private int fat;
NutritionFactsBuilder() {
}
public NutritionFacts.NutritionFactsBuilder servingSize(int servingSize) {
this.servingSize = servingSize;
return this;
}
public NutritionFacts.NutritionFactsBuilder servings(int servings) {
this.servings = servings;
return this;
}
public NutritionFacts.NutritionFactsBuilder calories(int calories) {
this.calories = calories;
return this;
}
public NutritionFacts.NutritionFactsBuilder fat(int fat) {
this.fat = fat;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this.servingSize, this.servings, this.calories, this.fat);
}
public String toString() {
return "NutritionFacts.NutritionFactsBuilder(servingSize=" + this.servingSize + ", servings=" + this.servings + ", calories=" + this.calories + ", fat=" + this.fat +")";
}
}
}
만약, calories 를 초기값으로 세팅을 하고자 할 때 Builder 를 통해서는 제공이 안되므로 calories 를 @Setter
를 제공해서 다음과 같이 NutrionFacts를 생성한 후 calories 를 set 할 수 있다.
NutritionFacts nutritionFacts = NutritionFacts.builder.servings(10).servingSize(1).build();
nutritionFacts.setCalories(1000);
부득이하게 @Setter
를 선언하게 될 수 밖에 없고,
@Setter
를 사용 시 해당 업데이트 문이 언제 발생했는지 추적하기가 어렵다.@Builder
를 사용할 수 있는 방법이 없을까?@Builder(builderMethodName = "")
을 사용한다.
@Builder(builderMethodName = "innerBuilder")
public class NutritionFacts {
private final int servingSize; // 필수 매개변수
private final int servings; // 필수 매개변수
@Builder.Default private int calories = 0; // 선택 매개변수
@Builder.Default private int fat = 0; // 선택 매개변수
public static NutritionFactsBuilder builder(int servingSize, int servings) {
return innerBuilder().servings(servings).servingSize(servingSize);
}
}
innerBuilder()
를 통해서 객체를 만들고, 다음에 롬복에서 제공하는 builder 패턴을 사용하겠다는 의미이다.@Builder.Default
값이 할당 되지 않은 경우 초기값을 설정하겠다는 뜻이다.public class NutritionFacts {
private final int servingSize;
private final int servings;
private int calories;
private int fat;
public static NutritionFactsBuilder builder(int servingSize, int servings) {
return innerBuilder().servings(servings).servingSize(servingSize);
}
private static int $default$calories() {
return 0;
}
private static int $default$fat() {
return 0;
}
NutritionFacts(int servingSize, int servings, int calories, int fat) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
}
public static NutritionFactsBuilder innerBuilder() {
return new NutritionFactsBuilder();
}
}
NutritionFacts nutritionFacts = NutritionFacts.builder(10, 200).fat(130).calories(222).build();
When comparing the Builder class and constructor in object-oriented programming, it's essential to understand their distinct roles and advantages. While constructors initialize objects directly, the Builder class offers a more flexible approach, particularly useful when dealing with complex object creation scenarios. With the Builder pattern, you can set optional parameters and create objects step by step, enhancing readability and maintainability. This flexibility becomes especially valuable when dealing with objects requiring numerous configuration options. Additionally, the Builder pattern promotes code reuse and simplifies the process of creating objects with varying configurations. If you're interested in exploring this topic further, you can find insightful resources on object-oriented design patterns at https://writepaper.com/custom-essay.