Note

[디자인패턴] Singleton Pattern - 싱글톤 패턴

Supreme_YS 2021. 12. 19. 13:02

싱글톤 패턴에 대해 ㅇrㄹr보ㅈr. 싱글톤 패턴도 예전에 데코레이터 패턴이나 프록시 패턴처럼 이름에서부터 느낌이 오는 경우의 디자인 패턴이다. 뭔가 싱글톤하면 '하나'인 느낌이다. 싱글톤 패턴을 공부하면서 계속 싱글톤, 싱글톤을 되뇌이는데 자꾸 아래의 짤이 생각이난다.

혼자야?
어, 아직 싱글이야

출처 : 영화 범죄도시

싱글톤 패턴이 주는 어감에서 알 수 있듯이 한 개에 뭔가 집착을 하는 것처럼 보인다. 싱글톤 패턴은 객체를 딱 한 번만 생성해서 사용하는 패턴이다. 그렇다면 왜? 한 번만 생성해서 사용하는지 그 이유가 궁금하다. 여러 블로그를 뒤적거렸고, 사용하는 이유에 대해 공통적으로 포스팅한 것을 나름 정리를 해보았다.

 

* 싱글톤 패턴 사용 이유

1. 최초 한 번의 new 연산자를 통해, 고정된 메모리 영역을 사용한다. 따라서 메모리 낭비를 줄인다.

2. 이미 생성된 인스턴스를 활용하므로 속도 측면에서 이점이 있다.

3. 싱글톤 인스턴스는 전역으로 사용되는 인스턴스이기 때문에, 다른 클래스의 인스턴스가 접근하기 쉬워진다. 즉, 데이터 공유가 쉽다.

4. 공통된 객체를 사용하는 코딩에서 매번 객체를 생성하지 않고 같은 객체를 사용하도록 하기 때문에 성능이 좋다.


장점이 있으면 문제점도 있는 법. 바로 문제점에 대해 알아보자.

 

* 싱글톤 패턴의 문제점

1. 유연성이 떨어진다.

2. 만약에 싱글톤으로 만든 객체의 역할이 간단한 것이 아닌 복잡한 역할을 한다면 싱글톤 객체를 사용하는 객체간의 결합도가 높아진다.

3. 동시성(Concurrency) 문제가 발생할 수 있다. (동시성 문제 ? 여러 클래스의 인스턴스에서 싱글톤 객체 데이터에 동시에 접근하는 문제)


개념, 장점, 단점을 알았으니 바로 코드로 구현해서 보자. 이 코드는 https://commin.tistory.com/121 님 블로그에서 이해하기가 참 쉬워서 발췌해왔다.

 

* 먼저 일반 클래스 : 단순히 객체의 같음과 다름 비교를 위한 심플한 코드

package DesignPattern.Singleton;

public class Normal {

    public Normal() {
        System.out.println("Normal Instance Created");
    }
}

* 싱글톤 클래스 : 싱글톤 객체 생성시 객체의 같음과 다름 비교 및 싱글톤 구조

package DesignPattern.Singleton;

public class Singleton {
    // private 접근 제한자로 인해 new 연산자로 객체를 생성하지못하는 클래스가 되어버린 Singleton 클래스
    private static Singleton singleton = new Singleton();

    private Singleton() {
        System.out.println("Singleton Instance Created");
    }

    // 정적으로 싱글톤 객체를 선언
    // 위에 private로 생성된 생성자는 자기 자신에서는 호출될 수 있음.
    // 이렇게 생성한 싱글톤 클래스의 객체를 getInstance() 메서드를 통해서 반환.
    public static Singleton getInstance() {
        return singleton;
    }
}

* Client 클래스 : 테스트를 위한 코드

package DesignPattern.Singleton;

public class Client {
    public static void main(String[] args) {
        Normal normal1 = new Normal();
        Normal normal2 = new Normal();

        // Error 발생!
        // 'Singleton()' has private access in 'DesignPattern.Singleton.Singleton'
        // Singleton singleton1 = new Singleton(); // 이렇게 생성 불가능하다. private이라서

        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();

        /* 출력결과
        Normal Instance Created
        Normal Instance Created
        Singleton Instance Created
         */

        if(normal1 == normal2) {
            System.out.println("normal1 과 normal2는 같다");
        } else {
            System.out.println("normal1 과 normal2는 다르다");
        }

        if(singleton1 == singleton2) {
            System.out.println("singleton1 과 singleton2는 같다");
        } else {
            System.out.println("singleton1 과 singleton2는 다르다");
        }

        /* 출력결과
        Normal Instance Created
        Normal Instance Created
        Singleton Instance Created
        normal1 과 normal2는 다르다
        singleton1 과 singleton2는 같다
         */
    }
}

코드 내의 주석을 통해 설명 및 출력 결과를 작성했다. 이를 참고하면 좋을 듯 하다.


이름으로 유추할 수 있는 디자인 패턴 포스팅들

2021.12.18 - [Note] - [디자인패턴] Decorator Pattern - 데코레이터 패턴

2021.12.16 - [Note] - [디자인패턴] Factory Pattern - 팩토리 패턴

 

[디자인패턴] Factory Pattern - 팩토리 패턴

팩토리 패턴은 말 그대로 공장이다. 공장은 무엇을 하는가를 생각해보면 조금 이해가 쉽다. 공장은 무언가를 생성하는 곳이고, 그것을 대량으로 찍어내기도 한다. 핵심 키워드를 조금 더 좁혀본

supreme-ys.tistory.com

2021.12.15 - [Note] - [디자인패턴] Proxy Pattern - 프록시 패턴

 

[디자인패턴] Proxy Pattern - 프록시 패턴

프록시 패턴을 알기 위해선, 먼저 프록시(Proxy)가 무엇을 의미하는 것인지 알아야 한다. Proxy는 대리, 대신이라는 뜻을 갖고 있다. 그 말인 즉슨, 프로그래밍에서 프록시는 무엇인가를 대신, 대리

supreme-ys.tistory.com