DevLog 😢

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

πŸ“–/Effective Java

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

dolmeng2 2023. 4. 3. 19:54

πŸ’¬ μ΄νŒ©ν‹°λΈŒμžλ°” μ•„μ΄ν…œ 2을 읽고 μ •λ¦¬ν•œ κΈ€μž…λ‹ˆλ‹€.


 

βœ”οΈ ν΄λž˜μŠ€μ— 멀버 λ³€μˆ˜κ°€ λ§Žμ„ 경우, 객체λ₯Ό μ–΄λ–»κ²Œ 생성할 수 μžˆμ„κΉŒ?

- μƒμ„±μžλ₯Ό μ—¬λŸ¬ μ’…λ₯˜λ‘œ λ‘μ–΄μ„œ, ν•„μš”ν•œ λ§€κ°œλ³€μˆ˜λ§Œμ„ μ‚¬μš©ν•˜λŠ” μƒμ„±μž μ—¬λŸ¬ 개λ₯Ό λ§Œλ“€ 수 μžˆλ‹€

- κ·ΈλŸ¬λ‚˜, 이 방법은 ν•„λ“œκ°€ λŠ˜μ–΄λ‚˜λ©΄ 그만큼 관리해야 ν•˜λŠ” μƒμ„±μžκ°€ λ§Žμ•„μ§€κΈ° λ•Œλ¬Έμ— 쒋지 μ•Šλ‹€.

- λ˜ν•œ, λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬ν•˜λ©΄ (μΈν…”λ¦¬μ œμ΄μ˜ νŒŒλΌλ―Έν„° 힌트λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 이상) 각 κ°’μ˜ 의미λ₯Ό ν•œλˆˆμ— μ•Œμ•„λ³΄κΈ°κ°€ νž˜λ“€κ³ , 버그가 λ°œμƒν•  ν™•λ₯ μ΄ λ†’μ•„μ§ˆ 수 μžˆλ‹€.

public class Crew {
    private String name;
    private int age;
    private String course;
    private String nickname;
}

μ˜ˆμ‹œλ‘œ, 크루에 λŒ€ν•œ 정보λ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ‹€μŒκ³Ό 같은 4가지 ν•„λ“œκ°€ μžˆλ‹€κ³  κ°€μ •ν•΄λ³΄μž.

 

 

πŸ’¬ ν•„μš”ν•œ μƒμ„±μžλ₯Ό μ „λΆ€ λ§Œλ“€κΈ°

- μš°λ¦¬κ°€ ν•„μš”ν•œ μƒμ„±μžμ— 따라 λͺ¨λ“  μ’…λ₯˜μ˜ μƒμ„±μžλ₯Ό 각각 μƒμ„±ν•˜λŠ” 방법이닀.

public class Crew {
    private String name;
    private int age;
    private String course;
    private String nickname;

    public Crew(String name, int age) {
        this(name, age, "", "");
    }

    public Crew(String name, String nickname, int age) {
        this(name, age, "", nickname);
    }

    public Crew(final String name, final int age, final String course, final String nickname) {
        this.name = name;
        this.age = age;
        this.course = course;
        this.nickname = nickname;
    }
}

이 λ°©λ²•μ—μ„œ 큰 νŠΉμ§•μ€, λ§€κ°œλ³€μˆ˜κ°€ 적은 μƒμ„±μžλŠ” λ§€κ°œλ³€μˆ˜κ°€ λ§Žμ€ μƒμ„±μžλ₯Ό μ μ§„μ μœΌλ‘œ ν˜ΈμΆœν•œλ‹€λŠ” 것이닀.

μ΄λ ‡κ²Œ 되면 μ΄ˆκΈ°κ°’μ„ 섀정해두기 λ•Œλ¬Έμ— λΆˆλ³€ 객체둜 생성할 수 μžˆμ§€λ§Œ, μƒμ„±μžμ˜ κ°œμˆ˜κ°€ ν•„λ“œμ— λ”°λΌμ„œ 계속 μ¦κ°€ν•œλ‹€λŠ” 단점이 있고, μ‹œκ·Έλ‹ˆμ²˜λ₯Ό 가진 λ§€κ°œλ³€μˆ˜μ˜ 경우 λ‹¨μˆœ μƒμ„±μžλ‘œμ„œλŠ” 생성할 수 μ—†λ‹€λŠ” 단점이 μ‘΄μž¬ν•œλ‹€.

 

 

πŸ’¬ μžλ°”λΉˆμ¦ˆ νŒ¨ν„΄

- λ§€κ°œλ³€μˆ˜κ°€ μ—†λŠ” μƒμ„±μžλ‘œ 객체λ₯Ό μƒμ„±ν•˜κ³ , setterλ₯Ό ν†΅ν•΄μ„œ 각 λ³€μˆ˜μ˜ 값을 μ„ΈνŒ…ν•˜λŠ” 방식이닀.

public class Crew {
    private String name;
    private int age;
    private String course;
    private String nickname;

    public void setName(final String name) {
        this.name = name;
    }

    public void setAge(final int age) {
        this.age = age;
    }

    public void setCourse(final String course) {
        this.course = course;
    }

    public void setNickname(final String nickname) {
        this.nickname = nickname;
    }
}

- κ·ΈλŸ¬λ‚˜, 이 방법은 객체 ν•˜λ‚˜λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄ μ—¬λŸ¬ 개의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄μ•Ό 되며, setterλ₯Ό μ—΄μ–΄λ‘κ²Œ λœλ‹€λ©΄ 객체에 λŒ€ν•œ λ³€κ²½ κ°€λŠ₯성을 열어두어 λΆˆλ³€ν•¨μ„ λ§Œλ“€ μˆ˜κ°€ 없어진닀.

- λ˜ν•œ, κ°œλ°œμžκ°€ λͺ…μ‹œμ μœΌλ‘œ setterλ₯Ό ν™œμš©ν•˜μ—¬ 값을 λ„£μ–΄μ£Όμ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ—, setterλ₯Ό ν˜ΈμΆœν•˜κΈ° μ „κΉŒμ§€ ν•΄λ‹Ή κ°μ²΄λŠ” λΆˆμ™„μ „ν•œ μƒνƒœκ°€ λœλ‹€. : μƒλ‹Ήνžˆ μœ„ν—˜ν•˜λ‹€. NPE의 κ°€λŠ₯성을 μ—΄μ–΄λ‘λŠ” 것이며, 객체의 λΆˆλ³€μ„±μ„ ν•΄μΉ˜κΈ° λ•Œλ¬Έμ— 였λ₯˜ κ°€λŠ₯성도 높아진닀.

 

 

πŸ’¬ λΉŒλ” νŒ¨ν„΄

- ν•„μˆ˜ λ§€κ°œλ³€μˆ˜λ‘œ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ—¬ λΉŒλ” 객체λ₯Ό μ–»κ³ , λΉŒλ” 객체의 setterλ₯Ό 톡해 선택 λ§€κ°œλ³€μˆ˜λ₯Ό μ„€μ •ν•˜λŠ” 방법이닀.

- 이후, buildλ₯Ό ν†΅ν•΄μ„œ λΆˆλ³€ 객체λ₯Ό λ§Œλ“œλŠ” 방법이닀.

public class Crew {
    private String name;
    private int age;
    private String course;
    private String nickname;

    public static class Builder {
        // ν•„μˆ˜ λ§€κ°œλ³€μˆ˜
        private final String name;
        private final String nickname;

        // 선택 λ§€κ°œλ³€μˆ˜λŠ” κΈ°λ³Έκ°’μœΌλ‘œ μ΄ˆκΈ°ν™”ν•˜κΈ° 
        private int age = 0;
        private String course = "";

        // ν•„μˆ˜ κ°’ μƒμ„±μž
        public Builder (String name, String nickname) {
            this.name = name;
            this.nickname = nickname;
        }

        // 선택 κ°’ μ£Όμž…
        public Builder age(int age) {
            this.age = age;
            return this;
        }

        public Builder course(int age) {
            this.course = age;
            return this;
        }

        // 객체 μƒμ„±ν•˜κΈ°
        public void build() {
            return new Crew(this);
        }
    }

    private Crew(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.course = builder.course;
        this.nickname = builder.nickname;
    }
}

 

κ°μ²΄λŠ” λ‹€μŒκ³Ό 같은 μˆœμ„œλ‘œ 생성할 수 μžˆλ‹€.

1. ν•„μš”ν•œ 객체의 λ‚΄λΆ€ Builder 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ—¬, Builder 객체λ₯Ό μ–»λŠ”λ‹€. (ν•„μˆ˜ λ§€κ°œλ³€μˆ˜ λ°›κΈ°)
2. Builder 객체의 setterλ₯Ό ν™œμš©ν•˜μ—¬ 선택 λ§€κ°œλ³€μˆ˜μ˜ 값을 ν• λ‹Ήν•œλ‹€.
3. build()λ₯Ό ν˜ΈμΆœν•˜μ—¬ μ΅œμ’…μ μœΌλ‘œ ν•„μš”ν•œ 객체λ₯Ό μ–»λŠ”λ‹€.

 

μœ„ μ½”λ“œλŠ” Crew의 μƒμ„±μžκ°€ private으둜 λ§‰ν˜€ 있고, Crew에 λŒ€ν•œ λΆˆλ³€μ„±μ„ 보μž₯ν•  수 μžˆλ‹€. (μƒμ„±μžλ₯Ό 톡해 λ§Œλ“€κΈ° λ•Œλ¬Έμ—)

- μ΄λ•Œ, μΆ”κ°€μ μœΌλ‘œ 검증 둜직이 λ“€μ–΄κ°„λ‹€λ©΄ buildκ°€ ν˜ΈμΆœν•˜λŠ” μƒμ„±μžμ—μ„œ κ²€μ‚¬ν•˜λŠ” 것이 μ’‹λ‹€. (ν˜Ήμ€ builder의 μƒμ„±μž)

- λ˜ν•œ, λΉŒλ”μ˜ setter λ©”μ„œλ“œλ“€μ΄ return this;λ₯Ό ν†΅ν•΄μ„œ 자기 μžμ‹  (=Builder)λ₯Ό λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ—, 또 λ‹€μ‹œ λ©”μ„œλ“œλ₯Ό μ—°μ‡„μ μœΌλ‘œ 호좜이 κ°€λŠ₯ν•˜κ²Œ λœλ‹€.

 

ν΄λΌμ΄μ–ΈνŠΈμ˜ μ½”λ“œλ‘œ λ³Έλ‹€λ©΄ λ‹€μŒκ³Ό 같이 μ‚¬μš©ν•  수 있게 λ˜λŠ” 것이닀.

Crew crew = new Crew
        .Builder(”이름”, “λ‹‰λ„€μž„”)
        .age(23)
        .course(”λ°±μ—”λ“œ”)
        .build();

μ΄λ ‡κ²Œ 되면, ν΄λΌμ΄μ–ΈνŠΈλŠ” 내뢀에 ν•„μš”ν•œ 각각의 값듀이 무엇을 μ˜λ―Έν•˜λŠ”μ§€ νŒŒμ•…ν•˜κΈ°λ„ μ‰¬μ›Œμ§„λ‹€.


βœ”οΈ μ–΄λ–»κ²Œ ν™œμš©ν•˜λ©΄ μ’‹μ„κΉŒ?

λ˜ν•œ, κ³„μΈ΅μ μœΌλ‘œ μ„€κ³„λœ ν΄λž˜μŠ€μ™€ 같이 μ‚¬μš©ν•˜λŠ” 것도 μ’‹λ‹€.

import java.util.EnumSet;
        import java.util.Objects;
        import java.util.Set;

public abstract class ConvenientStore {
    public enum Brand {CU, GS, SEVEN_ELEVEN, MINI_STOP}
    final Set<Brand> brands;

    abstract static class Builder<T extends Builder<T>> {
        EnumSet<Brand> brands = EnumSet.noneOf(Brand.class);

        public T addBrand(Brand brand) {
            brands.add(Objects.requireNonNull(brand));
            return self();
        }

        abstract ConvenientStore build();

        protected abstract T self();
    }

    ConvenientStore(Builder<?> builder) {
        brands = builder.brands.clone();
    }
}

κ°„λ‹¨ν•œ μ˜ˆμ‹œλ₯Ό λ“€μ–΄λ³΄μž. νŽΈμ˜μ μ— λŒ€ν•œ μΆ”μƒν΄λž˜μŠ€λ₯Ό μƒμ„±ν•œ λ‹€μŒ, λΈŒλžœλ“œμ— λŒ€ν•œ enum νƒ€μž…μ„ μ •μ˜ν•˜μ˜€λ‹€.

μœ„ μ½”λ“œμ˜ νŠΉμ§•μ„ λ“€μ–΄λ³΄μžλ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

 

1. 좔상 클래슀둜 선언이 λ˜μ–΄ 있기 λ•Œλ¬Έμ• , μ§μ ‘μ μœΌλ‘œ μΈμŠ€ν„΄μŠ€ν™”κ°€ λΆˆκ°€λŠ₯ν•˜λ‹€.

2. μ œλ„€λ¦­ νƒ€μž…μΈ Tκ°€ μ‚¬μš©λ˜μ–΄ 있으며, μ—¬κΈ°μ„œ TλŠ” Builder 클래슀λ₯Ό 상속받은 클래슀의 νƒ€μž…μ΄λ‹€.

3. brands의 경우 EnumSet<Brand> νƒ€μž…μœΌλ‘œ, BrandλΌλŠ” enum νƒ€μž…μ˜ 값을 λ‹΄λŠ”λ‹€.

4. addBrandλŠ” Brand νƒ€μž…μ˜ 값을 인수둜 λ°›μ•„μ„œ brands에 μΆ”κ°€ν•˜λ©°, self()λ₯Ό 톡해 Builder 클래슀λ₯Ό 상속받아 κ΅¬ν˜„ν•œ ν΄λž˜μŠ€μ—μ„œ κ΅¬ν˜„λœ λ©”μ„œλ“œμ˜ λ°˜ν™˜κ°’μ΄ λ¦¬ν„΄λœλ‹€.

 

 

πŸ’¬ μž¬κ·€μ  νƒ€μž… ν•œμ • 

μ—¬κΈ°μ„œ 쓰인 Builder<T extends Builder<T>>λŠ” μž¬κ·€μ  νƒ€μž… ν•œμ •μ΄λΌκ³  ν•œλ‹€.

νƒ€μž… λ§€κ°œλ³€μˆ˜ Tκ°€ μžμ‹ μ˜ νƒ€μž…μ„ ν¬ν•¨ν•˜λŠ” μƒμœ„ λͺ¨λ“ˆμ— ν•œμ •λ˜λŠ” 것을 μ˜λ―Έν•œλ‹€.

-> Tκ°€ μžμ‹ μ„ ν¬ν•¨ν•˜λŠ” μˆ˜μ‹μΈ Builder<T>에 μ˜ν•΄ ν•œμ • (extends)λœλ‹€.

: 말이 μ–΄λ ΅μ§€λ§Œ, μ‰½κ²Œ μƒκ°ν•˜λ©΄ TλŠ” Builder 클래슀λ₯Ό상속받은 ν΄λž˜μŠ€μž„μ„ μ˜λ―Έν•œλ‹€λŠ” λœ»μ΄λ‹€.

 

μ™œ μ‚¬μš©ν•˜λŠ” 걸까?

class Builder<T extends Builder<T>> {
        ...
}

μ΄λ ‡κ²Œ 되면 Builder 클래슀λ₯Ό 상속받은 ν΄λž˜μŠ€μ—μ„œ, ν•΄λ‹Ή 클래슀의 νƒ€μž…μ„ μ •μ˜ν•  λ•Œ

자기 μžμ‹ μ˜ νƒ€μž…μ„ μ œκ³΅ν•˜λ©΄μ„œ Builder 클래슀의 λ©”μ„œλ“œλ„ ν•¨κ»˜ μ‚¬μš©ν•  수 있게 λœλ‹€.

 

public static class Builder extends ConvenientStore.Builder<Builder> {
        ...
}

예λ₯Ό λ“€μ–΄, μ—¬κΈ°μ„œ ConvenientStore.Builder ν΄λž˜μŠ€λŠ” Builder<ConvenientStore.Builder> νƒ€μž…μ΄λ©°, TλŠ” Builder<ConvenientStore.Builder> κ°€ λ˜λŠ” 것이기 λ•Œλ¬Έμ— Builder 클래슀의 λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  수 있게 λœλ‹€.

κ·Έλ ‡κΈ° λ•Œλ¬Έμ—, μœ„μ—μ„œ μ„ μ–Έν–ˆλ˜ addBrand(), build() λ©”μ„œλ“œλŠ” ConvenientStore.Builderμ—μ„œλ„ μ‚¬μš©ν•  수 있게 λœλ‹€.

 

 

λ‹€μ‹œ λŒμ•„μ™€μ„œ, 편의점이 ν™•μž₯ν•˜μ—¬ μ™Έκ΅­μœΌλ‘œ ν™•μž₯ν–ˆλ‹€κ³  κ°€μ •ν•΄λ³΄μž. 

μ΄λ•Œ, 일본 νŽΈμ˜μ μ€ νŒŒλΌλ―Έν„°λ‘œ 맀μž₯의 점원 수λ₯Ό λ°›λŠ”λ‹€λ©΄?

public class JapanConvenientStore extends ConvenientStore {
    public final int employeesCount;

    public static class Builder extends ConvenientStore.Builder<Builder> {
        private int employeesCount = 0;

        public Builder updateEmployeesCount(int employeeCount) {
            this.employeesCount = employeeCount;
            return this;
        }

        @Override
        public JapanConvenientStore build() {
            return new JapanConvenientStore(this);
        }

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

    private JapanConvenientStore(Builder builder) {
        super(builder);
        employeesCount = builder.employeesCount;
    }
}

 

ν•˜μœ„ 클래슀의 build λ©”μ„œλ“œλŠ” ꡬ체 ν•˜μœ„ 클래슀λ₯Ό λ°˜ν™˜ν•˜λ„λ‘ μ„ μ–Έν–ˆλ‹€.

-> 이런 μ‹μœΌλ‘œ ν•˜μœ„ 클래슀의 λ©”μ„œλ“œ(build)κ°€ μƒμœ„ 클래슀의 λ©”μ„œλ“œκ°€ μ •μ˜ν•œ λ°˜ν™˜ νƒ€μž… λŒ€μ‹ , ν•˜μœ„ νƒ€μž…(JapanConvenientStore)을 λ°˜ν™˜ν•˜λŠ” 것을 ‘곡변 λ°˜ν™˜ 타이핑’이라고 ν•œλ‹€.

= λΆ€λͺ¨ 클래슀의 λ©”μ„œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ”© ν•  λ•Œ, λΆ€λͺ¨ 클래슀의 λ°˜ν™˜ νƒ€μž…μ„ μžμ‹ 클래슀의 νƒ€μž…μœΌλ‘œ λ³€κ²½ν•˜λŠ” 것.

 

이λ₯Ό μ‚¬μš©ν•˜κ²Œ 되면, ν΄λΌμ΄μ–ΈνŠΈλŠ” ν˜• λ³€ν™˜μ„ 신경쓰지 μ•Šκ³  λΉŒλ”λ₯Ό μ‚¬μš©ν•  수 있게 λœλ‹€.

 

λ˜ν•œ, self()λŠ” μžμ‹ μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•˜κ³  μžˆλŠ” 것을 λ³Ό 수 μžˆλ‹€.

public T addBrand(Brand brand) {
        brands.add(Objects.requireNonNull(brand));
        return self();
}

λ°˜ν™˜ νƒ€μž…μΈ TλŠ” μž¬κ·€μ  νƒ€μž… ν•œμ •μ— μ˜ν•΄μ„œ 자기 μžμ‹ μ„ κ΅¬ν˜„ν•œ ν•˜μœ„ 클래슀인데,

ν•˜μœ„ 클래슀의 self()μ—μ„œ thisλ₯Ό λ°˜ν™˜ν•˜μ—¬ μƒμœ„ ν΄λž˜μŠ€μ—μ„œ ν•˜μœ„ 클래슀λ₯Ό λ°˜ν™˜ν•  수 μžˆλ„λ‘ λ§Œλ“€μ—ˆλ‹€.

 

μ•„λ¬΄νŠΌ, 이 덕뢄에 ν΄λΌμ΄μ–ΈνŠΈλŠ” μ΄λŸ¬ν•œ λΉŒλ” νŒ¨ν„΄μ„ ν™œμš©ν•˜μ—¬ λ‹€μŒκ³Ό 같이 선언이 κ°€λŠ₯ν•˜λ‹€.

JapanConvenientStore store = new JapanConvenientStore
        .Builder()
        .addBrand(ConvenientStore.Brand.LAWSON)
        .build();

이런 μ‹μœΌλ‘œ μ›ν•˜λŠ” λ§€κ°œλ³€μˆ˜λ₯Ό ν™œμš©ν•˜μ—¬ 객체λ₯Ό 생성할 수 μžˆλ‹€λŠ” μž₯점이 μžˆλ‹€.

κ·ΈλŸ¬λ‚˜, 이 νŒ¨ν„΄μ€ 생성 λΉ„μš©μ„ κ³ λ €ν•΄μ•Ό ν•˜λ©°, λ§€κ°œλ³€μˆ˜κ°€ λ§Žμ„ 경우 더 잘 λ™μž‘ν•œλ‹€.

 

보톡 ν”„λ‘œκ·Έλž¨μ΄ 컀질수둝 λ§€κ°œλ³€μˆ˜κ°€ μ»€μ§€λŠ” κ²½μš°κ°€ 많기 λ•Œλ¬Έμ—, μƒμ„±μžμž 정적 νŒ©ν„°λ¦¬κ°€ μ²˜λ¦¬ν•  λ§€κ°œλ³€μˆ˜κ°€ λ§Žμ„ 경우 μ²˜μŒλΆ€ν„° λΉŒλ” νŒ¨ν„΄μ„ μ„ νƒν•˜λŠ” 게 λ‚˜μ„ 수 μžˆλ‹€.

 

+ λ§Œμ•½, μž¬κ·€μ  ν•œμ • νƒ€μž…μ„ μ‚¬μš©ν•˜μ§€ μ•Šμ•˜μ„ 경우 μ–΄λ–»κ²Œ 될까?

=public abstract class ConvenientStore {
    public enum Brand {CU, GS, SEVEN_ELEVEN, MINI_STOP, LAWSON}
    final Set<Brand> brands;

    abstract static class Builder {
        EnumSet<Brand> brands = EnumSet.noneOf(Brand.class);

        public Builder addBrand(Brand brand) {
            brands.add(Objects.requireNonNull(brand));
            return self();
        }

        abstract ConvenientStore build();

        protected abstract Builder self();
    }

    ConvenientStore(Builder builder) {
        brands = builder.brands.clone();
    }
}

public class JapanConvenientStore extends ConvenientStore {
    public final int employeesCount;

    public static class Builder extends ConvenientStore.Builder {
        private int employeesCount = 0;

        public Builder updateEmployeesCount(int employeeCount) {
            this.employeesCount = employeeCount;
            return this;
        }

        @Override
        public JapanConvenientStore build() {
            return new JapanConvenientStore(this);
        }

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

    private JapanConvenientStore(Builder builder) {
        super(builder);
        employeesCount = builder.employeesCount;
    }
}

이런 μ‹μœΌλ‘œ μ½”λ“œκ°€ μž‘μ„±λ  텐데, 그럼 ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œ λͺ…μ‹œμ μœΌλ‘œ ν˜•λ³€ν™˜μ„ ν•΄μ€˜μ•Ό ν•œλ‹€.

JapanConvenientStore store = (JapanConvenientStore) new JapanConvenientStore
        .Builder()
        .addBrand(ConvenientStore.Brand.LAWSON)
        .build();

 

Comments