-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #267 from SujinEmilyCho/sujin
[#2][2๊ธฐ] ์์ฑ์์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด ๋น๋๋ฅผ ๊ณ ๋ คํ๋ผ
- Loading branch information
Showing
1 changed file
with
318 additions
and
0 deletions.
There are no files selected for viewing
318 changes: 318 additions & 0 deletions
318
2์ฅ/2_์์ฑ์์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด ๋น๋๋ฅผ ๊ณ ๋ คํ๋ผ_์กฐ์์ง.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,318 @@ | ||
# ์์ดํ 2. ์์ฑ์์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด ๋น๋๋ฅผ ๊ณ ๋ คํ๋ผ | ||
์ ์ ํฉํฐ๋ฆฌ์ ์์ฑ์๋ ์ ํ์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง์ ๋ ๋์ํ๊ธฐ ์ด๋ ต๋ค. ์ด๋ฐ ์ผ์ด์ค์ `์ ์ธต์ ์์ฑ์ ํจํด`, `์๋ฐ ๋น์ฆ ํจํด`, `๋น๋ ํจํด`์ ๊ณ ๋ คํด๋ณผ ์ ์๋ค. | ||
|
||
### ์ ์ธต์ ์์ฑ์ ํจํด(telescoping constructor pattern) | ||
|
||
- ํ์ ๋งค๊ฐ๋ณ์๋ง ๋ฐ๋ ์์ฑ์, ํ์ ๋งค๊ฐ๋ณ์์ ์ ํ ๋งค๊ฐ๋ณ์ 1๊ฐ๋ฅผ ๋ฐ๋ ์์ฑ์, ์ ํ ๋งค๊ฐ๋ณ์๋ฅผ 2๊ฐ๊น์ง ๋ฐ๋ ์์ฑ์, ..., ์ ํ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ถ ๋ฐ๋ ์์ฑ์๊น์ง ๋๋ ค๊ฐ๋ ๋ฐฉ์ | ||
- ํ์ฅํ๊ธฐ ์ด๋ ต๋ค | ||
- ๋งค๊ฐ๋ณ์๊ฐ ๋ง์์ง๋ฉด ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ์์ฑํ๊ฑฐ๋ ์ฝ๊ธฐ ์ด๋ ต๋ค | ||
|
||
```java | ||
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, fat, 0); | ||
} | ||
|
||
public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium) { | ||
this(servingSize, servings, 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; | ||
} | ||
} | ||
``` | ||
|
||
```java | ||
// ์ง๋ฐฉ(fat)์ 0์ ์์ฑํ ๊ฒ ์ฒ๋ผ ์ค์ ํ๊ธธ ์์น ์๋ ๋งค๊ฐ๋ณ์๊น์ง ๊ฐ์ ์ง์ ํด์ค์ผํ๋ค. | ||
NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27); | ||
``` | ||
|
||
### ์๋ฐ ๋น์ฆ ํจํด(JavaBeans pattern) | ||
|
||
- ๋งค๊ฐ๋ณ์๊ฐ ์๋ ์์ฑ์๋ก ๊ฐ์ฒด๋ฅผ ๋ง๋ ํ, ์ธํฐ(setter) ๋ฉ์๋๋ฅผ ํธ์ถํด ์ํ๋ ๋งค๊ฐ๋ณ์์ ๊ฐ์ ์ค์ ํ๋ ๋ฐฉ์ | ||
- ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ธฐ ์ฝ๊ณ ๊ฐ๋ ์ฑ์ด ์ข์์ง๋ค | ||
- ๊ฐ์ฒด๋ฅผ ํ๋ ๋ง๋ค๊ธฐ ์ํด ๋ฉ์๋๋ฅผ ์ฌ๋ฌ ๊ฐ ํธ์ถํด์ผ ํ๊ณ , ๊ฐ์ฒด๊ฐ ์์ ํ ์์ฑ๋๊ธฐ ์ ๊น์ง๋ ์ผ๊ด์ฑ(consistency)์ด ๋ฌด๋์ง ์ํ์ ๋์ธ๋ค(์์ฑ์๋ฅผ ํตํ ์ ํจ์ฑ ๊ฒ์ฌ๋ผ๋ ์ฅ์น๊ฐ ์ฌ๋ผ์ง) | ||
- ๋ถ๋ณ์ผ๋ก ๋ง๋ค ์ ์์ผ๋ฉฐ ์ค๋ ๋ ์์ ์ฑ์ ์ํ ์ถ๊ฐ ์์ ์ด ํ์ํ๋ค | ||
|
||
```java | ||
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 val) { servingSize = val; } | ||
public void setServings(int val) { servings = val; } | ||
public void setCalories(int val) { calories = val; } | ||
public void setFat(int val) { fat = val; } | ||
public void setSodium(int val) { sodium = val; } | ||
public void setCarbohydrate(int val) {carbohydrate = val; } | ||
} | ||
``` | ||
|
||
```java | ||
// ์ ์ธต์ ์์ฑ์ ํจํด์ ๋นํด ํ์ฅํ๊ธฐ ์ฝ๊ณ , ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ธฐ ์ฝ๊ณ , ๊ฐ๋ ์ฑ์ด ์ข์์ง๋ค. | ||
NutritinFacts cocaCola = new NutritionFacts(); | ||
cocaCola.setServingSize(240); | ||
cocaCola.setServings(8); | ||
cocaCola.setCalories(100); | ||
cocaCola.setSodium(35); | ||
cocaCola.setCarbohydrate(27); | ||
``` | ||
|
||
### ๋น๋ ํจํด | ||
|
||
- ํ์ ๋งค๊ฐ๋ณ์์ ์์ฑ์(ํน์ ์ ์ ํฉํฐ๋ฆฌ)๋ฅผ ํตํด ๊ฐ์ฒด ์์ฑ์ ์ํ ๋น๋ ๊ฐ์ฒด๋ฅผ ์ป๊ณ , ๋น๋ ๊ฐ์ฒด๊ฐ ์ ๊ณตํ๋ ์ผ์ข ์ ์ธํฐ ๋ฉ์๋๋ค๋ก ์ํ๋ ์ ํ ๋งค๊ฐ๋ณ์๋ฅผ ์ค์ . ๋ง์ง๋ง์ผ๋ก build ๋ฉ์๋๋ฅผ ํธ์ถํด (๋ณดํต์ ๋ถ๋ณ์ธ) ํ๊ฒ ๊ฐ์ฒด๋ฅผ ์ป๋ ๋ฐฉ์ | ||
- ๋น๋์ ์ธํฐ ๋ฉ์๋๋ค์ ๋น๋ ์์ ์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ๋ฉ์๋ ์ฐ์(method chaining)๊ฐ ๊ฐ๋ฅํ๋ค(ํ๋ฃจ์ธํธ API๋ผ๊ณ ๋ ํ๋ค) | ||
- ์ ์ธต์ ์์ฑ์ ํจํด์ ์์ ์ฑ(์ ํจ์ฑ ๊ฒ์ฌ)๊ณผ ์๋ฐ ๋น์ฆ ํจํด์ ๊ฐ๋ ์ฑ์ด๋ผ๋ ์ฅ์ ์ ๊ฐ์ง๋ค | ||
- ๋น๋ ํ๋๋ก ์ฌ๋ฌ ๊ฐ์ฒด๋ฅผ ์ํํ๋ฉฐ ๋ง๋ค ์ ์๊ณ , ๋งค๊ฐ๋ณ์์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๋ฑ ์ ์ฐํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅ | ||
- ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๋น๋๋ถํฐ ๋ง๋ค์ด์ผํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ๋ฏผ๊ฐํ ์ํฉ์์ ๋ฌธ์ ๊ฐ ๋ ์ ์๋ค | ||
- ์ ์ธต์ ์์ฑ์ ํจํด๋ณด๋ค ์ฝ๋๊ฐ ์ฅํฉํด์ ๋งค๊ฐ๋ณ์๊ฐ 4๊ฐ ์ด์์ผ ๋ ์ ์ฉํ | ||
|
||
```java | ||
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 = serginsSize; | ||
this.servings = servings; | ||
} | ||
|
||
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 NutirionFacts(Builder builder) { | ||
servingSize = builder.servingSize; | ||
servings = builder.servings; | ||
calories = builder.calories; | ||
fat = builder.fat; | ||
sodium = builder.fat; | ||
carbohydrate = builder.carbohydrate; | ||
} | ||
} | ||
``` | ||
|
||
```java | ||
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8) | ||
.calories(100) | ||
.sodium(35) | ||
.carbohydrate(27) | ||
.build(); | ||
``` | ||
|
||
๋ถ๋ณ(immutable) vs ๋ถ๋ณ์(invariant) | ||
- ๋ถ๋ณ: ์ด๋ ํ ๋ณ๊ฒฝ๋ ํ์ฉํ์ง ์๋๋ค๋ ๋ป, ์ฃผ๋ก ๋ณ๊ฒฝ์ ํ์ฉํ๋ ๊ฐ๋ณ ๊ฐ์ฒด์ ๊ตฌ๋ถํ๋ ์ฉ๋๋ก ์ฐ์ธ๋ค. String์ด ๋ํ์ ์ธ ๋ถ๋ณ ๊ฐ์ฒด | ||
- ๋ถ๋ณ์: ํ๋ก๊ทธ๋จ์ด ์คํ๋๋ ๋์, ํน์ ์ ํด์ง ๊ธฐ๊ฐ ๋์ ๋ฐ๋์ ๋ง์กฑํด์ผ ํ๋ ์กฐ๊ฑด. ๋ณ๊ฒฝ์ ํ์ฉํ ์๋ ์์ผ๋ ์ฃผ์ด์ง ์กฐ๊ฑด ๋ด์์๋ง ํ์ฉํ๋ค๋ ๋ป. ์๋ฅผ ๋ค์ด, ๋ฆฌ์คํธ์ ํฌ๊ธฐ๋ ๋ฐ๋์ 0 ์ด์์ด์ด์ผ ํ๋, ํ ์๊ฐ์ด๋ผ๋ ์์ ๊ฐ์ด ๋๋ค๋ฉด ๋ถ๋ณ์์ด ๊นจ์ง ๊ฒ | ||
|
||
### ๋น๋ ํจํด - ๊ณ์ธต์ ๋น๋ | ||
|
||
- ๋น๋ ํจํด์ ๊ณ์ธต์ ์ผ๋ก ์ค๊ณ๋ ํด๋์ค์ ํจ๊ป ์ฐ๊ธฐ ์ข๋ค | ||
- ์ถ์ ํด๋์ค์๋ ์ถ์ ๋น๋๋ฅผ, ๊ตฌ์ฒด ํด๋์ค์๋ ๊ตฌ์ฒด ๋น๋๋ฅผ ์์ฑ | ||
- ํ์ ํด๋์ค์ build ๋ฉ์๋๋ ๊ตฌ์ฒด ํ์ ํด๋์ค๋ฅผ ๋ฐํํ๋๋ก ์ ์ธ(๊ณต๋ณ ๋ฐํ ํ์ดํ - covariant return typing) | ||
- ์์ฑ์์ ๋ฌ๋ฆฌ ๊ฐ๋ณ ์ธ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ๋ฌ ๊ฐ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค(addTopping ๋ฉ์๋) | ||
|
||
```java | ||
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(); | ||
} | ||
|
||
abstarct Pizza build(); | ||
|
||
protected abstract T self(); // ํ์ ํด๋์ค์์ ์ด ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ ํด์ this๋ฅผ ๋ฐํ | ||
} | ||
|
||
Pizza(Builder<?> builder) { | ||
toppings = builder.toppings.clone(); | ||
} | ||
} | ||
``` | ||
|
||
```java | ||
public class NyPizza 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 | ||
public NyPizza build() { | ||
return new NyPizza(this); | ||
} | ||
|
||
@Override | ||
protected Builder self() { | ||
return this; | ||
} | ||
|
||
public NyPizza(Builder builder) { | ||
super(builder); | ||
size = builder.size; | ||
} | ||
} | ||
} | ||
``` | ||
|
||
```java | ||
public class Calzone extends Pizza { | ||
private final boolean sauceInside; | ||
|
||
public static class Builder extends Pizza.Builder<Builder> { | ||
private boolean sauceInsice = false; | ||
|
||
public Builder sauceInside() { | ||
sauceInsdie = true; | ||
return this; | ||
} | ||
|
||
@Override | ||
public Calzone build() { | ||
return new Calzone(this); | ||
} | ||
|
||
@Override | ||
protected Builder self() { | ||
return this; | ||
} | ||
|
||
private Calzone(Builder builder) { | ||
super(builder); | ||
sauceInside = builder.sauceInside; | ||
} | ||
} | ||
} | ||
``` | ||
|
||
```java | ||
NyPizza pizza = new NyPizza.Builder(SMALL) | ||
.addTopping(SAUSAGE) | ||
.addTopping(ONION) | ||
.build(); | ||
|
||
Calzone pizza = new Calzone.Builder() | ||
.addTopping(HAM) | ||
.sauceInside() | ||
.build(); | ||
``` | ||
|
||
### ์ถ๊ฐ ์์ | ||
|
||
```java | ||
public class User { | ||
private final int id; // ํ์ | ||
private final String name; //ํ์ | ||
private final Set<String> nicknames; | ||
private final int phone; | ||
private final String address; | ||
|
||
private User(Builder builder) { | ||
this.id = builder.id; | ||
this.name = builder.name; | ||
this.nicknames = builder.nicknames; | ||
this.phone = builder.phone; | ||
this.address = builder.address; | ||
} | ||
|
||
public static class Builder { | ||
private final int id; // ํ์ | ||
private final String name; //ํ์ | ||
private final Set<String> nicknames = new HashSet<>(); | ||
private int phone; | ||
private String address; | ||
|
||
public Builder(int id, String name) { | ||
this.id = id; | ||
this.name = name; | ||
} | ||
|
||
public Builder nickname(String nickname) { | ||
this.nicknames.add(nickname); | ||
return this; | ||
} | ||
|
||
public Builder phone(int phone) { | ||
this.phone = phone; | ||
return this; | ||
} | ||
|
||
public Builder address(String address) { | ||
this.address = address; | ||
return this; | ||
} | ||
|
||
public User build() { | ||
return new User(this); | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### ์ ๋ฆฌ | ||
|
||
์์ฑ์๋ ์ ์ ํฉํฐ๋ฆฌ๊ฐ ์ฒ๋ฆฌํด์ผ ํ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๋ค๋ฉด ๋น๋ ํจํด์ ์ ํํ๋ ๊ฒ ๋ ๋ซ๋ค. ๋งค๊ฐ๋ณ์ ์ค ๋ค์๊ฐ ํ์๊ฐ ์๋๊ฑฐ๋ ๊ฐ์ ํ์ ์ด๋ฉด ํนํ ๋ ๊ทธ๋ ๋ค. ๋น๋๋ ์ ์ธต์ ์์ฑ์๋ณด๋ค ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ์ฝ๊ณ ์ฐ๊ธฐ๊ฐ ํจ์ฌ ๊ฐ๊ฒฐํ๊ณ , ์๋ฐ๋น์ฆ๋ณด๋ค ํจ์ฌ ์์ ํ๋ค. |