πŸ“– [Design Pattern] πŸ’» λ””μžμΈ νŒ¨ν„΄ Singletone Pattern

πŸ’» [Design Pattern] 싱글톀 νŒ¨ν„΄

μ•ˆλ…•ν•˜μ„Έμš”. πŸ‘‹

λ””μžμΈ νŒ¨ν„΄ 쀑

Java 와 Spring μ—μ„œ 주둜 μ‚¬μš©λ˜λŠ”

Singletone Pattern 에 λŒ€ν•΄ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

πŸ’» 싱글톀 νŒ¨ν„΄ μ΄λž€ 무엇인가?

μ†Œν”„νŠΈμ›¨μ–΄ λ””μžμΈ νŒ¨ν„΄μ—μ„œ μ‹±κΈ€ν„΄ νŒ¨ν„΄(Singleton pattern)을 λ”°λ₯΄λŠ” ν΄λž˜μŠ€λŠ”, μƒμ„±μžκ°€ μ—¬λŸ¬ μ°¨λ‘€ ν˜ΈμΆœλ˜λ”λΌλ„
μ‹€μ œλ‘œ μƒμ„±λ˜λŠ” κ°μ²΄λŠ” ν•˜λ‚˜μ΄κ³  졜초 생성 이후에 호좜된 μƒμ„±μžλŠ” 졜초의 μƒμ„±μžκ°€ μƒμ„±ν•œ 객체λ₯Ό λ¦¬ν„΄ν•œλ‹€.
이와 같은 λ””μžμΈ μœ ν˜•μ„ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ΄λΌκ³  ν•œλ‹€.
주둜 κ³΅ν†΅λœ 객체λ₯Ό μ—¬λŸ¬κ°œ μƒμ„±ν•΄μ„œ μ‚¬μš©ν•˜λŠ” DBCP(DataBase Connection Pool)와 같은 μƒν™©μ—μ„œ 많이 μ‚¬μš©λœλ‹€.


즉 Singleton 이름 κ·ΈλŒ€λ‘œ ν•˜λ‚˜μ˜ κ°μ²΄λ§Œμ„ μƒμ„±ν•΄μ„œ μ‚¬μš©ν•˜λŠ” λ””μžμΈ νŒ¨ν„΄μ„ λ§ν•©λ‹ˆλ‹€.
단 ν•˜λ‚˜μ˜ 졜초 μƒμ„±λœ 객체λ₯Ό 곡용으둜 μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— λ©€ν‹°μ“°λ ˆλ“œ ν™˜κ²½μ—μ„œ Thread-Safe κ°€ μ€‘μš”ν•©λ‹ˆλ‹€.

1. 싱글톀 νŒ¨ν„΄μ˜ μ‚¬μš©μ΄μœ ?

싱글톀 νŒ¨ν„΄μ€ 주둜 μžλ°”μ™€ Spring Framework μ—μ„œ μ‚¬μš©λ©λ‹ˆλ‹€.

싱글톀 νŒ¨ν„΄μ€ 졜초 ν•œλ²ˆ 객체λ₯Ό 생성해 μž¬μ‚¬μš© ν•  수 μžˆκΈ°μ— λ©”λͺ¨λ¦¬ λ‚­λΉ„λ₯Ό 방지할 수 μžˆμŠ΅λ‹ˆλ‹€.
μ΄λ ‡κ²Œ 졜초 ν•œλ²ˆ μƒμ„±λœ 싱글톀 κ°μ²΄λŠ” 전역성을 κ°–κ³  μžˆκΈ°μ— μ–΄λ””μ„œλ‚˜ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2. 싱글톀 νŒ¨ν„΄ κ΅¬ν˜„ 방법

1) Eager Init

public class EagerInit {
    private static EagerInit uniqueInstance = new EagerInit();

    private EagerInit(){

    }

    public static EagerInit getInstance(){
        return uniqueInstance;
    }

}
κ°€μž₯ μ‰½κ²Œ λ§Œλ“€ 수 μžˆλŠ” Singletone Pattern으둜 
static ν‚€μ›Œλ“œμ˜ νŠΉμ§•μ„ μ΄μš©ν•΄μ„œ 클래슀 λ‘œλ”κ°€ μ΄ˆκΈ°ν™” ν•˜λŠ” μ‹œμ μ—μ„œ 정적 바인딩(static binding)을 톡해
ν•΄λ‹Ή μΈμŠ€ν„΄μŠ€λ₯Ό λ©”λͺ¨λ¦¬μ— λ“±λ‘ν•΄μ„œ μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
Eager Init 방식은 Thread-Safe ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
Singletone κ΅¬ν˜„ μ‹œ μ€‘μš”ν•œ 점이, λ©€ν‹° μŠ€λ ˆλ”© ν™˜κ²½μ—μ„œλ„ λ™μž‘ κ°€λŠ₯ν•˜κ²Œλ” κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.
즉, Thread-safe κ°€ 보μž₯λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

2) Lazy init

package singletone;
public class LazyInit {
    private static LazyInit uniqueInstance;

    private LazyInit() {
    }

    public static LazyInit getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new LazyInit();
        }
        return uniqueInstance;
    }
}
Eager Init 을 κ°œμ„ μ‹œμΌœ 클래슀 λ‘œλ”© μ‹œμ μ΄ μ•„λ‹Œ μΈμŠ€ν„΄μŠ€κ°€ ν•„μš”ν•˜μ—¬ μš”μ²­μ‹œ 동적 바인딩을 톡해 κ΅¬ν˜„ κ°€λŠ₯ν•©λ‹ˆλ‹€.
ν•˜μ§€λ§Œ μ—¬λŸ¬ μ“°λ ˆλ“œμ—μ„œ getInstance에 μ ‘κ·Όν•  수 μžˆμ–΄ Thread-Safe ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

3) synchronized 방법

package singletone;

public class Synchronize {

    private static Synchronize uniqueInstance;

    private Synchronize() {
    }

    public static synchronized Synchronize getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Synchronize();
        }
        return uniqueInstance;
    }
}

synchronized ν‚€μ›Œλ“œλ₯Ό ν†΅ν•΄μ„œ 동기화λ₯Ό 톡해 Lazy μ΄ˆκΈ°ν™”μ™€ Thread-Safe ν•˜κ²Œ 싱글톀을 κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
ν•˜μ§€λ§Œ μ„±λŠ₯이 μƒλ‹Ήνžˆ 쒋지 λͺ»ν•©λ‹ˆλ‹€.

4) Lazy Holder 방법

package singletone;

public class Holder {

    private Holder() {}
    private static class InnerInstanceClazz() {
        // 클래슀 λ‘œλ”© μ‹œμ μ—μ„œ 생성
        private static final Holder uniqueInstance = new Holder();
    }

    public static Holder getInstance() {
        return InnerInstanceClazz.instance;
    }

}
Holder 방법은 Singletone Pattern κ΅¬ν˜„μ— κ°€μž₯ 많이 μ“°μ΄λŠ” λŒ€ν‘œμ μΈ ν˜•νƒœμž…λ‹ˆλ‹€.
Holder ν΄λž˜μŠ€μ—λŠ” InnerInstanceClazz 클래슀의 λ³€μˆ˜κ°€ μ—†μ–΄μ„œ
static 멀버 ν΄λž˜μŠ€μ§€λ§Œ 클래슀 λ‘œλ”κ°€ μ΄ˆκΈ°ν™” 과정을 진행할 λ•Œ
InnerInstanceClazz λ©”μ„œλ“œλ₯Ό μ΄ˆκΈ°ν™” ν•˜μ§€μ•Šκ³ , getInstance() λ©”μ„œλ“œ 호좜 μ‹œ μ΄ˆκΈ°ν™” λ©λ‹ˆλ‹€.
동적바인딩(Dynamic Binding) 의 νŠΉμ§•μ„ μ΄μš©ν•˜μ—¬ Thread-safe ν•˜λ©΄μ„œ μ„±λŠ₯이 λ›°μ–΄λ‚©λ‹ˆλ‹€

InnerInstanceClazz λ‚΄λΆ€ μΈμŠ€ν„΄μŠ€λŠ” static 이기 λ•Œλ¬Έμ— 클래슀 λ‘œλ”© μ‹œμ μ— ν•œλ²ˆλ§Œ ν˜ΈμΆœλœλ‹€λŠ” 점을 μ΄μš©ν•œκ²ƒμ΄κ³ 
final을 μ¨μ„œ 값이 λ‹€μ‹œ ν• λ‹Ήλ˜μ§€ μ•Šλ„λ‘ ν•©λ‹ˆλ‹€.

끝

Design Pattern 쀑 μžλ°”μ™€ Spring Framework μ—μ„œ
많이 μ‚¬μš©λ˜λŠ” Singletone Pattern에 λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€.
κ°μ‚¬ν•©λ‹ˆλ‹€. πŸ™

Reference

https://elfinlas.github.io/2019/09/23/java-singleton/

https://medium.com/webeveloper/%EC%8B%B1%EA%B8%80%ED%84%B4-%ED%8C%A8%ED%84%B4-singleton-pattern-db75ed29c36

Written on June 28, 2020