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

 

객체의 생성은 오직 하나만 생성되는 것을 보장하며,
인스턴스에 접근할 수 있는 전역적인 접촉점을 제공하는 패턴

 

싱글톤 패턴의 특징

  • 객체의 인스턴스가 오직 단 1개만 생성이 된다.
  • 자바에서 객체를 생성할 때, new 라는 키워드를 이용하여 객체를 생성하는데, 싱글톤 패턴을 적용한 모든 코드에서 new는 단 한 번만 이루어지게 된다.

 

싱글톤 패턴을 사용하는 이유

  1. 메모리 측면에서의 이점
  2. 최초 한번의 new 연산자를 통해서 고정된 메모리 영역을 사용하기 때문에 메모리 낭비 방지할 수 있다.
  3. 다른 클래스간에 데이터 공유가 쉽다.
  4. 싱글톤 인스턴스가 전역으로 사용되는 인스턴스이기 때문에 다른 클래스의 인스턴스들이 접근하여 사용할 수 있다. 하지만 객체 접근 시 동시성 문제가 발생할 수 있으니 이점을 유의해서 설계하는 것이 좋다.

 

이러한 싱글톤 패턴이 장점이 강해서 무조건 사용해야 하는 것 처럼 보이지만 그렇지만은 않다. 

싱글톤 패턴의 단점

  • 개방-폐쇄 원칙 위배
  • 싱글톤 인스턴스가 너무 많은 일을 하거나 데이터를 공유시킬 경우에 다른 클래스의 인스턴스 간에 결합도가 높아진다.
  • 객체 지향 설계 원칙에 어긋나기 때문에 수정이 어려워지고 유지보수의 비용이 높아질 수 있다.
  • 멀티쓰레드 환경에서의 동시성 문제가 발생할 수 있다.

 

싱글톤 방식의 주의점

싱글톤 방식에서는 여러 클라이언트가 하나의 같은 객체 인스턴스를 공유하기 때문에 상태를 유지(stateful)하게 설계하면 안된다.

따라서, 무상태(stateless) 하게 설계해야 한다.

 

무상태(stateless) 란??

  • 특정 클라이언트에 의존적인 필드가 있으면 안된다.
  • 값을 변경할 수 있는 필드가 있으면 안된다.
  • 가급적 읽기만 가능해야 한다.
  • 공유되지 않는 지역변수, 파라미터등을 사용해야 한다.

 

자바에서의 싱글톤 패턴

자바에서의 싱글톤 패턴이란 JVM에서 클래스의 객체가 단 하나만 존재하게 하는 디자인 패턴이다.

클래스 내부에서 private static final 키워드로 객체를 생성한다.

  • 외부에서는 객체 생성 불가
  • 단 하나의 객체 생성

아래의 예시 코드를 통해 싱글톤 패턴을 이해 해보자.

 

SingletonService.java

public class SingletonService {

    private static final SingletonService instance = new SingletonService();

    public static SingletonService getInstance() {
        return instance;
    }

    private SingletonService() {
        
    }
}

 

SingletonTest.java

void singletonServiceTest(){
    SingletonService singletonService1 = SingletonService.getInstance();
    SingletonService singletonService2 = SingletonService.getInstance();

    System.out.println("singletonService1 = " + singletonService1);
    System.out.println("singletonService2 = " + singletonService2);
    
    Assertions.assertThat(singletonService1).isSameAs(singletonService2);
}

 

Result

singletonService1 = com.example.springdemostudy.singleton.SingletonService@6e4566f1
singletonService2 = com.example.springdemostudy.singleton.SingletonService@6e4566f1

getInstance를 통해 JVM 로딩 시에 생성된 객체 인스턴스를 비교했을 때 같은 객체임을 확인하여 싱글톤 패턴이 제대로 적용됬음을 알 수 있다.