[Effective Java] Item 2. ์์ฑ์์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด Builder๋ฅผ ๊ณ ๋ คํ์.
by rlaehddnd0422์ ์ ํฉํ ๋ฆฌ ๋ฉ์๋, ์ค์ฌ์ ์ ํฉ๋ฉ์ ์์ฑ์์ ๋ชจ๋ ํ ๊ฐ์ง ์ ์ฝ์ด ์์ต๋๋ค.
> ๋ฐ๋ก ์ ํ์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง์๋ ์ ์ ํ ๋์ํ๊ธฐ ์ด๋ ต๋ค๋ ์ ์ธ๋ฐ์.
์ด ์ ์ฝ์ ๋ํ ๋์๋ค์ด ์ด๋ค ๊ฒ๋ค์ด ์๋์ง ๋จผ์ ํ๋์ฉ ์์๋ณด๊ฒ ์ต๋๋ค.
์ ์ธต์ ์์ฑ์ ํจํด(Telescoping Constructor Pattern)
// ์์ ์ ๋ณด ํด๋์ค
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 NutritionFacts(int servingSize, int servings) {
this(servingSize, servings, 0);
}
public NutritionFacts(int servingSize, int servings, int calories) {
this(servingSize, servings, calories, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat) {
this(servingSize, servings, calories, calories, fat, 0);
}
public 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;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
}
}
- ์์์ ๋ณด๋ฅผ ๋ด๋ ํด๋์ค NutritionFacts์ ๋๋ค.
- ์ด ํด๋์ค๋ ํ๋กํผํฐ๋ก servingSize, servings, ... carbohydrate๋ฅผ ๊ฐ์ง๋๋ค.
ํ์ง๋ง ์ฌ๊ธฐ์ servingSize์ servings ํ๋กํผํฐ๋ ํ์๋ก ๊ฐ์ ๊ฐ์ ธ์ผ ํ๊ณ , ๋๋จธ์ง ํ๋กํผํฐ๋ ๊ฐ์ ๊ผญ ๊ฐ์ ธ์ผ ํ๋ ๊ฒ์ด ์๋ ์ ํ์ ํ๋กํผํฐ๋ผ๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
์ด๋ฐ ๊ฒฝ์ฐ, ์ด๊ธฐ ๊ฐ๋ฐ์๋ค์ ์ ์ฝ๋์ ๊ฐ์ด ์์ฑ์๋ฅผ ๊ตฌ์ฑํ์ฌ ๋งค๊ฐ๋ณ์ 2๊ฐ๋ฅผ ๋ฐ๋ ์์ฑ์์์ 3๊ฐ๋ฅผ ๋ฐ๋ ์์ฑ์๋ฅผ ํธ์ถํ๊ณ 3๊ฐ๋ฅผ ๋ฐ๋ ์์ฑ์๋ 4๊ฐ๋ฅผ ๋ฐ๋ ์์ฑ์๋ฅผ ํธ์ถํ๊ณ 4๊ฐ๋ 5๊ฐ๋ฅผ ๋ฐ๋ ์์ฑ์๋ฅผ ํธ์ถํ์ฌ ๊ฒฐ๊ตญ n-1๊ฐ๋ฅผ ๋ฐ๋ ์์ฑ์๊ฐ n๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ๋ ์์ฑ์๋ฅผ ํธ์ถํ๋ ์ ์ธต์ ์์ฑ์ ํจํด์ ์ฌ์ฉํ๊ณค ํ๋ค๊ณ ํฉ๋๋ค. ์์ฑ์ ์ฝ๋๋ง ์์ฑํ์ ๋ฟ์ธ๋ฐ ๋ฒ์จ ๋ฌด๊ฑฐ์์ง ๋๋์ด๋ค์.
NutritionFacts nutritionFacts = new NutritionFacts(10, 100, 0);
์ด ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์ํ๋ ์ด๋ ๊ฒ ๋งค๊ฐ๋ณ์๋ฅผ ํฌํจํ ์์ฑ์ ์ค ๊ฐ์ฅ ์งง์ ๊ฒ์ ๊ณ ๋ฅด๋ฉด ๋๋๋ฐ์.
๋ณดํต ์ด๋ฐ ์์ฑ์๋ ์ฌ์ฉ์๊ฐ ์ค์ ํ๊ธธ ์ํ์ง ์๋ ๋งค๊ฐ๋ณ์๊น์ง ํฌํจํ๊ธฐ ์ฌ์ด๋ฐ, ๊ทธ๋ฐ ๋งค๊ฐ๋ณ์์๋ ๊ฐ์ ์ง์ ํด์ผ ํ๋ค๋ ๋จ์ ์ด ์์ต๋๋ค. ์ ์ฝ๋๋ก ๋งํ์๋ฉด fat ๋งค๊ฐ๋ณ์์ ๊ตณ์ด 0์ ๊ฐ์ ์ค์ ํด์ค ๊ฒ์ฒ๋ผ ๋ง์ด์ฃ .
์ ๋ฆฌํ์๋ฉด ์ด๋ฐ ์ ์ธต์ ์์ฑ์ ํจํด๋ ์ฌ์ฉํ ์๋ ์๊ฒ ์ง๋ง, ๋งค๊ฐ๋ณ์๊ฐ ๋ง์์ง๋ฉด ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ๋ ์ฝ๊ธฐ๋ ์ด๋ ต๋ค๋ ๋จ์ ์ด ์์ต๋๋ค.
์ฝ๋๋ฅผ ์ฝ์ ๋ ๊ฐ ๊ฐ์ ์๋ฏธ๋ฅผ ํ์ ํด์ผ ํ๊ณ , ๋งค๊ฐ๋ณ์๊ฐ ๋ช ๊ฐ์ธ์ง๋ ์ฃผ์ํด์ ์ธ์ด๋ณด์์ผํ๋ ๋ฒ๊ฑฐ๋ก์๋ ์๊ณ , ํ์ ์ด ๊ฐ์ ๋งค๊ฐ๋ณ์๊ฐ ์ฐ๋ฌ์ ์์ผ๋ฉด ์ฐพ๊ธฐ ์ด๋ ค์ด ๋ฒ๊ทธ๊ฐ ์๊ฒจ๋ ์๋ ์๊ฒ ๊ตฌ์.
์ด๋ฒ์๋ ๋ค๋ฅธ ๋์์ธ ์๋ฐ๋น์ฆ ํจํด์ ์์๋ณด๊ฒ ์ต๋๋ค.
์๋ฐ๋น์ฆ ํจํด(JavaBeans Pattern)
์๋ฐ๋น์ฆ ํจํด์ ์ ์ฉํ ์ฝ๋ ๋จผ์ ๋ณด๊ฒ ์ต๋๋ค.
package dw.chapter1.item2;
// ์์ ์ ๋ณด ํด๋์ค
public class NutritionFacts {
private int servingSize = -1; // ํ์
private int servings = -1; // ํ์
private int calories = 0; // ์ ํ
private int fat = 0;// ์ ํ
private int sodium = 0;// ์ ํ
private int carbohydrate = 0; // ์ ํ
public NutritionFacts() {}
public void setServingSize(int servingSize) {
this.servingSize = servingSize;
}
public void setServings(int servings) {
this.servings = servings;
}
public void setCalories(int calories) {
this.calories = calories;
}
public void setFat(int fat) {
this.fat = fat;
}
public void setSodium(int sodium) {
this.sodium = sodium;
}
public void setCarbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
}
}
- ๊ฐ ํ๋กํผํฐ์ final ํค์๋๋ฅผ ๋ถ์ด์ง ์๊ณ , ์ด๊ธฐ ๊ฐ์ ์ธํ ํ๊ณ setter๋ฅผ ์์ฑํ ํจํด
- ๊ฐ๋ ์ฑ์ด ์ ์ธต์ ์์ฑ์ ํจํด์ ๋๋นํด์๋ ์ฝ๊ธฐ์๋ ๋๋ฌด ์ฝ๋ค๋ ์ ์ด ์ฅ์ ์ด ๋๊ฒ ์ต๋๋ค.
- ์ ์ธต์ ์์ฑ์ ํจํด์ ๋จ์ (๋๋ฌด ๋ง์ ์์ฑ์, ์์ฑ์ arugment์ ๋ถํ์ํ ๊ฐ ์ธํ , ๋ฎ์ ๊ฐ๋ ์ฑ)์ ์ฌ๋ผ์ก๋ค๊ณ ๋ณผ ์ ์์ง๋ง, ํ๋กํผํฐ ์ธํ ์ setter๋ก ํ๋ํ๋ ์์ฑํด์ฃผ์ด์ผ ํ๋ค๋ ์ ๊ณผ ์๋ฌด๋๋ setter๋ฅผ ์ด์ด๋์ด ์ผ๊ด์ฑ์ด ๋ฌด๋์ก๋ค๋ ์ ์ผ๋ก ๋ณด์ ์ข์ ํจํด์ผ๋ก ๋ณผ ์๋ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
ํ์ง๋ง ์์ฑ์ด ๋๋ ๊ฐ์ฒด๋ฅผ ์๋์ผ๋ก ์ผ๋ฆฌ๊ณ ์ผ๋ฆฌ๊ธฐ ์ ์๋ ์ฌ์ฉํ ์ ์๋๋ก ์ค์ ํ์ฌ ์ด๋ฐ ๋จ์ ๋ค์ ์ํํ ์ ์๋ค๊ณ ํฉ๋๋ค.
ํ์ง๋ง ๊ทผ๋ณธ์ ์ผ๋ก ์ด ๋ฐฉ๋ฒ์ ๋ค๋ฃจ๊ธฐ ์ด๋ ค์ ์ค๋ฌด์์๋ ๊ฑฐ์ ์ฌ์ฉ๋์ง๋ ์๊ณ , ๊ฐ์ฒด๋ฅผ ์ผ๋ฆฌ๊ธฐ ์ํด ์ฌ์ฉํ freeze ๋ฉ์๋์ ๋ํด ์ปดํ์ผ๋ฌ๊ฐ ๋ณด์ฆํ ๋ฐฉ๋ฒ์ด ์์ด ๋ฐํ์ ์ค๋ฅ์ ์ทจ์ฝํ๋ ๋จ์ ์ผ๋ก ๊ทธ์ ์์ฑ์๋ฅผ ์ด๋ฐ ๋ฐฉ๋ฒ๋ ์๊ตฌ๋ ์ ๋๋ง ์์๋์ด๋ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
๋ง์ง๋ง ๋์์ผ๋ก ๊ฐ๋ณด๊ฒ ์ต๋๋ค.
Builder ํจํด
์ด Theme์์ ๋งํ๊ณ ์ ํ๋ ๋น๋ ํจํด์ด ๋ง์ง๋ง ๋์์ด ๋๊ฒ ์ต๋๋ค.
๋น๋ ํจํด์ ์ ์ธต์ ์์ฑ์ ํจํด๊ณผ ์๋ฐ๋น์ฆ ํจํด์ ์ฅ์ (์ ์ธต์ ์์ฑ์ ํจํด์ ์์ ์ฑ, ์๋ฐ๋น์ฆ ํจํด์ ๊ฐ๋ ์ฑ)์ ๋ชจ๋ ๊ฒธ๋นํ๋ค๊ณ ํ๋๋ฐ์. ๋จผ์ ์ฝ๋๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
package dw.chapter1.item2;
// ์์ ์ ๋ณด ํด๋์ค
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 {
// ํ์ ๋งค๊ฐ๋ณ์
private final int servingSize;
private final int servings;
// ์ ํ ๋งค๊ฐ๋ณ์ - default ๊ฐ์ผ๋ก ์ด๊ธฐํ
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 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 sodium(int val) {
sodium = val;
return this;
}
public Builder carbohydrate(int val) {
carbohydrate = 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;
}
}
- NutritionFacts๋ ํ๋กํผํฐ์ ๋ชจ๋ final ํค์๋๋ฅผ ๋ถ์ฌ ๋ถ๋ณ ํด๋์ค์์ ๋ณด์ฆํด์ฃผ๋ฉด์, ๋ชจ๋ ๋งค๊ฐ๋ณ์์ ๊ธฐ๋ณธ๊ฐ๋ค์ ํ ๊ณณ์ ๋ชจ์ ๋์์ต๋๋ค.
Builder์ ์ธํฐ ๋ฉ์๋๋ค๋ ๊ฒฐ๊ตญ ์์ ์ ๋ฆฌํดํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฉ์๋๋ค์ ์ฐ์์ ์ผ๋ก ํธ์ถํ ์ ์์ต๋๋ค!
๊ทธ๋์ ๊ฒฐ๊ตญ ๋น๋๋ฅผ ์ ์ฉํ๋ฉด ์ด๋ ๊ฒ ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๊ฒ ์ต๋๋ค.
NutritionFacts nutritionFacts = new NutritionFacts.Builder(10, 100) // 3. ๋น๋ ํจํด
.calories(10)
.fat(100)
.sodium(30)
.carbohydrate(20)
.build();
- ๊ฐ์ธ์ ์ผ๋ก Lombok์ ์ฌ๊ธฐ์ฑ์ ์ ์ ์๋ ๋ถ๋ถ์ด์์ต๋๋ค.
- ๊ทธ๋ฅ @Builder ์ด๋ ธํ ์ด์ ๋ง ๋ถ์ด๋ฉด ์ด๋ฐ ํจํด์ ์๋์ผ๋ก ์ ์ฉํ ์ ์์๋๋ฐ, ์ด๋ ธํ ์ด์ ๋ด๋ถ์์ ์ด๋ฐ์์ผ๋ก ์ฝ๋๋ฅผ ๊ตฌ์ฑํ๊ณ ์์๋ค์. ์ด ๋ํ ์ฒ์ ์์์ต๋๋ค.
์ด๋ ๊ฒ ๊ฐ ์ธํฐ๊ฐ ์์ ์ ์ธ์คํด์ค๋ฅผ ๋ฆฌํดํ๋ ๋๋ถ์ ๋ฉ์๋๋ฅผ ์ฐ์์ ์ผ๋ก ํธ์ถํ ์ ์์๋๋ฐ ์ด๋ฐ ๋ฐฉ์์ ๋ฉ์๋ ์ฒด์ด๋, ํ๋ฃจ์ธํธ API๋ผ๊ณ ํ๋ค๊ณ ํฉ๋๋ค!
๋ฌด์๋ณด๋ค ์ด ์ฝ๋๋ ํด๋ผ์ด์ธํธ๋ ์ฝ๊ณ ์ฐ๊ธฐ ์ฝ๋ค๋ ํฐ ์ฅ์ ์ด ์์ต๋๋ค๋ง,
๊ฐ ํ๋กํผํฐ์ ์ ํจ์ฑ์ ๊ฒ์ฆํ ์ ์๋ค๋ ๋จ์ ์ด ์๋๋ฐ ์ด ๋จ์ ์ ๊ทธ๋ฅ build() ๋ฉ์๋์์ ๊ฐ ํ๋กํผํฐ์ ์ ํจ์ฑ์ ๊ฒ์ฆํ๊ณ ํต๊ณผํ์ง ๋ชปํ๋ค๋ฉด ๋ฉ์์ง๋ฅผ ๋ด์ Un-Checked ์์ธ๋ฅผ ๋์ ธ์ค์ผ๋ก์จ ํด๋ผ์ด์ธํธ์๊ฒ ์์ธ๋ฅผ ์๋ ค์ฃผ์ด ์ถฉ๋ถํ ๋ณด์ํ ์ ์๊ฒ ์ต๋๋ค.
์ด ๋น๋ ํจํด์ ๊ณ์ธต์ ์ผ๋ก ์ค๊ณ๋ ํด๋์ค์ ํจ๊ป ์ฐ๊ธฐ์ ์ข์ต๋๋ค.
๋น๋ ํจํด์ ๊ณ์ธต์ ์ผ๋ก ์ค๊ณ๋ ํด๋์ค์ ์ ์ฉํด๋ณด๊ธฐ
์ง๊ธ๋ถํฐ๋ ์กฐ๊ธ ์ด๋ ค์ด ๋ด์ฉ์ผ ์ ์๋๋ฐ, ์ต๋ํ ์ฝ๊ฒ ํ์ด๊ฐ๋ณด๊ฒ ์ต๋๋ค.
์ถ์ ํด๋์ค๋ ์ถ์ ๋น๋๋ฅผ, ๊ตฌ์ฒด ํด๋์ค๋ ๊ตฌ์ฒด ๋น๋๋ฅผ ๊ฐ๊ฒ ํด๋์ค๋ฅผ ์ค๊ณํ ์ฝ๋๋ฅผ ๋จผ์ ๋ณด๊ฒ ์ต๋๋ค.
์ถ์ ํด๋์ค์๋ ์ถ์ ๋น๋๋ฅผ
package dw.chapter1.item2;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
public abstract class Pizza {
public enum Topping {HAM, MUSHROOM, ONION, PEPPER, SAUSAGE}
final Set<Topping> toppings;
abstract static class Builder<T extends Builder<T>> {
EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
public T addTopping(Topping topping) {
toppings.add(Objects.requireNonNull(topping));
return self();
}
// ํ์ ํด๋์ค์์ ์ด ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ์ฌ this๋ฅผ ๋ฆฌํดํ๋๋ก ํด์ผํจ.
protected abstract T self();
abstract Pizza build();
}
Pizza(Builder<?> builder) {
toppings = builder.toppings.clone();
}
}
- Pizza ๋ ํผ์๋ฅผ ๋ํ๋ด๋ ์ถ์ ํด๋์ค๋ก ํผ์ ํ ํ์ ์ด๊ฑฐํ๋ ์ด๊ฑฐํ(enum) ํ์ Topping์ด ์๊ณ ํด๋์ค์๋ ์ต์ข ์ ์ธ ํ ํ ์งํฉ์ธ EnumSet<Topping> toppings๋ฅผ ํ๋กํผํฐ๋ก ๊ฐ์ง๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ ๋ํด ์ถ์ ๋น๋๋ ์์ฑ์ด ๋์๋๋ฐ, ์ถ์ ๋น๋ ํด๋์ค๋ฅผ ์ดํด๋ด ์๋ค.
abstract static class Builder<T extends Builder<T>> {
EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
public T addTopping(Topping topping) {
toppings.add(Objects.requireNonNull(topping));
return self();
}
// ํ์ ํด๋์ค์์ ์ด ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ์ฌ this๋ฅผ ๋ฆฌํดํ๋๋ก ํด์ผํจ.
protected abstract T self();
abstract Pizza build();
}
- ํ์
๋งค๊ฐ๋ณ์ T
- Builder ํด๋์ค๋ ์ ๋ค๋ฆญ ํ์ T๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๋น๋ ํด๋์ค๋ฅผ ์์ํ๋ ํ์ ํด๋์ค์ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค.
EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
- toppings ํ๋
- EnumSet์ ์ฌ์ฉํ์ฌ Topping ์ด๊ฑฐํ์ ํ ํ์ ์ ์ฅํ๋ ํ๋์ ๋๋ค.
- EnumSet.noneOf(Topping.class)์ ํตํด ์ด๊ธฐํ๋์ด ๋น ์ํ๋ก ์์ํฉ๋๋ค.
public T addTopping(Topping topping) {
toppings.add(Objects.requireNonNull(topping));
return self();
}
- addTopping ๋ฉ์๋
- ํ ํ์ ์ถ๊ฐํ๋ ๋ฉ์๋์ ๋๋ค.
- Objects.requireNonNull์ ์ฌ์ฉํ์ฌ null ๊ฐ์ด ์ ๋ฌ๋์ง ์๋๋ก ํ์ธํฉ๋๋ค.
- ๋ฉ์๋๋ ๋น๋ ๊ฐ์ฒด ์์ฒด๋ฅผ ๋ฐํํ๋ฏ๋ก ๋ฉ์๋ ์ฒด์ด๋์ ํตํด ์ฌ๋ฌ ํ ํ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
protected abstract T self();
- ์ฌ๊ธฐ์ ์ถ์ ๋ฉ์๋์ธ self๋ฅผ ๋ํด ํ์ ํด๋์ค์์๋ ํ๋ณํ์ ํ์ง ์๊ณ ๋ ๋ฉ์๋ ์ฐ์๋ฅผ ์ง์ํ ์ ์์
- ํ์ด์ฌ๊ณผ ๋ฌ๋ฆฌ self ํ์ ์ด ์๋ ์๋ฐ๋ฅผ ์ํ ์ฐํ๋ฐฉ๋ฒ์ ์๋ฎฌ๋ ์ดํธํ ์ ํ ํ์ ์ด๋ผ๊ณ ํ๋ค๊ณ ํฉ๋๋ค;
- ๋ฉ์๋ ์ฐ์๋ฅผ ์ํด ํ์ ํด๋์ค์์๋ ์ด ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ์ฌ this๋ฅผ ๋ฆฌํดํ๋๋ก ๊ตฌํํ๋ฉด ๋๊ฒ ์ต๋๋ค.
abstract Pizza build();
- ์ค์ ๋ก Pizza ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ฐํํ๋ ๋ฉ์๋๋ก ์ถ์ ๋ฉ์๋๋ก, ํ์ ํด๋์ค์์๋ ๋ฐ๋์ ํ์ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋๋ก ๊ตฌํ์ด ๋์ด์ผ๊ฒ ์ต๋๋ค.
๊ตฌ์ฒด ํด๋์ค๋ฅผ ๋ณด๋ฉด ์ข ๋ ์ดํด๊ฐ ์ฌ์ธ์๋ ์๊ฒ ์ต๋๋ค. ์ด ์ถ์ํด๋์ค Pizza๋ฅผ ์์๋ฐ์ ๊ตฌ์ฒด ํด๋์ค๋ฅผ ๋ด ์๋ค.
๊ตฌ์ฒด ํด๋์ค์์๋ ์ถ์ ๋น๋๋ฅผ ์์๋ฐ์ ๊ตฌ์ฒด ๋น๋ ๊ตฌํ
package dw.chapter1.item2;
import java.util.Objects;
public class NewYorkPizza extends Pizza {
public enum Size {SMALL, MEDIUM, LARGE}
private final Size size;
public static class Builder extends Pizza.Builder<Builder> {
private final Size size;
public Builder(Size size) {
this.size = Objects.requireNonNull(size);
}
@Override
protected Builder self() {
return this;
}
@Override
public NewYorkPizza build() {
return new NewYorkPizza(this);
}
}
private NewYorkPizza(Builder builder) {
super(builder);
size = builder.size;
}
}
- ๊ฐ ํ์ ํด๋์ค์ ๋น๋๊ฐ ์ ์ํ build ๋ฉ์๋๋ ๋ฐ๋์ ๊ตฌ์ฒด ํ์ ํด๋์ค๋ฅผ ๋ฐํํ๋๋ก ์ ์ธํ๊ธฐ
- > NewYorkPizza.Builder๋ NewYork ํผ์๋ฅผ ๋ฐํ
- > XXXPizza.Builder๋ XXXPizza๋ฅผ ๋ฐํ
- self() ๋ฉ์๋๋ ์๊ธฐ ์์ ์ ๋ฆฌํดํ๋๋ก ํ๊ธฐ
- ํ์ ํด๋์ค์ ๋ฉ์๋๊ฐ ์์ ํด๋์ค์ ๋ฉ์๋๊ฐ ์ ์ํ ๋ฐํ ํ์ ์ด ์๋(์์ ์์๋ก๋ Pizza๋ฅผ ๋ฆฌํดํ๋ ๊ฒ์ด ์๋), ๊ทธ ํ์ ํ์ ์ ๋ฐํํ๋ ๊ธฐ๋ฅ์ ๊ณต๋ณ ๋ฐํ ํ์ดํ์ด๋ผ๊ณ ํ๋ค๊ณ ํฉ๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ด์ฉํ๋ฉด ํด๋ผ์ด์ธํธ๋ ํ๋ณํ์ ์ ๊ฒฝ์ฐ์ง ์๊ณ ๋น๋๋ฅผ ํธํ๊ฒ ์ฌ์ฉํ ์ ์๊ฒ ์ต๋๋ค.
+ NewYorkPizza์ ๊ฐ์ ๋งฅ๋ฝ์ ๊ตฌ์ฒด ํด๋์ค๋ฅผ ๋ง๋ ์์(SeoulPizza)์ ๋๋ค.
public class SeoulPizza extends Pizza {
private final boolean sauceInside;
public static class Builder extends Pizza.Builder<Builder> {
private boolean sauceInside = false; // ๊ธฐ๋ณธ๊ฐ
public Builder sauceInside() {
sauceInside = true;
return this;
}
@Override
protected Builder self() {
return this;
}
@Override
public SeoulPizza build() {
return new SeoulPizza(this);
}
}
private SeoulPizza(Builder builder) {
super(builder);
sauceInside = builder.sauceInside;
}
}
- ์ด์ ๋ ๊ตฌ์ฒด ํด๋์ค์ ์ถ์ ๋น๋์ ๊ตฌ์ฒด ๋น๋๋ฅผ ์ ์ฉํ ์ ์๊ฒ ์ต๋๋ค. ์ฝ๋๋ฅผ ๋ณด๊ฒ ์ต๋๋ค!
NewYorkPizza newYorkPizza = new NewYorkPizza
.Builder(SMALL)
.addTopping(SAUSAGE)
.addTopping(ONION)
.build();
SeoulPizza seoulPizza = new SeoulPizza
.Builder()
.addTopping(ONION)
.sauceInside()
.build();
- ์ด๋ ๊ฒ ๋น๋ ํจํด์ ์ ์ฉํ๋ฉด ๊ณ์ธตํ ํด๋์ค์์๋ ์ ์ฐํ๊ฒ ํ๋กํผํฐ๋ฅผ ์ค์ ํ ์ ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๋น๋ ํจํด ๋จ์
๋ฌผ๋ก ๋น๋ ํจํด์๋ ์ฅ์ ๋ง ์๋ ๊ฒ์ ์๋๋๋ค.
- ๋น๋ ํจํด์ ์ ์ฉํด์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๋ ค๋ฉด ๋น๋๋ถํฐ ๋ง๋ค์ด์ผ ํ๋ค๋ ์
- ์ฝ๋๊ฐ ์ฅํฉํ ๋งํผ ์ต์ ๋งค๊ฐ๋ณ์ 4๊ฐ์ด์์ ๋์ด์ผ ๊ฐ์ด์น๋ฅผ ํ๋ค๋ ์
- ๋ฌผ๋ก API๋ ์๊ฐ์ด ์ง๋ ์๋ก ๋งค๊ฐ๋ณ์๊ฐ ๋ง์์ง๋ค๋ ์ ์ ๊ณ ๋ คํ๋ฉด ๋น๋ ํจํด์ ๋จผ์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ข์ ์ ์๊ฒ ๋ค.
- Item1์์๋ ๋๋๊ณ ์ ํฉ๋ฉ๋ฅผ ๊ณ ๋ คํ๋ผ๊ณ ํ์์ง๋ง, ์ ์ ํ๋กํผํฐ๊ฐ ์ฆ๊ฐํจ์ ๋ฐ๋ผ ์์ฑ ๋ฐฉ๋ฒ ๋ํ ๋์ด๋ ๋งค๊ฐ๋ณ์๊ฐ ๋ง์์ง ์ฐ๋ ค๊ฐ ์๋ค๋ฉด ์ ์ด์ ๋น๋๋ก ์ค๊ณํ๋ ๊ฒ์ด ๋์ค์ ๊ณ ์์ ๋ ํ์ง ์์๊น .. ์ฑ ์ ์์ ์๊ฐ์ ๋๋ค.
- ํ์๋ Spring์์๋ ๋ณ๋์ ์ฌ์ ์์ ์์ด ๋กฌ๋ณต ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ง ์ถ๊ฐํ๋ค๋ฉด @Builder๋ง ๋ถ์ฌ์ฃผ๋ฉด ๋๋ ๊ทธ๋ฅ ๋น๋๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ข๋ค๊ณ ์๊ฐ๋ฉ๋๋ค.
ํ ์ค ์์ฝ
์์ฑ์, ์ ํฉ๋ฉ๊ฐ ์ฒ๋ฆฌํ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด ๋น๋๋ฅผ ์ ํํ๋ ๊ฒ์ด ๋ซ๋ค.
'๐ Backend > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ธ๋ก๊ทธ์ ์ ๋ณด
Study Repository
rlaehddnd0422