λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
IT

[JAVA] 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ(static factory method) λž€?

by πŸ’²πŸŽ΅βœ–οΈβœ”οΈβ˜Ό 2022. 11. 3.
728x90

객체 μƒμ„±μ˜ μΊ‘μŠν™”μ™€ 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ

κ°œμš”

객체 생성 μ‹œ μΊ‘μŠν™”λŠ” μ΄λ¦„μžˆλŠ” μƒμ„±μž λŒ€μ‹  정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό ν™œμš©ν•˜μ—¬ μœ μ—°μ„±κ³Ό ν™•μž₯성을 μ œκ³΅ν•©λ‹ˆλ‹€. 이에 λŒ€ν•œ μž₯점과 단점, 그리고 κ΄€λ ¨λœ μ£Όμ œλ“€μ„ 닀루고 μžˆμŠ΅λ‹ˆλ‹€. 이 λ¬Έμ„œλŠ” Joshua Bloch의 "μ΄νŽ™ν‹°λΈŒ μžλ°” 3판"을 μ°Έκ³ ν•˜μ—¬ μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μž₯점

1. 이름을 κ°€μ§ˆ 수 μžˆλ‹€.

정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλŠ” 이름을 가지기 λ•Œλ¬Έμ— λ°˜ν™˜λ  객체의 νŠΉμ„±μ„ μ‰½κ²Œ μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” 가독성과 μœ μ§€λ³΄μˆ˜μ— 도움이 λ©λ‹ˆλ‹€.

class Company {
    private Company() {}

    // 이름을 ν†΅ν•œ 가독성 ν–₯상
    public static Company createNewTeam() {
        // 객체 생성 둜직
    }
}

2. 호좜될 λ•Œλ§ˆλ‹€ μΈμŠ€ν„΄μŠ€λ₯Ό μƒˆλ‘œ μƒμ„±ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

미리 λ§Œλ“€μ–΄λ†“κ±°λ‚˜ 캐싱을 톡해 λΆˆν•„μš”ν•œ 객체 생성을 ν”Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. 싱글톀 νŒ¨ν„΄μ΄λ‚˜ ν”ŒλΌμ΄μ›¨μ΄νŠΈ νŒ¨ν„΄κ³Ό 같은 νŒ¨ν„΄μ—μ„œ ν™œμš©λ©λ‹ˆλ‹€.

class Company {
    private static Company company;

    private Company() {}

    // κΈ°μ‘΄ μΈμŠ€ν„΄μŠ€ ν™œμš©
    public static Company createNewTeam() {
        if(company == null) {
            company = new Company();
        } else {
            return company;
        }
    }
}

3. λ°˜ν™˜ νƒ€μž…μ˜ ν•˜μœ„ νƒ€μž… 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆλŠ” λŠ₯λ ₯이 μžˆλ‹€.

객체λ₯Ό κ΅¬ν˜„ 클래슀 없이 μΈν„°νŽ˜μ΄μŠ€λ§ŒμœΌλ‘œ λ‹€λ£° 수 있으며, μ΄λŠ” μžλ°” 8 μ΄ν›„μ˜ κΈ°λŠ₯을 ν™œμš©ν•  수 μžˆλŠ” μž₯점이 μžˆμŠ΅λ‹ˆλ‹€.

4. λ‹€λ₯Έ 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆλ‹€.

μž…λ ₯ λ§€κ°œλ³€μˆ˜μ— 따라 맀번 λ‹€λ₯Έ 클래슀의 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆμ–΄ 객체 선택에 μžˆμ–΄μ„œ μœ μ—°μ„±μ„ μ œκ³΅ν•©λ‹ˆλ‹€.

5. 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ—λŠ” λ°˜ν™˜ν•  객체의 ν΄λž˜μŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

단점

1. 상속을 ν•˜λ €λ©΄ publicμ΄λ‚˜ protected μƒμ„±μžκ°€ ν•„μš”ν•˜λ‹€.

정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ§Œ μ œκ³΅ν•˜λ©΄ ν•˜μœ„ 클래슀λ₯Ό λ§Œλ“€ 수 μ—†μŠ΅λ‹ˆλ‹€. μ΄λŠ” μƒμ†λ³΄λ‹€λŠ” μ»΄ν¬μ§€μ…˜μ„ μœ λ„ν•˜κ³  λΆˆλ³€ νƒ€μž…μœΌλ‘œ λ§Œλ“€λ €λ©΄ 였히렀 μž₯점이 될 수 μžˆμŠ΅λ‹ˆλ‹€.

뢀둝

λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜λž€?

λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜λŠ” λ©”μ„œλ“œ 이름과 μž…λ ₯ λ§€κ°œλ³€μˆ˜μ˜ μˆœμ„œ, νƒ€μž…, 개수둜 이뀄진 것을 λ§ν•©λ‹ˆλ‹€. 단, λ°˜ν™˜ κ°’μ˜ νƒ€μž…μ€ μ‹œκ·Έλ‹ˆμ²˜μ— ν¬ν•¨λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

싱글톀과 ν”ŒλΌμ΄μ›¨μ΄νŠΈ νŒ¨ν„΄μ˜ 차이점은?

싱글톀은 였직 ν•˜λ‚˜μ˜ 객체가 μ‘΄μž¬ν•΄μ•Ό ν•˜λŠ” κ²½μš°μ™€ 객체 생성에 μ œν•œμ„ 두어야 ν•  경우 μ‚¬μš©λ©λ‹ˆλ‹€. 반면, ν”ŒλΌμ΄μ›¨μ΄νŠΈλŠ” μ€‘λ³΅λ˜λŠ” 데이터가 μžˆλ‹€λ©΄ 객체λ₯Ό κ³΅μœ ν•˜μ—¬ λ©”λͺ¨λ¦¬μ™€ μΈμŠ€ν„΄μŠ€ 생성 μ‹œκ°„μ„ μ ˆμ•½ν•©λ‹ˆλ‹€.

μ‹€μ œ μ‚¬μš© 예제

1. 싱글톀 νŒ¨ν„΄

싱글톀 νŒ¨ν„΄μ€ ν•œ ν΄λž˜μŠ€μ—μ„œ ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ§Œ μƒμ„±ν•˜κ³ , κ·Έ μΈμŠ€ν„΄μŠ€μ— μ ‘κ·Όν•  수 μžˆλŠ” 전역적인 접근점을 μ œκ³΅ν•©λ‹ˆλ‹€.

class SingletonExample {
    private static SingletonExample instance;

    private SingletonExample() {}

    public static SingletonExample getInstance() {
        if(instance == null) {
            instance = new SingletonExample();
        }
        return instance;
    }
}

2. ν”ŒλΌμ΄μ›¨μ΄νŠΈ νŒ¨ν„΄

ν”ŒλΌμ΄μ›¨μ΄νŠΈ νŒ¨ν„΄μ€ 객체λ₯Ό μƒμ„±ν•˜λŠ” λΉ„μš©μ΄ 큰 경우, λ™μΌν•œ 객체λ₯Ό κ³΅μœ ν•˜μ—¬ λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•©λ‹ˆλ‹€.

import java.util.HashMap;
import java.util.Map;

interface Flyweight {
    void operation();
}

class ConcreteFlyweight implements Flyweight {
    @Override
    public void operation() {
        // λ…λ¦½λœ 객체의 λ™μž‘
    }
}

class FlyweightFactory {
    private static final Map<String, Flyweight> flyweights = new HashMap<>();

    public static Flyweight getFlyweight(String key) {
        return flyweights.computeIfAbsent(key, k -> new ConcreteFlyweight());
    }
}

μ°Έκ³ 

λ„μ„œ: "μ΄νŽ™ν‹°λΈŒ μžλ°” 3판" - Joshua Bloch

λŒ“κΈ€