π§λ€μ΄κ°κΈ°μ ..
[!NOTE]
ν΄λμ€κ° κ°μ§κ³ μλ νλ λ³μκ° λ§μ λ,
μ νμ μΈ νλλ§ μ΄κΈ°ννλ μμ±μλ₯Ό λ§λ€λ €λ©΄ μ΄λ»κ² ν΄μΌν κΉ?
public class Character {
private final String name;
private final int faceSize;
private final int neckSize;
private final int bodySize;
private final int armSize;
private final int legSize;
public Character(String name) {
this(name, 0);
}
...
}
λ§μ½ μ μ ν©ν 리λ₯Ό μ¬μ©νλ€λ©΄ μ νμ λ§€κ°λ³μκ° λ§λ€λ©΄ μ¬μ©νκΈ°κ° νλ€ κ²μ΄λ€.
λ°λΌμ μ΄λ¬ν λ¬Έμ λ₯Ό ν΄κ²°νκ³ μ μΈ κ°μ§ ν¨ν΄μ λν΄ μμλ³Ό κ²μ΄λ€.
1οΈβ£ μ μΈ΅μ μμ±μ ν¨ν΄(telescoping constructor pattern)
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ν μ 곡λ) μ ν
μμ κ°μ΄ νμ λ§€κ°λ³μμ μ ν λ§€κ°λ³μκ° μλ€κ³ κ°μ νμ.
μ΄λ μ μΈ΅μ μμ±μ ν¨ν΄μ΄λ.
- νμ λ§€κ°λ³μλ§ λ°λ μμ±μ
- νμ λ§€κ°λ³μ + μ ν λ§€κ°λ³μ 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;
}
}
μμ κ°μ λ°©μλλ‘ λ§€κ°λ³μλ₯Ό μ μ λλ €κ°λ©° this()λ₯Ό μ΄μ©ν μ μΈ΅μ μμ±μ ν¨ν΄, μμ±μ 체μ΄λμ μ΄μ©νλ€.
βοΈ λ¨μ
- λ§€κ°λ³μκ° λμ΄λ μλ‘ μμ±μκ° λ§μμ§λ€.
κ°λ μ± μ ν
- λ³΄ν΅ 0 κ°μ κΈ°λ³Έκ°μΌλ‘ λ€λ₯Έ λ§€κ°λ³μμ κ°μ μ±μ΄λ€.
- λͺ λ²μ§Έ μΈμκ° μ΄λ€ κ°μ μλ―Ένλμ§ μκΈ° μ΄λ ΅λ€.
κ°μ μκ·Έλμ²μ μμ±μ
λ λ§λ€μ§ λͺ»νλ―λ‘ μλ²½ν μ μ΄λ₯Ό ν μ μλ€.
2οΈβ£ μλ°λΉμ¦ ν¨ν΄(JavaBeans pattern)
π© μλ°λΉμ΄λ?
μλ°λΉ : μλ°λΉ(JavaBean)μ μλ°μμ μ¬μ¬μ© κ°λ₯ν μννΈμ¨μ΄ μ»΄ν¬λνΈλ₯Ό λ§λ€κΈ° μν νμ€μ λ°λ₯΄λ ν΄λμ€μ΄λ€.
νΉμ§
κΈ°λ³Έ μμ±μ μ 곡
- JavaBean ν΄λμ€λ κΈ°λ³Έ μμ±μ(νλΌλ―Έν°κ° μλ μμ±μ)λ₯Ό λ°λμ ν¬ν¨ν΄μΌν¨
νλ‘νΌν° μ κ·Όμ λ©μλ
- Getter
- Setter
μ§λ ¬ν κ°λ₯
- java.io.Serializable μΈν°νμ΄μ€λ₯Ό ꡬν
μΊ‘μν
- λͺ¨λ νλ‘νΌν°λ privateλ‘ μ μΈ
π’ μλ°λΉμ¦ ν¨ν΄?
μλ°λΉμ¦ ν¨ν΄: λ§€κ° λ³μκ° μλ μμ±μ (κΈ°λ³Έ μμ±μ)λ‘ κ°μ²΄λ₯Ό λ§λ ν setter λ©μλλ₯Ό νΈμΆνμ¬ μνλ λ§€κ°λ³μμ κ°μ μ€μ νλ λ°©μμ΄λ€.
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() {
}
// setter
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;
}
}
μμ κ°μ΄ κΈ°λ³Έμμ±μλ₯Ό νλ λκ³ λλ¨Έμ§μ νλ‘νΌν°μ λν΄μλ Setterλ‘ μ§μ ν μ μκ² κ΅¬ννλ λ°©μμ΄λ€.
βοΈ μ₯μ
- μΈμ€ν΄μ€ μμ±μ΄ κ°λ¨ν΄μ§λ€.
- κΈ°λ³Έ μμ±μλ§μΌλ‘λ κ°μ²΄λ₯Ό μμ±ν μ μλ€.
- νμν λ§€κ°λ³μλ§ μΈν
ν μ μλ€.
- μμ±μ 체μ΄λκ³Ό λ€λ₯΄κ² μ νμ μΌλ‘ λ§€κ°λ³μλ₯Ό μΈν ν μ μλ€.
- κ°λ μ±μ΄ μ’λ€.
βοΈ λ¨μ
- νμμ μΈ λ§€κ°λ³μλ₯Ό μ§μ ν μ μλ€.
- νμλ‘ μ€μ ν΄μ€μΌ νλ νλκ° μ΄κΈ°νλμ§ μκ³ κ°μ²΄κ° μμ±λ μ¬μ§κ° λλ€.
- μμ ν κ°μ²΄λ₯Ό λ§λ€κΈ° μν΄μλ μ¬λ¬ κ°μ setter λ©μλλ₯Ό νΈμΆν΄μΌνλ€.
- μ΄λ€ ν setter λ©μλλ₯Ό λΉΌλ¨Ήμ΄μ κ°μ²΄κ° λΆμμ ν μνλ‘ μ¬μ©λ μ¬μ§κ° μλ€.
- ν΄λμ€λ₯Ό
λΆλ³
μΌλ‘ λ§λ€ μ μλ€.- setter λ©μλμ μΉλͺ μ μΈ λ¨μ μ μΈλΆμμ ν΄λμ€μ νλ‘νΌν°λ₯Ό μμλ‘ λ°κΏ μ μλ€λ μ μ΄λ€.
κ°μ²΄ νλ¦¬μ§ κΈ°μ
λ‘ λ³΄μκ°λ₯νμ§λ§ νμ μμλ μ μμ
public void setLegSize(int legSize) {
validateSetter();
this.legSize = legSize;
}
private void validateSetter() {
if (freeze) {
throw new IllegalStateException("λμ΄μ νλλ₯Ό μ€μ ν μ μμ΅λλ€.");
}
}
public void freeze() {
freeze = true;
}
- μμ κ°μ λ°©μμΌλ‘ freezeλ₯Ό ν λ² νΈμΆνλ©΄ setter λ©μλ μ¬μ©μ΄ λΆκ°λ₯νλ€.
3οΈβ£ λΉλ ν¨ν΄(Builder pattern)
[!NOTE]
μ μΈ΅μ μμ±μ ν¨ν΄κ³Ό μλ°λΉμ¦ μμ±μ ν¨ν΄μ λ¨μ μ 보μν μ μλ λ°©μ
λΉλν¨ν΄μ μ리λ λ€μκ³Ό κ°μ΅λλ€.
- μμ±μ(νΉμ μ μ ν©ν 리) λ©μλλ₯Ό νΈμΆν΄ νμ λ§€κ°λ³μλ§μΌλ‘ λΉλ κ°μ²΄λ₯Ό μ»μ΅λλ€.
- λΉλ κ°μ²΄κ° μ 곡νλ μΌμ’
μ
Setter λ©μλ
λ€λ‘ μνλ μ ν λ§€κ°λ³μλ₯Ό μ ννλ€. - λ§μ§λ§μΌλ‘ λ§€κ°λ³μκ° μλ
build λ©μλ
λ₯Ό νΈμΆν΄ νμνλΆλ³μ κ°μ²΄
λ₯Ό μ»λ λ°©μμ΄λ€.
public class NutritionFacts {
// λΉλ ν¨ν΄(Builder pattern)
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 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;
}
}
[!NOTE]
λΉλ ν΄λμ€λ λ³΄ν΅ μμ±ν ν΄λμ€ μμ μ μ λ©€λ² ν΄λμ€λ‘ λ§λ λ€.
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
.calories(100).sodium(35).carbohydrate(27).build();
μμ κ°μ΄ Builder
μ Setter λ©μλ
λ€μ this() μ°μ°μ
λ₯Ό ν΅ν μμ μ λ°ννκΈ° λλ¬Έμ μ°μμ μΌλ‘ μ¬μ©μ΄ κ°λ₯νλ€.
(=ν루μΈνΈ API(fluent API) νΉμ λ©μλ μ°μ(method chaining))
βοΈ μ₯μ
- μ μΈ΅μ μμ±μ ν¨ν΄λ³΄λ€ ν΄λΌμ΄μΈνΈ μ
μ₯μμ ν¨μ¬ μ΄ν΄νκΈ° μ½λ€.
- μμ±μμ λ§€κ° λ³μλ₯Ό ν΅ν΄ νμμ μΈ νλ‘νΌν°κ° 무μμΈμ§ νμ κ°λ₯
public class NutritionFacts { // λΉλ ν¨ν΄(Builder pattern) private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate;
- μλ°λΉμ¦ ν¨ν΄λ³΄λ€ μμ μ μ΄λ€.
- λ©μλ 체μ΄λ λμ μμ±λλ κ°μ²΄λ λͺ¨λ νλκ° finalμΈ ‘λΆλ³ κ°μ²΄’ λ‘ λ°νλ°μ μ μλ€.
- λ§€κ°λ³μμ κ°λ€μ μ κΈ°μ μΌλ‘ μ€μ ν΄μ€ μ μλ€.
- κ°λ³μΈμ λ³μλ₯Ό μ¬λ¬ κ° μ¬μ©ν μ μλ€.
- Builder ν΄λμ€μμ Setter λ©μλλ₯Ό μ¬λ¬ κ°λ‘ νμ₯μν΄μ λ°λΌ κ°λ₯νλ€.
- λ©μλ μ¬λ¬ κ°λ‘λΆν° λ°μ κ°λ€μ ν νλλ‘ λͺ¨μ μ μλ€.
- λ©μλ 체μ΄λμ ν΅ν΄ λ§€κ°λ³μμ κ°μ νλμ© ν΄λΉ νλμ μΆκ°ν μ μλ€.
- κ°λ³μΈμ λ³μλ₯Ό μ¬λ¬ κ° μ¬μ©ν μ μλ€.
βοΈ λ¨μ
- μ±λ₯μ λ―Όκ°ν μν©μμ λ¬Έμ κ° λ μ μλ€.
- μ½λλ§ λ΄λ ν¨μ¬ κΈΈμ΄μ‘μΌλ..
- λ§€κ°λ³μκ° λ§μμλ‘ μμ λ¨μ μ μμμν¬ μ μλ€..
- ꡬννκΈ°κ° μ΄λ ΅λ€.
- μ΄μ λν ν΄κ²°μ±
μΌλ‘λ
@builder
둬볡 μ΄λ Έν μ΄μ μ μ¬μ©ν μ μλ€.
- μ΄μ λν ν΄κ²°μ±
μΌλ‘λ
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
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;
}
Builder μ΄λ
Έν
μ΄μ
μ μ μ©νλ©΄ μμ κ°μ΄ μ½λκ° κ°κ²°ν΄μ§λ€.
κ·Έλ¬λ Builder ν¨ν΄μλ μΉλͺ
μ μΈ λ¨μ μ΄ μλ€.
μ»΄νμΌλ μ½λλ₯Ό μ΄ν΄λ³΄λ©΄ λ€μκ³Ό κ°λ€.
import java.util.Objects;
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;
// Getter λ©μλ (둬볡μ @Getterμ μν΄ μμ±λ¨)
public int getServingSize() {
return servingSize;
}
public int getServings() {
return servings;
}
public int getCalories() {
return calories;
}
public int getFat() {
return fat;
}
public int getSodium() {
return sodium;
}
public int getCarbohydrate() {
return carbohydrate;
}
// @Builderκ° μμ±ν λ΄λΆ μ μ Builder ν΄λμ€
public static class NutritionFactsBuilder {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate;
// Builder λ©μλ
public NutritionFactsBuilder servingSize(int servingSize) {
this.servingSize = servingSize;
return this;
}
public NutritionFactsBuilder servings(int servings) {
this.servings = servings;
return this;
}
public NutritionFactsBuilder calories(int calories) {
this.calories = calories;
return this;
}
public NutritionFactsBuilder fat(int fat) {
this.fat = fat;
return this;
}
public NutritionFactsBuilder sodium(int sodium) {
this.sodium = sodium;
return this;
}
public NutritionFactsBuilder carbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
return this;
}
// build() λ©μλ
public NutritionFacts build() {
return new NutritionFacts(this.servingSize, this.servings, this.calories, this.fat, this.sodium, this.carbohydrate);
}
@Override
public String toString() {
return "NutritionFacts.NutritionFactsBuilder(servingSize=" + this.servingSize + ", servings=" + this.servings
+ ", calories=" + this.calories + ", fat=" + this.fat + ", sodium=" + this.sodium + ", carbohydrate="
+ this.carbohydrate + ")";
}
}
// NutritionFactsμ μμ±μ
private 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;
}
// Builder μμ± λ©μλ
public static NutritionFactsBuilder builder() {
return new NutritionFactsBuilder();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof NutritionFacts)) return false;
NutritionFacts that = (NutritionFacts) o;
return servingSize == that.servingSize && servings == that.servings && calories == that.calories &&
fat == that.fat && sodium == that.sodium && carbohydrate == that.carbohydrate;
}
@Override
public int hashCode() {
return Objects.hash(servingSize, servings, calories, fat, sodium, carbohydrate);
}
@Override
public String toString() {
return "NutritionFacts(servingSize=" + this.servingSize + ", servings=" + this.servings + ", calories=" + this.calories
+ ", fat=" + this.fat + ", sodium=" + this.sodium + ", carbohydrate=" + this.carbohydrate + ")";
}
}
@Builder
μμλ νμ λ§€κ°λ³μλ₯Ό κ°μ νμ§ μλλ€.- κ²°κ΅ @Builderμ λ³λμ κ²μ¦ λ‘μ§μ μΆκ°νκ±°λ, νμ λ§€κ°λ³μλ₯Ό μ΄κΈ°ννλ μ μ λ©μλλ₯Ό μμ±ν΄μΌ νλ€.
- μ±λ₯ μ€λ²ν€λ
- λλ²κΉ μ΄ μ΄λ €μ
[!IMPORTANT]
ν΄λμ€μ νλκ°μ΄ 4κ° μ΄μμΈ κ²½μ°μλ μμ±μλ μ ν©λ© λμ λΉλν¨ν΄μ κ³ λ €ν΄λ³΄μ.