본문 바로가기
아키텍처/디자인 패턴

5. Singleton Pattern

by doflamingo 2020. 12. 13.

싱글턴 패턴은 클래스가 단 하나의 인스턴스만 갖도록 하는 디자인 패턴을 의미한다.

 

singleton pattern

 

그러나 만들 때 주의할 점이 있다. 

  1. 생성자는 private으로 만들어서 새로운 인스턴스를 생성하지 못하게 만들어야 한다. 
  2. 최초 생성을 할 때는 getInstance와 같은 하나의 인스턴스를 가져오는 메소드 내에서 생성을 해준다

예를 통해서 확인해보자. 

우리는 SystemSpeaker라는 클래스를 싱글턴으로 만들 것이다. 

 

public class SystemSpeaker {
  private static SystemSpeaker instance;
  private int volume;

  private SystemSpeaker() {
    volume = 5;
  };

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

    return instance;
  }

  public int getVolume() {
    return volume;
  }

  public void volumeUp() {
    volume++;
  }
  public void volumeDown() {
    if(volume > 0)
      volume--;
  }
}

위에서 말한대로 생성자를 private으로 생성한 후 instance가 존재하지 않을 때만 instance를 새로 생성하게 만들었다. 

이렇게 만든 SystemSpeaker 인스턴스가 정말 단 하나인지 아래를 통해서 확인해볼 수 있다. 

public class Main {
  public static void main(String[] args) {
    SystemSpeaker systemSpeaker1 = SystemSpeaker.getInstance();
    SystemSpeaker systemSpeaker2 = SystemSpeaker.getInstance();

    System.out.println(systemSpeaker1.getVolume());
    System.out.println(systemSpeaker2.getVolume());

    //1번 볼륨 업
    systemSpeaker1.volumeUp();
    System.out.println(systemSpeaker1.getVolume());
    System.out.println(systemSpeaker2.getVolume());

    //2번 볼륨 다운
    systemSpeaker2.volumeDown();
    System.out.println(systemSpeaker1.getVolume());
    System.out.println(systemSpeaker2.getVolume());


    System.out.println(systemSpeaker1);
    System.out.println(systemSpeaker2);

  }
}

systemSpeaker1과 systemSpeaker2를 각각 getInstance를 통해서 가져온 후 1번을 볼륨 업 하고 결과를 확인하고 2번을 볼륨 다운하고 확인을 했다. 

그리고 마지막에는 실제 systemSpeaker1과 systemSpeaker2가 각각 가리키는 주소 값을 확인했다. 

결과는 아래와 같이 하나의 변수만 볼륨업, 다운을 했는데도 두개가 다 변한 것을 볼 수 있다. 

즉, 같은 인스턴스를 가리키는 걸 알 수 있다. 

그리고 가리키는 주소 값 역시 같음을 알 수 있다. 

결과화면

 

코드

 

 

싱글턴 객체를 사용하는 이유는 무엇일까?

 

싱글턴은 객체가 하나의 인스턴스만 갖고 있기 때문에 객체가 계속 생성돼서 메모리가 낭비되는 것을 막을 수 있다.

또한, 객체가 딱 하나임을 보증하고 싶을때 사용한다. 

예를 들어, DBCP(DB Connection Pool) 같은 곳에서 같은 방법으로 Connection을 열었다 닫았다 하는데 굳이 새로 객체를 여러개 생성해서 좋을게 없기 때문이다.

또한, 객체 로딩시간 또한 줄어들어 성능적으로도 이점을 볼 수 있다.

 

 

 

그렇다면 싱글턴의 단점은 없을까?

 

싱글턴 객체는 첫번째로 Unit Test가 어렵다는 점을 들수 있다.

싱글턴 객체는 Mocking을 하기 어렵기 때문에 싱글턴 객체에 의존성이 있는 객체는 분리해서 유닛테스트를 진행할수 없다.

 

또한, 싱글턴 객체를 처음 생성할 때, 동기화를 해주지 않으면 싱글턴 객체가 여러개 생길 수 있다. 그렇기 때문에 반드시 synchronized로 동기화를 해줘야 한다.

아니면 

그리고 인스턴스가 한개라고 하더라도 리플렉션을 이용하면 객체를 더 생성해낼 수도 있다. 

 

 

 

 

 

 

- 출처 -

youtu.be/5jgpu9-ywtY

javacodetips.blogspot.com/2014/04/design-patterns-singleton-pattern.html

www.vojtechruzicka.com/singleton-pattern-pitfalls/

'아키텍처 > 디자인 패턴' 카테고리의 다른 글

4. Factory Method Pattern  (0) 2020.12.13
3. Template Method Pattern  (0) 2020.12.13
2. Adapter Pattern  (2) 2020.12.10
1. Strategy Pattern  (0) 2020.12.09

댓글