Skip to content

singleton-pattern

TL;DR

싱글톤 패턴은 애플리케이션에서 하나의 클래스에 대해 단 하나의 인스턴스만 존재하도록 보장하는 패턴임. 이를 통해 전역적으로 접근 가능한 유일한 인스턴스를 제공함.

활용성

  • 시스템에서 유일해야 하는 인스턴스를 제공하고자 할 때 유용함 (예: 데이터베이스 연결, 설정 관리 객체).
  • 전역적으로 접근할 필요가 있는 객체가 있을 때 사용됨 (예: 로깅 서비스, 캐시).
  • 자원의 낭비를 방지하기 위해 객체를 단일 인스턴스로 제한하고자 할 때 적합함.

결과

  • 장점

    • 단일 인스턴스를 보장할 수 있음.
    • 전역 접근이 가능함.
    • 자원 절약 효과가 있음.
  • 단점

    • 테스트가 어려워질 수 있음.
    • 의존 관계가 숨겨질 수 있음.
    • 멀티스레딩 환경에서 잘못 구현하면 문제가 발생할 수 있음.

단점에 대한 상세 노트

테스트가 어려워지는 이유

  • 싱글톤 패턴을 사용하면 클래스의 인스턴스가 하나만 존재하도록 강제됨.
  • 이로 인해 전역적으로 접근 가능한 상태가 만들어지는데, 이 전역 인스턴스는 여러 테스트에서 공유될 수 있음.
  • 예를 들어, 테스트 A에서 싱글톤 인스턴스의 상태를 변경한 후, 테스트 B에서도 같은 인스턴스를 사용하게 되면, B는 A의 영향을 받을 수 있음.
  • 이렇게 되면 각 테스트가 독립적으로 동작하지 않고 서로 간섭하게 되어, 예측할 수 없는 테스트 결과가 발생할 수 있음.
  • 특히, 테스트 실행 순서에 따라 결과가 달라지는 문제가 발생할 수 있어, 단위 테스트의 신뢰성이 떨어지게 됨.

의존 관계가 숨겨지는 이유

  • 싱글톤 패턴은 전역적인 접근을 가능하게 하기 때문에, 다른 클래스들이 싱글톤 인스턴스를 직접 참조하게 됨.
  • 이 경우 의존 관계가 코드에서 명시적으로 드러나지 않음.
  • 예를 들어, 클래스 A가 싱글톤 B를 사용한다고 가정하면, A는 B를 생성자나 메서드 매개변수로 받지 않고 전역적으로 접근하여 사용함.
  • 이로 인해 A와 B 간의 의존성이 코드상에 명확하게 나타나지 않음. 의존성이 숨겨지면, 코드의 유연성이 떨어지고, 나중에 B를 교체하거나 확장하기 어려워짐. 이는 유지보수성과 테스트 가능성을 저하시킴.
  • 또한, 싱글톤에 대한 의존성이 여러 클래스에 퍼져 있을 경우, 해당 싱글톤을 교체하거나 모킹(mocking)하는 것이 어려워지며, 전체 시스템의 결합도가 높아져 코드의 유연성과 재사용성이 낮아짐.

구현

  • Singleton: 인스턴스 생성을 제어하며, 하나의 인스턴스만 생성되도록 보장함.
  • Client: 싱글톤 인스턴스에 접근하여 필요한 작업을 처리함.

예시 코드

class SingletonMeta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            instance = super().__call__(*args, **kwargs)
            cls._instances[cls] = instance
        return cls._instances[cls]

class Singleton(metaclass=SingletonMeta):
    def __init__(self, value: str):
        self.value = value

    def business_logic(self):
        return f"비즈니스 로직 수행: {self.value}"

if __name__ == "__main__":
    s1 = Singleton("첫 번째 인스턴스")
    s2 = Singleton("두 번째 인스턴스")

    print(s1.business_logic())  # "첫 번째 인스턴스" 출력
    print(s2.business_logic())  # "첫 번째 인스턴스" 출력

    print(s1 is s2)  # True 출력, 두 인스턴스는 동일함을 확인

요약

  • 싱글톤 패턴은 클래스의 인스턴스가 하나만 생성되도록 보장하면서도, 해당 인스턴스에 전역적으로 접근할 수 있는 방법을 제공함.
  • 이 패턴은 주로 애플리케이션에서 유일한 인스턴스가 필요할 때, 또는 전역 접근이 필요한 객체가 있을 때 유용함. 하지만 멀티스레딩 환경에서 주의 깊게 구현하지 않으면 문제가 발생할 수 있음.