Skip to content

Latest commit

ย 

History

History
159 lines (95 loc) ยท 5.94 KB

Singleton Pattern.md

File metadata and controls

159 lines (95 loc) ยท 5.94 KB

[๋””์ž์ธ ํŒจํ„ด] ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด(Singleton pattern)


์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์ด๋ž€?

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋  ๋•Œ, ์–ด๋–ค ํด๋ž˜์Šค๊ฐ€ ์ตœ์ดˆ ํ•œ ๋ฒˆ๋งŒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น(static)ํ•˜๊ณ  ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ์— ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด


์ฆ‰, ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์€ 'ํ•˜๋‚˜'์˜ ์ธ์Šคํ„ด์Šค๋งŒ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.

์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”ํ•  ๋•Œ, ๋˜‘๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๊ธฐ์กด์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ!


์ƒ์„ฑ์ž๊ฐ€ ์—ฌ๋Ÿฌ๋ฒˆ ํ˜ธ์ถœ๋˜๋„, ์‹ค์ œ๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด๋Š” ํ•˜๋‚˜์ด๋ฉฐ ์ตœ์ดˆ๋กœ ์ƒ์„ฑ๋œ ์ดํ›„์— ํ˜ธ์ถœ๋œ ์ƒ์„ฑ์ž๋Š” ์ด๋ฏธ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜์‹œํ‚ค๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค

(java์—์„œ๋Š” ์ƒ์„ฑ์ž๋ฅผ private์œผ๋กœ ์„ ์–ธํ•ด ๋‹ค๋ฅธ ๊ณณ์—์„œ ์ƒ์„ฑํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋งŒ๋“ค๊ณ , getInstance() ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค)


์™œ ์“ฐ๋‚˜์š”?

๋จผ์ €, ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งˆ๋‹ค ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ํ• ๋‹น๋ฐ›์•„์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ํ•œ๋ฒˆ์˜ new๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ตฌํ˜„ํ•œ ์ธ์Šคํ„ด์Šค๋Š” '์ „์—ญ'์ด๋ฏ€๋กœ, ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋“ค์ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•œ ์žฅ์ ์ด ์žˆ๋‹ค.


๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์–ธ์ œ์ธ๊ฐ€์š”?

์ฃผ๋กœ ๊ณตํ†ต๋œ ๊ฐ์ฒด๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์ƒ์„ฑํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ปค๋„ฅ์…˜ํ’€, ์Šค๋ ˆ๋“œํ’€, ์บ์‹œ, ๋กœ๊ทธ ๊ธฐ๋ก ๊ฐ์ฒด ๋“ฑ

์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ : ๊ฐ ์•กํ‹ฐ๋น„ํ‹ฐ ๋“ค์ด๋‚˜, ํด๋ž˜์Šค๋งˆ๋‹ค ์ฃผ์š” ํด๋ž˜์Šค๋“ค์„ ํ•˜๋‚˜ํ•˜๋‚˜ ์ „๋‹ฌํ•˜๋Š”๊ฒŒ ๋ฒˆ๊ฑฐ๋กญ๊ธฐ ๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ํ†ค ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์–ด๋””์„œ๋“  ์ ‘๊ทผํ•˜๋„๋ก ์„ค๊ณ„

๋˜ํ•œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ ˆ๋Œ€์ ์œผ๋กœ ํ•œ ๊ฐœ๋งŒ ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ ๋ณด์ฆํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•จ


๋‹จ์ ๋„ ์žˆ๋‚˜์š”?

๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„ ์›์น™ ์ค‘์— ๊ฐœ๋ฐฉ-ํ์‡„ ์›์น™์ด๋ž€ ๊ฒƒ์ด ์กด์žฌํ•œ๋‹ค.

๋งŒ์•ฝ ์‹ฑ๊ธ€ํ†ค ์ธ์Šคํ„ด์Šค๊ฐ€ ํ˜ผ์ž ๋„ˆ๋ฌด ๋งŽ์€ ์ผ์„ ํ•˜๊ฑฐ๋‚˜, ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ์‹œํ‚ค๋ฉด ๋‹ค๋ฅธ ํด๋ž˜์Šค๋“ค ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋†’์•„์ง€๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋•Œ ๊ฐœ๋ฐฉ-ํ์‡„ ์›์น™์ด ์œ„๋ฐฐ๋œ๋‹ค.

๊ฒฐํ•ฉ๋„๊ฐ€ ๋†’์•„์ง€๊ฒŒ ๋˜๋ฉด, ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํž˜๋“ค๊ณ  ํ…Œ์ŠคํŠธ๋„ ์›ํ™œํ•˜๊ฒŒ ์ง„ํ–‰ํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ•œ๋‹ค.


๋˜ํ•œ, ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋™๊ธฐํ™” ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š์•˜์„ ๋•Œ, ์ธ์Šคํ„ด์Šค๊ฐ€ 2๊ฐœ๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๋ฌธ์ œ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.


๋”ฐ๋ผ์„œ, ๋ฐ˜๋“œ์‹œ ์‹ฑ๊ธ€ํ†ค์ด ํ•„์š”ํ•œ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ฉด ์ง€์–‘ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ํ•œ๋‹ค. (์„ค๊ณ„ ์ž์ฒด์—์„œ ์‹ฑ๊ธ€ํ†ค ํ™œ์šฉ์„ ์›ํ™œํ•˜๊ฒŒ ํ•  ์ž์‹ ์ด ์žˆ์œผ๋ฉด ๊ดœ์ฐฎ์Œ)



๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์•ˆ์ „ํ•œ ์‹ฑ๊ธ€ํ†ค ๋งŒ๋“œ๋Š” ๋ฒ•


  1. Lazy Initialization (์ดˆ๊ธฐํ™” ์ง€์—ฐ)
    public class ThreadSafe_Lazy_Initialization{
     
        private static ThreadSafe_Lazy_Initialization instance;
     
        private ThreadSafe_Lazy_Initialization(){}
         
        public static synchronized ThreadSafe_Lazy_Initialization getInstance(){
            if(instance == null){
                instance = new ThreadSafe_Lazy_Initialization();
            }
            return instance;
        }
     
    }

    private static์œผ๋กœ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ ๋งŒ๋“ฌ

    private์œผ๋กœ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด ์™ธ๋ถ€์—์„œ์˜ ์ƒ์„ฑ์„ ๋ง‰์Œ

    synchronized ๋™๊ธฐํ™”๋ฅผ ํ™œ์šฉํ•ด ์Šค๋ ˆ๋“œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ฌ

    ํ•˜์ง€๋งŒ, synchronized๋Š” ํฐ ์„ฑ๋Šฅ์ €ํ•˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋ฏ€๋กœ ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•


  2. Lazy Initialization + Double-checked Locking

    1๋ฒˆ์˜ ์„ฑ๋Šฅ์ €ํ•˜๋ฅผ ์™„ํ™”์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•

    public class ThreadSafe_Lazy_Initialization{
        private volatile static ThreadSafe_Lazy_Initialization instance;
    
        private ThreadSafe_Lazy_Initialization(){}
    
        public static ThreadSafe_Lazy_Initialization getInstance(){
        	if(instance == null) {
            	synchronized (ThreadSafe_Lazy_Initialization.class){
                    if(instance == null){
                        instance = new ThreadSafe_Lazy_Initialization();
                    }
                }
            }
            return instance;
        }
    }

    1๋ฒˆ๊ณผ๋Š” ๋‹ฌ๋ฆฌ, ๋จผ์ € ์กฐ๊ฑด๋ฌธ์œผ๋กœ ์ธ์Šคํ„ด์Šค์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•œ ๋‹ค์Œ ๋‘๋ฒˆ์งธ ์กฐ๊ฑด๋ฌธ์—์„œ synchronized๋ฅผ ํ†ตํ•ด ๋™๊ธฐํ™”๋ฅผ ์‹œ์ผœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•

    ์Šค๋ ˆ๋“œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉด์„œ, ์ฒ˜์Œ ์ƒ์„ฑ ์ดํ›„์—๋Š” synchronized๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ €ํ•˜ ์™„ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•จ

    ํ•˜์ง€๋งŒ ์™„์ „ํžˆ ์™„๋ฒฝํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋‹˜


  3. Initialization on demand holder idiom (holder์— ์˜ํ•œ ์ดˆ๊ธฐํ™”)

    ํด๋ž˜์Šค ์•ˆ์— ํด๋ž˜์Šค(holder)๋ฅผ ๋‘์–ด JVM์˜ ํด๋ž˜์Šค ๋กœ๋” ๋งค์ปค๋‹ˆ์ฆ˜๊ณผ ํด๋ž˜์Šค๊ฐ€ ๋กœ๋“œ๋˜๋Š” ์‹œ์ ์„ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•

    public class Something {
        private Something() {
        }
     
        private static class LazyHolder {
            public static final Something INSTANCE = new Something();
        }
     
        public static Something getInstance() {
            return LazyHolder.INSTANCE;
        }
    }

    2๋ฒˆ์ฒ˜๋Ÿผ ๋™๊ธฐํ™”๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์„ ์•ˆํ•˜๋Š” ์ด์œ ๋Š”, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋™๊ธฐํ™” ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ํšŒํ”ผํ•˜๋ ค๊ณ  ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์กฐ๊ฐ€ ๊ทธ๋งŒํผ ๋ณต์žกํ•ด์ง€๊ณ  ๋น„์šฉ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ. ๋˜ํ•œ ์ฝ”๋“œ ์ž์ฒด๊ฐ€ ์ •ํ™•ํ•˜์ง€ ๋ชปํ•  ๋•Œ๋„ ๋งŽ์Œ


    ์ด ๋•Œ๋ฌธ์—, 3๋ฒˆ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ JVM์˜ ํด๋ž˜์Šค ์ดˆ๊ธฐํ™” ๊ณผ์ •์—์„œ ๋ณด์žฅ๋˜๋Š” ์›์ž์  ํŠน์„ฑ์„ ์ด์šฉํ•ด ์‹ฑ๊ธ€ํ†ค์˜ ์ดˆ๊ธฐํ™” ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ฑ…์ž„์„ JVM์—๊ฒŒ ๋– ๋„˜๊ธฐ๋Š” ๊ฑธ ํ™œ์šฉํ•จ


    ํด๋ž˜์Šค ์•ˆ์— ์„ ์–ธํ•œ ํด๋ž˜์Šค์ธ holder์—์„œ ์„ ์–ธ๋œ ์ธ์Šคํ„ด์Šค๋Š” static์ด๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค ๋กœ๋”ฉ์‹œ์ ์—์„œ ํ•œ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋œ๋‹ค. ๋˜ํ•œ final์„ ์‚ฌ์šฉํ•ด์„œ ๋‹ค์‹œ ๊ฐ’์ด ํ• ๋‹น๋˜์ง€ ์•Š๋„๋ก ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ ๊ฒƒ

    ์‹ค์ œ๋กœ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์ผ๋ฐ˜์ ์ธ ์‹ฑ๊ธ€ํ†ค ํด๋ž˜์Šค ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์ด 3๋ฒˆ์ด๋‹ค.