Singleton pattern

Jay Jang·2022년 7월 1일
0

design pattern

목록 보기
1/1

Singleton (refactoring.guru)

싱글톤(Singleton) 패턴의 정의는 단순하다. 단독 개체 Singleton 이라는 이름에 걸맞게, 객체의 인스턴스가 오직 1개만 생성되는 패턴을 의미한다.

애플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하고(static) 그 메모리에 인스턴스를 만들어 사용하는 패턴이다.

그림과 코드를 통해 구조를 먼저 알아보자.

우선 코드를 통해 클래스 객체를 먼저 선언한다.

public class Singleton {

   //create an object of Singleton
   private static Singleton instance = new Singleton();

   //make the constructor private so that this class cannot be
   //instantiated
   private Singleton(){}

   //Get the only object available
   public static Singleton getInstance(){
      return instance;
   }

   public void showMessage(){
      System.out.println("Hello World!");
   }
}

이처럼 Singleton 이라는 클래스를 선언했다.

Singleton 클래스를 내부에 static으로 생성하고, 생성자의 접근자를 private로 하여 해당 클래스 생성자 접근에 제한을 두었다.

객체에 접근할 수 있는 유일한 방법은 getInstance() 메소드를 통해 instance에 접근하는 것 뿐이다.

이제 외부에서 이 유일한 객체 인스턴스에 접근해보자.

public class SingletonPatternDemo {
   public static void main(String[] args) {

      //illegal construct
      //Compile Time Error: The constructor SingleObject() is not visible
      //Singleton object = new Singleton();

      //Get the only object available
      Singleton object = Singleton.getInstance();

      //show the message
      object.showMessage();
   }
}

클래스 생성자 접근자를 private로 제한을 두었기 때문에 new 를 통해 클래스 인스턴스를 생성하는 것이 불가능하다. visible 하지도 않다.

앞에서 말했듯이 이 클래스 인스턴스에 접근할 수 있는 유일한 방법은 getInstance() 메소드를 통해 static 설정한 필드에 접근하는 것이다.

이제 이 구조를 나타내면 다음과 같다.

Singleton (refactoring.guru)

그렇다면 오직 한개의 인스턴스, 싱글톤 패턴을 사용하여 우리는 무엇을 얻을 수 있을까?


why we use singleton?


다시 말하지만 싱글톤 패턴은 객체 생성자 접근을 막아 놓고 static 인스턴스로만 접근할 수 있다. 최초의 한 번 new 이후 다시 사용하지 않기 때문에 인스턴스 생성으로 인한 메모리 낭비를 방지할 수 있다.

또한 이미 생성된 인스턴스를 사용하기 때문에 속도 측면에서도 이점이 있다.

자원 공유의 측면도 있다. 서로 다른 클래스간의 데이터 공유가 용이하다. 싱글톤 인스턴스는 전역으로 사용되는 인스턴스이기 때문에 다른 클래스의 인스턴스들이 접근하여 사용할 수 있다. 하지만 이는 때로 문제가 되기도 하는데, 여러 클래스의 인스턴스에서 싱글톤 인스턴스의 데이터에 동시에 접근하게 되면 동시성 문제가 발생할 수 있다. Thread safe 하지 못할수도 있다는 것이다.

또한 도메인 관점에서 인스턴스가 한 개만 존재해야만 하는 경우 사용하기도 한다.


Singleton (refactoring.guru)

이처럼 싱글톤 인스턴스는 효율적이다. 그렇다면 단점은 없을까?


Problem


싱글톤 패턴을 구현하는 코드 자체가 많이 필요하다. 앞서 소개한 방법 외에도 정적 팩토리 메서드에서 객체 생성을 확인하고 생성자를 호출하는 경우에 멀티스레딩 환경에서 발생할 수 있는 동시성 문제를 해결하기 위해 동기화 처리를 위해 synchronized 키워드를 사용해야 한다. 동기화 처리하지 않으면 인스턴스 2개가 생성될 수 있는 가능성이 생긴다.

그 다음은 테스트하기 어렵다는 것이다. 싱글톤 인스턴스는 자원을 공유하고 있기때문에 테스트가 격리된 환경에서 수행되기 위해선 매번 인스턴스의 상태를 초기화시켜야 한다. 그렇지 않으면 애플리케이션 전역에서 상태를 공유하기 때문에 테스트가 온전하게 수행되지 못한다.

또한 싱글톤 인스턴스가 너무 많은 일을 하거나 많은 자원을 공유시킬 경우에, 다른 클래스의 인스턴스들 간에 결합도가 높아진다. 이는 SOLID개방-폐쇄 원칙Open-Closed Principle OCP을 위배하며, 의존 관계상 클라이언트가 추상 클래스(인터페이스)가 아닌 구체 클래스에 의존하게 되기 때문에, SOLID의존 관계 역전의 원칙 Dipendency Inversion Principle을 위반하게 된다.

이외에도 클래스 상속이 불가하다는 점과, 상태 변경이 어렵다는 등 여러가지 문제가 존재한다. 결과적으로 이런 문제들과 함께 싱글톤 패턴은 유연성이 떨어진다고 할 수 있다.


결론


싱글톤 패턴이 무엇인지 알아보았다. 싱글톤 인스턴스로 얻을 수 있는 이점과, 문제점에 대해 이야기했다.

Spring Bean이 컨테이너의 도움을 받아 싱글톤 scope으로 관리되고 있다는 것을 이야기 하며 글을 마친다.



REFERENCE


Singleton (refactoring.guru)
Singleton Design Pattern (sourcemaking.com)
Design Pattern - Singleton Pattern (tutorialspoint.com)
싱글톤(Singleton) 패턴이란? (techcourse.co.kr)
[디자인 패턴] 싱글톤 패턴(Singleton Pattern) 정리 및 예제 - 생성 패턴 (tistory.com)

profile
그때는맞고지금은틀리다

0개의 댓글