item 2 leekyunghee - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
- ์ ์ ํฉํ ๋ฆฌ์ ์์ฑ์์๋ ์ ํ์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง์ ๋ ์ ์ ํ ๋์ํ๊ธฐ ์ด๋ ต๋ค๋ ์ ์ฝ์ด ์๋ค.
- ํ์ ๋งค๊ฐ๋ณ์๋ง ๋ฐ๋ ์์ฑ์
- ํ์ ๋งค๊ฐ๋ณ์์ ์ ํ ๋งค๊ฐ๋ณ์ 1๊ฐ๋ฅผ ๋ฐ๋ ์์ฑ์
- ์ ํ ๋งค๊ฐ๋ณ์๋ฅผ 2๊ฐ๊น์ง ๋ฐ๋ ์์ฑ์ ํํ
- ์ ํ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ถ๋ค ๋ฐ๋ ์์ฑ์๋ก ๋๋ ค๊ฐ๋ ๋ฐฉ์
๋ค์ ์์ ์ฝ๋๋ฅผ ์ดํด๋ณด์.
public class NutritionFacts {
private final int servingSize; // (ml/1ํ ์ ๊ณต๋) ํ์
private final int servings; // (ํ/์ด nํ ์ ๊ณต๋) ํ์
private final int calories; // (1ํ ์ ๊ณต๋๋น) ์ ํ
private final int fat; // (g/1ํ ์ ๊ณต๋) ์ ํ
private final int sodium; // (mg/1ํ ์ ๊ณต๋) ์ ํ
private final int carbohydrate; // (g/1ํ ์ ๊ณต๋) ์ ํ
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, fat, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium) {
this(servingSize, servings, calories, fat, sodium, 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 cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);
๋ณดํต ์ด๋ฐ ์์ฑ์๋ ์ฌ์ฉ์๊ฐ ์ค์ ํ๊ธธ ์์น ์๋ ๋งค๊ฐ๋ณ์๊น์ง ํฌํจํ๊ธฐ ์ฌ์. ๊ฐ์๊ฐ ๋์ฑ ๋์ด๋๊ฑฐ๋ ์ค์ ํ๊ธฐ ์์น์๋ ๋งค๊ฐ๋ณ์๊น์ง ๊ฐ์ ์ง์ ํด์ค์ผํ๋ ๋ฒ๊ฑฐ๋ก์์ด ์๋ค. ์ ์ธต์ ์์ฑ์ ํจํด๋ ์ธ ์๋ ์์ง๋ง ๋ง์์ง ๊ฒฝ์ฐ ํด๋ผ์ด์ด์ธํธ ์ฝ๋๋ฅผ ์์ฑํ๊ฑฐ๋ ์ฝ๊ธฐ ์ด๋ ต๋ค.
- ์ ํ ๋งค๊ฐ๋ณ์๊ฐ ๋ง์ ๋ ํ์ฉํ ์ ์๋ ๋์
- ๋งค๊ฐ๋ณ์๊ฐ ์๋ ์์ฑ์๋ก ๊ฐ์ฒด๋ฅผ ๋ง๋ ํ, ์ธํฐ(setter) ๋ฉ์๋๋ค์ ํธ์ถํด ์ํ๋ ๋งค๊ฐ๋ณ์์ ๊ฐ์ ์ค์ ํ๋ ๋ฐฉ์
- ์ ์ธต์ ์์ฑ์ ํจํด๋ณด๋ค ์ฝ๋๊ฐ ๊ธธ์ด์ง์ง๋ง ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ธฐ ์ฝ๊ณ ๊ทธ ๊ฒฐ๊ณผ ๋ ์ฝ๊ธฐ ์ฌ์ด ์ฝ๋๊ฐ ๋์๋ค.
NutritionFacts cocaCola = new NutritionFacts();
cocaChola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);
์๋ฐ๋น์ฆ ํจํด์ ๋จ์
- ๊ฐ์ฒด ํ๋๋ฅผ ๋ง๋ค๋ ค๋ฉด ๋ฉ์๋๋ฅผ ์ฌ๋ฌ ๊ฐ ํธ์ถํด์ผ ํ๊ณ ๊ฐ์ฒด๊ฐ ์์ ํ ์์ฑ๋๊ธฐ ์ ๊น์ง๋ ์ผ๊ด์ฑ(consistency)์ด ๋ฌด๋์ง ์ํ์ ๋์ด๊ฒ ๋๋ค.
- ํด๋์ค๋ฅผ ๋ถ๋ณ(์์ดํ 17)์ผ๋ก ๋ง๋ค ์ ์์ผ๋ฉฐ ์ค๋ ๋ ์์ ์ฑ์ ์ป์ผ๋ ค๋ฉด ์ถ๊ฐ ์์ ์ด ํ์ํ๋ค.
- ์ ์ธต์ ์์ฑ์ ํจํด์ ์์ ์ฑ๊ณผ ์๋ฐ ๋น์ฆ ํจํด์ ๊ฐ๋ ์ฑ์ ๊ฒธ๋น
- ํด๋ผ์ด์ธํธ๋ ํ์ํ ๊ฐ์ฒด๋ฅผ ์ง์ ๋ง๋๋ ๋์ , ํ์ ๋งค๊ฐ๋ณ์๋ง์ผ๋ก ์์ฑ์(ํน์ ์ ์ ํฉํฐ๋ฆฌ)๋ฅผ ํธ์ถํด ๋น๋ ๊ฐ์ฒด๋ฅผ ์ป๋๋ค.
- ๋น๋ ๊ฐ์ฒด๊ฐ ์ ๊ณตํ๋ ์ผ์ข ์ ์ธํฐ ๋ฉ์๋๋ค๋ก ์ํ๋ ์ ํ ๋งค๊ฐ๋ณ์๋ค์ ์ค์ ํ๋ค.
- ๋งค๊ฐ๋ณ์๊ฐ ์๋ 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 {
// ํ์ ๋งค๊ฐ๋ณ์
private final int servingSize;
private final int servings;
// ์ ํ ๋งค๊ฐ๋ณ์ - ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ด๊ธฐํ ํ๋ค.
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(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
}
}
NutritionFacts ํด๋์ค๋ ๋ถ๋ณ์ด๋ฉฐ ๋ชจ๋ ๋งค๊ฐ๋ณ์์ ๊ธฐ๋ณธ๊ฐ๋ค์ ํ๊ณณ์ ๋ชจ์๋๋ค. ๋น๋์ ์ธํฐ ๋ฉ์๋๋ค์ ๋น๋ ์์ ์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์ฐ์์ ์ผ๋ก ํธ์ถํ ์ ์๋ค. ๋ฉ์๋ ํธ์ถ์ด ํ๋ฅด๋ฏ ์ฐ๊ฒฐ๋๋ค๋ ๋ป์ ํ๋ฃจ์ธํธ API(fluent API) ํน์ ๋ฉ์๋ ์ฐ์(mehod chaining)
// ์ค์ ์์ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ํด๋ผ์ด์ธํธ ์ฝ๋
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();
๋น๋ ํจํด์ ์ค์นผ๋ผ์ ์๋ ๋ช ๋ช ๋ ์ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ํ๋ด๋ธ ๊ฒ ์๋ชป๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ต๋ํ ์ผ์ฐ ๋ฐ๊ฒฌํ๋ ค๋ฉด ๋น๋์ ์์ฑ์์ ๋ฉ์๋์์ ์ ๋ ฅ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฒ์ฌํ๊ณ build ๋ฉ์๋๊ฐ ํธ์ถํ๋ ์์ฑ์์์ ์ฌ๋ฌ ๋งค๊ฐ๋ณ์์ ๊ฑธ์น ๋ถ๋ณ์์ ๊ฒ์ฌํ์. ๊ณต๊ฒฉ์ ๋๋นํด ์ด๋ฐ ๋ถ๋ณ์์ ๋ณด์ฅํ๋ ค๋ฉด ๋น๋๋ก๋ถํฐ ๋งค๊ฐ๋ณ์๋ฅผ ๋ณต์ฌํ ํ ํจ๋น ๊ฐ์ฒด ํ๋๋ค๋ ๊ฒ์ฌํด์ผํ๋ค. (์์ดํ 50) ๋งค๊ฐ๋ณ์๊ฐ ์๋ชป๋์๋์ง ์๋ ค์ฃผ๋ ๋ฉ์ธ์ง๋ฅผ ๋ด์ IllegalArgumentException์ ๋์ง๋ฉด ๋๋ค. ๋น๋ ํจํด์ ๊ณ์ธต์ ์ผ๋ก ์ค๊ณ๋ ํด๋์ค์ ํจ๊ป ์ฐ๊ธฐ์ ์ข๋ค. ๊ฐ ๊ณ์ธต์ ํด๋์ค์ ๊ด๋ จ ๋น๋๋ฅผ ๋ฉค๋ฒ๋ก ์ ์ํ์. ์ถ์ ํด๋์ค๋ ์ถ์ ๋น๋๋ฅผ, ๊ตฌ์ฒด ํด๋์ค๋ ๊ตฌ์ฒด ๋น๋๋ฅผ ๊ฐ๊ฒ ํ๋ค.
// ๊ณ์ธต์ ์ผ๋ก ์ค๊ณ๋ ํด๋์ค์ ์ ์ด์ธ๋ฆฌ๋ ๋น๋ ํจํด
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) {
addToppings.add(Objects.requireNonNULL(topping));
return self();
}
// ํ์ ํด๋์ค๋ ์ด ๋ฉ์๋๋ฅผ ์ฌ์ ์ ํ์ฌ "this"๋ฅผ ๋ฐํํ๋๋ก ํด์ผํ๋ค.
abstract Pizza build();
protected abstract T self();
}
Pizza(Builder<?> builder) {
toppings = builder.toppings.clone(); // Item 50์ฐธ์กฐ
}
}
Pizza.Builder ํด๋์ค๋ ์ฌ๊ท์ ํ์ ํ์ (์์ดํ 30)์ ์ด์ฉํ๋ ์ ๋ค๋ฆญ ํ์ ์ด๋ค. ์ฌ๊ธฐ์ ์ถ์ ๋ฉ์๋์ธ self๋ฅผ ๋ํด ํ์ ํด๋์ค์์๋ ํ๋ณํํ์ง ์๊ณ ๋ ๋ฉ์๋ ์ฐ์๋ฅผ ์ง์ํ ์ ์๋ค. self ํ์ ์ด ์๋ ์๋ฐ๋ฅผ ์ํ ์ด ์ฐํ ๋ฐฉ๋ฒ์ ์๋ฎฌ๋ ์ดํธํ ์ ํ ํ์ ๊ด์ฉ๊ตฌ๋ผ ํ๋ค.
์์ฑ์๋ก๋ ๋๋ฆด ์ ์๋ ์ฌ์ํ ์ด์ ์ผ๋ก ๋น๋๋ฅผ ์ด์ฉํ๋ฉด ๊ฐ๋ณ์ธ์(varargs) ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ๋ฌ๊ฐ ์ฌ์ฉํ ์ ์๋ค. ๊ฐ๊ฐ์ ์ ์ ํ ๋ฉ์๋๋ก ๋๋ ์ ์ธํ๋ฉด ๋๋ค. ๋ฉ์๋๋ฅผ ์ฌ๋ฌ ๋ฒ ํธ์ถํ๋๋ก ํ๊ณ ๊ฐ ํธ์ถ ๋ ๋๊ฒจ์ง ๋งค๊ฐ๋ณ์๋ค์ ํ๋์ ํ๋๋ก ๋ชจ์ ์๋ ์๋ค. ๋น๋ ํจํด์ ๋น๋ ํ๋๋ก ์ฌ๋ฌ ๊ฐ์ฒด๋ฅผ ์ํํ๋ฉด์ ๋ง๋ค ์ ์๊ณ ๋น๋์ ๋๊ธฐ๋ ๋งค๊ฐ๋ณ์์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์๋ ์๋ค. ๊ฐ์ฒด๋ง๋ค ๋ถ์ฌ๋๋ ์ผ๋ จ๋ฒํธ์ ๊ฐ์ ํน์ ํ๋๋ ๋น๋๊ฐ ์์์ ์ฑ์ฐ๋๋ก ํ ์๋ ์๋ค.
- ๊ฐ์ฒด๋ฅผ ๋ง๋ค๋ ค๋ฉด ๊ทธ์ ์์ ๋น๋๋ถํฐ ๋ง๋ค์ด์ผํ๋ค.
- ๋น๋ ์์ฑ ๋น์ฉ์ด ํฌ์ง๋ ์์ง๋ง ์ฑ๋ฅ์ ๋ฏผ๊ฐํ ์ํฉ์์๋ ๋ฌธ์ ๊ฐ ๋ ์์๋ค.
- ์ฝ๋๊ฐ ์ฅํฉํด์ ๋งค๊ฐ๋ณ์๊ฐ 4๊ฐ๋ ๋์ด์ผํ๋ค.
ํต์ฌ ์ ๋ฆฌ
๋งค๊ฐ๋ณ์ ์ค ๋ค์๊ฐ ํ์๊ฐ ์๋๊ฑฐ๋ ๊ฐ์ ํ์
์ธ ๊ฒฝ์ฐ ํน์ ์์ฑ์๋ ์ ์ ํฉํฐ๋ฆฌ๊ฐ ์ฒ๋ฆฌํด์ผ ํ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด ๋น๋ ํจํด์ ์ ํํ๋๊ฒ ๋ซ๋ค.
๋น๋๋ ์ ์ธต์ ์์ฑ์ ๋ณด๋ค ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ์ฝ๊ธฐ ์ฝ๊ณ ๊ฐ๊ฒฐํ๋ฉฐ ์๋ฐ ๋น์ฆ ๋ณด๋ค ํจ์ฌ ์์ ํ๋ค.