본문 바로가기

설계

[디자인 패턴] 싱글턴 패턴 (Singleton Pattern) - python 예제 코드

싱글턴 패턴(Singleton Pattern)은 객체 생성에 대한 디자인 패턴 중 하나입니다. 이 패턴은 어떤 클래스를 단 하나의 인스턴스만 생성하도록 보장하며, 해당 인스턴스를 전역에서 접근 가능하게 합니다.

1. 구현 방법


싱글턴 패턴을 구현하는 방법은 다양하지만, 대표적으로는 클래스 내부에 인스턴스 변수를 선언하고, 해당 클래스의 생성자 메서드를 private로 만드는 것입니다. 그리고 클래스 내부에서는 해당 클래스의 인스턴스가 생성되어있는지 확인하고, 생성되어 있지 않으면 인스턴스를 생성하는 정적 메서드를 제공합니다.

2. 예제 코드

다음은 파이썬으로 구현한 싱글턴 패턴 예제입니다.

class Singleton:
    __instance = None  # 클래스 내부에 유일한 인스턴스를 저장할 클래스 변수

    @staticmethod
    def getInstance():
        """ 유일한 인스턴스를 반환하는 정적 메서드 """
        if Singleton.__instance == None:
            Singleton()
        return Singleton.__instance

    def __init__(self):
        """ 생성자 메서드를 private로 만들어 객체 생성을 제한 """
        if Singleton.__instance != None:
            raise Exception("이 클래스는 싱글턴 패턴으로 구현되었습니다. getInstance() 메서드를 사용하세요.")
        else:
            Singleton.__instance = self

s1 = Singleton.getInstance() # 인스턴스 생성
s2 = Singleton.getInstance() # 기존 인스턴스 반환

print(s1) # <__main__.Singleton object at 0x7f3ecb7f7520>
print(s2) # <__main__.Singleton object at 0x7f3ecb7f7520>
print(s1 == s2) # True


위의 예제 코드에서 __instance는 클래스 변수로 유일한 인스턴스를 저장하기 위한 용도로 사용됩니다. getInstance() 메서드는 유일한 인스턴스를 반환하기 위한 정적 메서드입니다. 만약 __instance에 인스턴스가 생성되어 있지 않다면, 생성자 메서드를 호출하여 인스턴스를 생성하고, __instance에 저장한 후 반환합니다.

생성자 메서드인 __init__()은 private로 선언되어 클래스 외부에서는 호출할 수 없습니다. 이로써 클래스 인스턴스를 직접 생성하는 것을 방지하고, getInstance() 메서드를 통해서만 유일한 인스턴스를 생성하도록 합니다.

위의 예제 코드를 실행하면 s1과 s2 객체는 동일한 객체를 참조하게 됩니다. 이는 getInstance() 메서드가 항상 동일한 인스턴스를 반환하도록 구현되어 있기 때문입니다.

3. 장점


유일한 인스턴스를 전역에서 접근 가능하게 함으로써 전체 시스템에서 일관성 있는 상태를 유지할 수 있습니다. 인스턴스 생성, 관리 등의 로직을 캡슐화하여 코드의 가독성과 유지 보수성을 높일 수 있습니다. 다중 스레드 환경에서 안전하게 인스턴스를 생성하고 관리할 수 있습니다.

4. 단점


유일한 인스턴스가 전역에서 접근 가능하게 되므로, 해당 인스턴스의 상태를 변경하는 작업이 다른 부분에 영향을 줄 수 있습니다. 객체 지향 설계 원칙 중 하나인 "개방-폐쇄 원칙"에 어긋날 수 있습니다. 즉, 클래스를 확장하거나 수정하기가 어려울 수 있습니다. 싱글턴 패턴이 항상 필요한 것은 아니므로, 불필요하게 사용하면 코드의 복잡도를 증가시킬 수 있습니다.

싱글턴 패턴은 유용한 디자인 패턴 중 하나입니다. 그러나 필요하지 않은 경우에는 불필요한 코드를 작성하게 되므로, 사용할 때는 신중하게 판단해야 합니다.