(디자인 패턴)싱글톤 패턴 (Singleton Pattern)

Singleton
홍윤's avatar
Aug 14, 2024
(디자인 패턴)싱글톤 패턴 (Singleton Pattern)
💡
싱글톤 패턴(Singleton Pattern)은 소프트웨어 디자인 패턴 중 하나로, 클래스의 인스턴스를 하나만 생성하여 전역적으로 접근할 수 있도록 하는 패턴입니다. 이 패턴은 애플리케이션 내에서 어떤 클래스가 딱 하나의 객체만 필요하고, 그 객체를 어디서든 접근할 수 있어야 할 때 사용됩니다.
 

싱글톤 패턴의 주요 개념

  1. 유일한 인스턴스:
      • 싱글톤 패턴은 특정 클래스의 인스턴스를 하나만 생성하고, 그 인스턴스를 전역적으로 접근할 수 있도록 보장합니다. 이 유일한 인스턴스는 프로그램이 실행되는 동안 공유됩니다.
  1. 전역 접근:
      • 싱글톤 객체는 전역적으로 접근 가능하기 때문에, 어디서든 같은 인스턴스를 사용할 수 있습니다. 이를 통해 전역 상태나 설정 정보를 관리하는 데 유용합니다.
  1. 인스턴스 생성의 제어:
      • 클래스 외부에서 직접 인스턴스를 생성하지 못하도록, 생성자를 private으로 설정합니다. 인스턴스는 클래스 내부에서 관리되며, 필요한 경우에만 생성됩니다.

싱글톤 패턴의 구조

  1. Private 생성자:
      • 클래스의 생성자는 외부에서 호출할 수 없도록 private으로 선언됩니다. 이를 통해 외부에서 직접 객체를 생성하는 것을 방지합니다.
  1. Static 인스턴스 변수:
      • 클래스 내부에 유일한 인스턴스를 가리키는 static 변수를 선언합니다. 이 변수는 클래스가 처음 로드될 때 메모리에 할당됩니다.
  1. Static 메서드:
      • 외부에서 인스턴스에 접근할 수 있도록 static 메서드를 제공합니다. 이 메서드는 인스턴스가 존재하지 않으면 생성하고, 이미 존재하면 기존 인스턴스를 반환합니다.

싱글톤 패턴의 예시 (Java)

public class Singleton { // 유일한 인스턴스를 저장할 static 변수 private static Singleton instance; // 생성자는 private으로 외부에서 접근 불가 private Singleton() { // 생성자 로직 } // 인스턴스를 반환하는 static 메서드 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }

싱글톤 패턴의 장점

  1. 전역적인 접근:
      • 프로그램 어디에서든지 동일한 인스턴스를 사용할 수 있습니다. 전역 상태 관리에 유리합니다.
  1. 메모리 절약:
      • 객체를 하나만 생성하기 때문에 불필요한 메모리 낭비를 줄일 수 있습니다.
  1. 인스턴스 제어:
      • 객체 생성의 과정을 제어할 수 있습니다. 예를 들어, 인스턴스를 처음 사용할 때만 생성되도록 할 수 있습니다.

싱글톤 패턴의 단점

  1. 테스트의 어려움:
      • 전역적인 상태를 가지므로, 단위 테스트를 할 때 의존성 주입(Dependency Injection) 방식과 충돌할 수 있습니다. 이는 테스트의 복잡성을 증가시킵니다.
  1. 멀티스레드 환경에서의 문제:
      • 싱글톤 패턴은 멀티스레드 환경에서 동시 접근 시 문제를 일으킬 수 있습니다. 동기화(synchronization)를 사용하여 이를 해결할 수 있지만, 성능 저하를 초래할 수 있습니다.
  1. 클래스 간 결합도 증가:
      • 싱글톤 패턴을 사용하면 클래스 간의 결합도가 증가할 수 있어, 유지보수가 어려워질 수 있습니다.

싱글톤 패턴의 변형

  • 이른 초기화 (Eager Initialization):
    • 클래스가 로드될 때 싱글톤 인스턴스를 미리 생성하는 방식입니다. 인스턴스 생성 비용이 낮거나, 인스턴스가 항상 사용될 때 유리합니다.
    • public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; } }
  • 느린 초기화 (Lazy Initialization):
    • 인스턴스가 처음 필요할 때 생성하는 방식으로, 위의 예시가 이에 해당합니다. 인스턴스가 필요 없을 때는 메모리를 절약할 수 있지만, 멀티스레드 환경에서 주의가 필요합니다.
  • 더블 체크 락킹 (Double-Checked Locking):
    • 멀티스레드 환경에서 안전하게 싱글톤 인스턴스를 생성하기 위해 사용하는 방식입니다. 인스턴스가 null인지 두 번 확인한 후 동기화 블록을 사용하여 생성합니다.
    • public class Singleton { private static volatile Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
싱글톤 패턴은 특정 클래스의 인스턴스가 하나만 존재해야 할 때, 그리고 전역적으로 접근이 필요할 때 매우 유용한 패턴입니다. 하지만 사용 시에는 단점과 주의사항을 고려하여 신중하게 적용해야 합니다.
notion image

1. 싱클톤 패턴 연습 예제 및 해설

App
package ex04; /** * * Animal 생성 (abstract) * 타입 일치(다형성) = 쥐(동물), 호랑이(동물) * 문지기한테 DIP만 지켜주면 됨 */ public class App { public static void main(String[] args) { Doorman d1 = Doorman.instance; Doorman d2 = Doorman.instance; // new 두번 하는 거 막기 (싱클톤 패턴) System.out.println(d1.hashCode()); System.out.println(d2.hashCode()); } }
  • 싱글톤 패턴을 사용하여 ‘Doorman’ 클래스의 인스턴스를 하나만 생성합니다.
  • ‘d1’ 과 ‘d2’는 동일한 ‘Doorman’ 인스턴스를 참조하며, 이를 ‘hasCode()’ 메소드를 통해 동일한지 확인하다.
  • 싱클톤 패턴은 클래스의 인스턴스를 전역적으로 하나만 유지하고자 할 때 사용됩니다.

Doorman
package ex04; /** * 문지기한테 DIP만 지켜줘라는 뜻은 * 하나만 지키게 하라 즉 Animal이라는 부모에 속한 쥐, 호랑이들을 * App인 큰 틀에서 책임지게 만들어라는 뜻! * * */ public class Doorman { //staic박스에는 doorman이 나왔고 public static Doorman instance = new Doorman(); //메소드 하나 만들기 // public static Doorman getInstance() { // return doorman; // } private Doorman(){} // 쥐 출입금지 //heap에는 쫓아내만 떠있다. public void 쫒아내(Animal m) { System.out.println(m.getName()+"쫒아내"); } }
  • 싱클톤 패턴을 사용하여 ‘Doorman’ 클래스의 유일한 인스턴스를 ‘instance’ 라는 정적 변수로 선언했다.
  • ‘private’ 생성자를 사용하여 외부에서 인스턴스를 생성하지 못 하도록 하고, 인스턴스를 클래스 내부에서만 생성할 수 있게 한다.
  • DIP원칙을 지키며, ‘Doorman’ 클래스는 ‘Animal’이라는 추상화된 타입을 사용하여 다양한 동물 객체를 처리합니다.
Share article

Uni