Skip to content

Latest commit

Β 

History

History
385 lines (281 loc) Β· 14.3 KB

File metadata and controls

385 lines (281 loc) Β· 14.3 KB

item 02. μƒμ„±μžμ— λ§€κ°œλ³€μˆ˜κ°€ λ§Žλ‹€λ©΄ λΉŒλ”λ₯Ό κ³ λ €ν•˜λΌ

정적 νŒ©ν„°λ¦¬μ™€ μƒμ„±μžμ—λŠ” λ˜‘κ°™μ€ μ œμ•½μ΄ ν•˜λ‚˜ μžˆλ‹€. 선택적 λ§€κ°œλ³€μˆ˜κ°€ λ§Žμ„ λ•Œ 적절히 λŒ€μ‘ν•˜κΈ° μ–΄λ ΅λ‹€λŠ” 점이닀.

클래슀용 μƒμ„±μž ν˜Ήμ€ 정적 νŒ©ν† λ¦¬μ˜ λͺ¨μŠ΅

선택 λ§€κ°œλ³€μˆ˜κ°€ λ§Žμ„ λ•Œ λŒ€μ•ˆμ— λŒ€ν•΄ μ•Œμ•„λ³΄μž.

첫 번째 λŒ€μ•ˆ : 점측적 μƒμ„±μž νŒ¨ν„΄

ν”„λ‘œκ·Έλž˜λ¨Έλ“€μ€ 이럴 λ•Œ, 점측적 μƒμ„±μž νŒ¨ν„΄(telescoping constructor pattern)을 즐겨 μ‚¬μš©ν–ˆλ‹€.

점측적 μƒμ„±μž νŒ¨ν„΄μ΄λž€?

ν•„μˆ˜ λ§€κ°œλ³€μˆ˜λ§Œ λ°›λŠ” μƒμ„±μž, ν•„μˆ˜ λ§€κ°œλ³€μˆ˜μ™€ 선택 λ§€κ°œλ³€μˆ˜ 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); // λ‹€λ₯Έ μƒμ„±μž 호좜
    }

    // ν•„μˆ˜ ν•„λ“œ + 선택적 ν•„λ“œ (calories)
    public NutritionFacts(int servingSize, int servings, int calories) {
        this(servingSize, servings, calories, 0); // λ‹€λ₯Έ μƒμ„±μž 호좜
    }

    // ν•„μˆ˜ ν•„λ“œ + 선택적 ν•„λ“œ (calories, fat)
    public NutritionFacts(int servingSize, int servings, int calories, int fat) {
        this(servingSize, servings, calories, fat, 0); // λ‹€λ₯Έ μƒμ„±μž 호좜
    }

    // ν•„μˆ˜ ν•„λ“œ + 선택적 ν•„λ“œ (calories, fat, sodium)
    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);

이런 μƒμ„±μžμ˜ 경우, μ‚¬μš©μžκ°€ μ„€μ •ν•˜κΈΈ μ›μΉ˜ μ•ŠλŠ” λ§€κ°œλ³€μˆ˜κΉŒμ§€ ν¬ν•¨ν•˜κΈ° μ‰¬μš΄λ°, 그런 λ§€κ°œλ³€μˆ˜μ—λ„ 값을 μ§€μ •ν•΄μ€˜μ•Ό ν•œλ‹€.

κ²°κ΅­, 점측적 μƒμ„±μž νŒ¨ν„΄λ„ μ“Έ μˆ˜λŠ” μžˆμ§€λ§Œ, λ§€κ°œλ³€μˆ˜ κ°œμˆ˜κ°€ λ§Žμ•„μ§€λ©΄ ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ±°λ‚˜ 읽기 μ–΄λ ΅λ‹€

λ§€κ°œλ³€μˆ˜λ₯Ό μœ νš¨ν•œμ§€ μƒμ„±μžμ—μ„œλ§Œ ν™•μΈν•˜λ©΄ 일관성 μœ μ§€ κ°€λŠ₯

두 번째 λŒ€μ•ˆ : μžλ°”λΉˆμ¦ˆ(javaBeans patteren) νŒ¨ν„΄

μžλ°”λΉˆμ¦ˆ νŒ¨ν„΄μ΄λž€?

λ§€κ°œλ³€μˆ˜κ°€ μ—†λŠ” μƒμ„±μžλ‘œ 객체λ₯Ό λ§Œλ“  ν›„, μ„Έν„°(setter) λ©”μ„œλ“œλ“€μ„ ν˜ΈμΆœν•΄ μ›ν•˜λŠ” λ§€κ°œλ³€μˆ˜μ˜ 값을 μ„€μ •ν•˜λŠ” 방식

public class NutritionFacts {
    // ν•„μˆ˜ ν•„λ“œ (κΈ°λ³Έκ°’ -1둜 μ΄ˆκΈ°ν™”)
    private int servingSize = -1; // ν•„μˆ˜
    private int servings = -1;    // ν•„μˆ˜

    // 선택적 ν•„λ“œ (κΈ°λ³Έκ°’ 0으둜 μ΄ˆκΈ°ν™”)
    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;
    }

    // μΆ”κ°€λ‘œ ν•„μš”ν•˜λ‹€λ©΄ 각 ν•„λ“œλ₯Ό λ°˜ν™˜ν•˜λŠ” getter λ©”μ„œλ“œλ„ μ •μ˜ν•  수 μžˆλ‹€.
}

μžλ°” 빈즈 νŒ¨ν„΄μ˜ μž₯점

  • μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€κΈ° 쉬움
  • 더 읽기 μ‰¬μš΄ μ½”λ“œ
  • ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œ
NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setSe rvings(8);
cocaCola.setCalories(100);
cocaCola.setSod ium(35);
cocaCola.setCa rbohyd rate(27);

μžλ°” 빈즈 νŒ¨ν„΄μ˜ 단점

  • μžλ°”λΉˆμ¦ˆ νŒ¨ν„΄μ—μ„œλŠ” 객체 ν•˜λ‚˜λ₯Ό λ§Œλ“€λ €λ©΄ λ©”μ„œλ“œλ₯Ό μ—¬λŸ¬ 개 ν˜ΈμΆœν•΄μ•Ό ν•˜κ³ , 객체가 μ™„μ „νžˆ μƒμ„±λ˜κΈ° μ „κΉŒμ§€λŠ” 일관성(consistency)이 λ¬΄λ„ˆμ§„ μƒνƒœμ— λ†“μ΄κ²Œ λœλ‹€.
  • 일관성이 κΉ¨μ§„ 객체가 λ§Œλ“€μ–΄μ§€λ©΄, 버그λ₯Ό 심은 μ½”λ“œμ™€ κ·Έ 버그 λ•Œλ¬Έμ— λŸ°νƒ€μž„μ— 문제λ₯Ό κ²ͺλŠ” μ½”λ“œκ°€ 물리적으둜 멀리 λ–¨μ–΄μ Έ 있기 λ•Œλ¬Έμ— 디버깅도 만만치 μ•ŠμŒ => 이둜 인해 ν΄λž˜μŠ€λΆˆλ³€μœΌλ‘œ λ§Œλ“€ 수 μ—†μŒ
  • μŠ€λ ˆλ“œ μ•ˆμ •μ„±μ„ μ–»μœΌλ €λ©΄ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μΆ”κ°€ μž‘μ—… ν•„μš”
  • λŒ€μ•ˆμœΌλ‘œ freeze λ©”μ„œλ“œκ°€ μžˆμœΌλ‚˜ ν™•μ‹€νžˆ ν˜ΈμΆœν•΄μ€¬λŠ”μ§€λ₯Ό μ»΄νŒŒμΌλŸ¬κ°€ 보증 ν•  방법이 μ—†μ–΄μ„œ λŸ°νƒ€μž„ 였λ₯˜μ— μ·¨μ•½ν•˜λ‹€.

μ„Έ 번째 λŒ€μ•ˆ : λΉŒλ” νŒ¨ν„΄(Builder pattern)

점측적 μƒμ„±μž νŒ¨ν„΄μ˜ μ•ˆμ „μ„±κ³Ό μžλ°” 빈즈 νŒ¨ν„΄μ˜ 가독성을 κ²ΈλΉ„ν•˜λ©°, λΉŒλ” νŒ¨ν„΄μ€ (파이썬과 μŠ€μΉΌλΌμ— μžˆλŠ”) λͺ…λͺ…λœ 선택적 λ§€κ°œλ³€μˆ˜λ₯Ό 흉내낸 것

λΉŒλ” νŒ¨ν„΄μ΄λž€?

  1. ν΄λΌμΈμ–ΈνŠΈλŠ” ν•„μš”ν•œ 객체λ₯Ό 직접 λ§Œλ“œλŠ” λŒ€μ‹ , ν•„μˆ˜ λ§€κ°œλ³€μˆ˜λ§ŒμœΌλ‘œ μƒμ„±μž(ν˜Ήμ€ 정적 νŒ©ν† λ¦¬)λ₯Ό ν˜ΈμΆœν•΄ λΉŒλ” 객체λ₯Ό μ–»λŠ”λ‹€.
  2. λΉŒλ” 객체가 μ œκ³΅ν•˜λŠ” μΌμ’…μ˜ μ„Έν„° λ©”μ„œλ“œλ“€λ‘œ μ›ν•˜λŠ” 선택 λ§€κ°œλ³€μˆ˜λ“€μ„ μ„€μ •ν•œλ‹€.
  3. λ§ˆμ§€λ§‰μœΌλ‘œ, λ§€κ°œλ³€μˆ˜κ°€ μ—†λŠ” 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 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;
    }
}

λ©”μ„œλ“œ 연쇄(method chaining) ν˜Ήμ€ ν”Œλ£¨μ–ΈνŠΈ API(fluent API)

  • NutritionFacts 클래슀 : λͺ¨λ“  λ§€κ°œλ³€μˆ˜μ˜ 기값듀을 ν•œ 곳에 λͺ¨μ•„λ‘ 
  • λΉŒλ”μ˜ μ„Έν„° λ©”μ„œλ“œλ“€μ€ λΉŒλ” μžμ‹ μ„ λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ— μ—°μ‡„μ μœΌλ‘œ 호좜 ν•  수 μžˆλ‹€.

ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œμ˜ λͺ¨μŠ΅

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
    .calories(100)
    .sodium(35)
    .carbohydrate(27)
    .build();

μž₯점

  • ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλŠ” μ“°κΈ° 쉽고, 무엇보닀 읽기 쉽닀.
  • λΉŒλ” νŒ¨ν„΄μ€ μƒλ‹Ήνžˆ μœ μ—°ν•˜λ‹€. λΉŒλ” ν•˜λ‚˜λ‘œ μ—¬λŸ¬ 객체λ₯Ό μˆœνšŒν•˜λ©΄μ„œ λ§Œλ“€ 수 있고, λΉŒλ”μ— λ„˜κΈ°λŠ” λ§€κ°œλ³€μˆ˜μ— 따라 λ‹€λ₯Έ 객체λ₯Ό λ§Œλ“€ μˆ˜λ„ μžˆλ‹€.
  • μƒμ„±μžλ‘œλŠ” λˆ„λ¦΄ 수 μ—†λŠ” μ‚¬μ†Œν•œ 이점으둜, λΉŒλ”λ₯Ό μ΄μš©ν•˜λ©΄ κ°€λ³€μΈμˆ˜(varargs) λ§€κ°œλ³€μˆ˜λ₯Ό μ—¬λŸ¬ 개 μ‚¬μš©ν•  수 μžˆλ‹€.

단점

  • 객체λ₯Ό λ§Œλ“€λ €λ©΄, 그에 μ•žμ„œ λΉŒλ”λΆ€ν„° λ§Œλ“€μ–΄μ•Ό ν•œλ‹€. λΉŒλ” 생성 λΉ„μš©μ΄ ν¬μ§€λŠ” μ•Šμ§€λ§Œ μ„±λŠ₯에 λ―Όκ°ν•œ μƒν™©μ—μ„œλŠ” λ¬Έμ œκ°€ 될 수 μžˆλ‹€.
  • 점측적 μƒμ„±μž νŒ¨ν„΄λ³΄λ‹€λŠ” μ½”λ“œκ°€ μž₯ν™©ν•΄μ„œ λ§€κ°œλ³€μˆ˜ κ°€ 4개 이상은 λ˜μ–΄μ•Ό κ°’μ–΄μΉ˜λ₯Ό ν•œλ‹€. BUT, APIλŠ” μ‹œκ°„μ΄ μ§€λ‚ μˆ˜λ‘ λ§€κ°œλ³€μˆ˜ κ°€ λ§Žμ•„μ§€λŠ” κ²½ν–₯이 μžˆμŒμ„ λͺ…μ‹¬ν•˜μž

βœ”οΈ λΆˆλ³€(immutable ν˜Ήμ€ immutability)은 μ–΄λ– ν•œ 변경도 ν—ˆμš©ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 뜻 으둜, 주둜 변경을 ν—ˆμš©ν•˜λŠ” κ°€λ³€(mutable) 객체와 κ΅¬λΆ„ν•˜λŠ” μš©λ„λ‘œ 쓰인닀. λŒ€ν‘œμ μœΌλ‘œ String κ°μ²΄λŠ” ν•œλ²ˆ λ§Œλ“€μ–΄μ§€λ©΄ μ ˆλŒ€ 값을 λ°”κΏ€ 수 μ—†λŠ” λΆˆλ³€ 객체닀. ν•œνŽΈ, λΆˆλ³€μ‹(invariant)은 ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λŠ” λ™μ•ˆ, ν˜Ήμ€ μ •ν•΄μ§„ κΈ°κ°„ λ™μ•ˆ λ°˜λ“œμ‹œ λ§Œμ‘±ν•΄μ•Ό ν•˜λŠ” 쑰건을 λ§ν•œλ‹€. λ‹€μ‹œ 말해 변경을 ν—ˆμš©ν•  μˆ˜λŠ” μžˆμœΌλ‚˜ μ£Όμ–΄μ§„ 쑰건 λ‚΄μ—μ„œ 만 ν—ˆμš©ν•œλ‹€λŠ” λœ»μ΄λ‹€. μ˜ˆμ»¨λŒ€ 리슀트의 ν¬κΈ°λŠ” λ°˜λ“œμ‹œ 0 이상이어야 ν•˜λ‹ˆ, λ§Œμ•½ ν•œμˆœκ°„ 이라도 음수 값이 λœλ‹€λ©΄ λΆˆλ³€μ‹μ΄ κΉ¨μ§„ 것이닀.

κ°€λ³€ 객체에도 λΆˆλ³€μ‹μ€ μ‘΄μž¬ν•  수 있으며, λ„“κ²Œ 보면 λΆˆλ³€μ€ λΆˆλ³€μ‹μ˜ 극단적 인 예라 ν•  수 μžˆλ‹€.

κ³„μΈ΅μ μœΌλ‘œ μ„€κ³„λœ ν΄λž˜μŠ€μ™€ μ“°κΈ° 쒋은 λΉŒλ” νŒ¨ν„΄

1. 좔상 클래슀 Pizza

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();
        }

        abstract Pizza build();

        // ν•˜μœ„ ν΄λž˜μŠ€λŠ” 이 λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜(overriding)ν•˜μ—¬ "this"λ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€.
        protected abstract T self();
    }

    Pizza(Builder<?> builder) {
        toppings = builder.toppings.clone(); // μ•„μ΄ν…œ 50 μ°Έμ‘°
    }
}
  • Pizza ν΄λž˜μŠ€λŠ” ν”Όμžμ˜ κΈ°λ³Έ 속성을 μ •μ˜ν•˜κ³ , Topping μ—΄κ±°ν˜•μ„ 포함
  • Builder λ‚΄λΆ€ ν΄λž˜μŠ€λŠ” μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ, ν”Όμž λΉŒλ”λ₯Ό μƒμ„±ν•˜λŠ” 데 ν•„μš”ν•œ λ©”μ„œλ“œλ₯Ό μ •μ˜
  • addTopping λ©”μ„œλ“œλŠ” 토핑을 μΆ”κ°€ν•˜λŠ” 역할을 ν•˜λ©°, self λ©”μ„œλ“œλŠ” ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ κ΅¬ν˜„λ˜μ–΄μ•Ό

2. λ‰΄μš• ν”Όμž (NyPizza)

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;
        }
    }

    private NyPizza(Builder builder) {
        super(builder);
        size = builder.size;
    }
}
  • NyPizza ν΄λž˜μŠ€λŠ” Pizza의 ν•˜μœ„ 클래슀이며, ν”Όμžμ˜ 크기(Size)λ₯Ό μΆ”κ°€λ‘œ μ •μ˜
  • Builder ν΄λž˜μŠ€λŠ” Pizza.Builderλ₯Ό 상속받아 λ‰΄μš• ν”Όμž μ „μš© λΉŒλ”λ₯Ό κ΅¬ν˜„
  • build λ©”μ„œλ“œλŠ” NyPizza 객체λ₯Ό λ°˜ν™˜ν•˜λ©°, self λ©”μ„œλ“œλŠ” μžμ‹ μ„ λ°˜ν™˜

3. μΉΌμ΄ˆλ„€ ν”Όμž (Calzone)

public class Calzone 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
        public Calzone build() {
            return new Calzone(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }

    private Calzone(Builder builder) {
        super(builder);
        sauceInside = builder.sauceInside;
    }
}
  • Calzone ν΄λž˜μŠ€λŠ” Pizza의 또 λ‹€λ₯Έ ν•˜μœ„ 클래슀둜, μ†ŒμŠ€κ°€ μ•ˆμ— λ“€μ–΄κ°€λŠ”μ§€ μ—¬λΆ€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” sauceInside λ³€μˆ˜λ₯Ό 포함함
  • Builder ν΄λž˜μŠ€λŠ” sauceInside λ©”μ„œλ“œλ₯Ό 톡해 μ†ŒμŠ€λ₯Ό μΆ”κ°€ν•  수 μžˆλŠ” κΈ°λŠ₯을 제곡

4. ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œ μ˜ˆμ‹œ

NyPizza pizza = new NyPizza.Builder(NyPizza.Size.SMALL)
    .addTopping(Pizza.Topping.SAUSAGE)
    .addTopping(Pizza.Topping.ONION)
    .build();

Calzone calzone = new Calzone.Builder()
    .addTopping(Pizza.Topping.HAM)
    .sauceInside()
    .build();
  • ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλŠ” Builderλ₯Ό μ‚¬μš©ν•˜μ—¬ 쉽고 μ§κ΄€μ μœΌλ‘œ ν”Όμžλ₯Ό 생성
  • NyPizza와 Calzone κ°μ²΄λŠ” 각각의 λΉŒλ”λ₯Ό 톡해 생성

μš”μ•½

각 ν•˜μœ„ ν΄λž˜μŠ€λŠ” μžμ‹ μ˜ νŠΉμ„±μ„ μΆ”κ°€ν•˜λ©΄μ„œλ„ μƒμœ„ 클래슀의 λΉŒλ” λ©”μ„œλ“œλ₯Ό μž¬μ‚¬μš©ν•©λ‹ˆλ‹€. 이둜 인해 ν΄λΌμ΄μ–ΈνŠΈλŠ” ν˜•λ³€ν™˜μ„ κ±±μ •ν•˜μ§€ μ•Šκ³ λ„ λ‹€μ–‘ν•œ ν”Όμž 객체λ₯Ό 생성할 수 μžˆλ‹€. λΉŒλ” νŒ¨ν„΄μ€ μœ μ—°μ„±κ³Ό 가독성을 높이며, 객체 생성 κ³Όμ •μ—μ„œμ˜ λ³΅μž‘μ„±μ„ μ€„μ—¬μ€Œ

βœ”οΈ μƒμ„±μžλ‚˜ 정적 νŒ©ν„°λ¦¬κ°€ μ²˜λ¦¬ν•΄μ•Ό ν•  λ§€κ°œλ³€μˆ˜κ°€ λ§Žλ‹€λ©΄ λΉŒλ” νŒ¨ν„΄μ„ μ„ νƒν•˜λŠ” 게 λ‚«λ‹€. λ§€κ°œλ³€μˆ˜ 쀑 λ‹€μˆ˜κ°€ ν•„μˆ˜κ°€ μ•„λ‹ˆκ±°λ‚˜ 같은 νƒ€μž…μ΄λ©΄ 특히 더 κ·Έλ ‡λ‹€. λΉŒλ”λŠ” 점측적 μƒμ„±μžλ³΄λ‹€ ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλ₯Ό 읽고 μ“°κΈ°κ°€ 훨씬 κ°„κ²°ν•˜κ³ , μžλ°”λΉˆμ¦ˆλ³΄λ‹€ 훨씬 μ•ˆμ „ν•˜λ‹€.

static을 μ‚¬μš©ν•˜μ§€ 말고.. ν•˜κ²Œ 되면... κ²°κ΅­ λ©”λͺ¨λ¦¬μ— λΉŒλ”κ°€ λ‚¨μ•„μžˆλ‹€λŠ”