싱글톤 패턴(singleton pattern): 하사용자가 여러 번 객체 생성을 하더라도 클래스로부터 오직 하나의 객체(인스턴스)만 생성되도록 하는 디자인 패턴. 보통 데이터베이스 연결 모듈에 많이 사용된다.
(디자인 패턴: 프로그램을 설계할 때 발생했던 문제점들을 객체 간의 상호 관계 등을 이용하여 해결할 수 있도록 하나의 '규약' 형태로 만들어 놓은 것)
class Singleton(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"): # Foo 클래스 객체에 _instance 속성이 없다면
print("__new__ is called\n")
cls._instance = super().__new__(cls) # Foo 클래스의 객체를 생성하고 Foo._instance로 바인딩
return cls._instance # Foo._instance를 리턴
def __init__(self, data):
cls = type(self)
if not hasattr(cls, "_init"): # Foo 클래스 객체에 _init 속성이 없다면(instance가 생성된 적이 없다면)
print("__init__ is called\n")
self.data = data
cls._init = True
s1 = Singleton(3) # __new__is called
s2 = Singleton(4) # __init__is called
print(s1.data) # 3
print(s2.data) # 3
print(s1 is s2) # True(같은 주소를 가지고 있는 두 객체 s1, s2)
예제 코드에서 알 수 있다시피 s1 = Singleton(3)
에서 인스턴스가 생성되었으므로, s2 = Singleton(4)
에서 새로운 인스턴스를 생성하지 않고 앞서 만들어진 인스턴스를 가리키게 된다. 고로, s1과 s2는 하나의 객체를 가리키므로 주소와 데이터 모두 동일하다.
싱글톤 패턴은 사용하기 쉽고 굉장히 실용적이지만 모듈 간의 결합을 강하게 만든다는 즉, 하나의 모듈의 변경사항이 다른 모듈에 영향을 미칠 수 있다는 단점이 있다. 이때 의존성 주입(DI, Dependency Injection)을 통해 모듈 간의 결합을 조금 더 느슨하게 만들어 해결할 수 있다.
앞의 그림처럼 메인 모듈(main mudule)이 '직접' 다른 하위 모듈에 대한 의존성을 주기보다는 중간에 의존성 주입자(dependency injector)가 이 부분을 가로채 메인 모듈이 '간접'적으로 의존성을 주입하는 방식이다.
이를 통해 메인 모듈(상위 모듈)은 하위 모듈에 대한 의존성이 떨어지게 된다. 참고로 이를 '디커플링이 된다'고도 한다.
장점 부분 실수롤 이라는 오타가 있습니다.