싱글톤 패턴(Singleton Pattern)은 클래스의 인스턴스가 오직 하나만 존재하도록 보장하고, 전역 접근점을 제공하는 생성 패턴이다. DB 연결, 설정 관리, 로거 등에 사용된다.
python
import threading
# 방법 1: __new__ 오버라이드
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
# 방법 2: 메타클래스
class SingletonMeta(type):
_instances = {}
_lock = threading.Lock()
def __call__(cls, *args, **kwargs):
with cls._lock:
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class DatabaseConnection(metaclass=SingletonMeta):
def __init__(self, url: str = ""):
if not hasattr(self, '_initialized'):
self.url = url
self._conn = None
self._initialized = True
def connect(self):
if not self._conn:
print(f"Connecting to {self.url}")
# 실제 연결 로직
return self._conn
# 방법 3: 데코레이터
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class Config:
def __init__(self):
self.debug = False
멀티스레드 안전성 확인
python
import threading
def test_thread():
db = DatabaseConnection("postgres://localhost/mydb")
print(id(db))
threads = [threading.Thread(target=test_thread) for _ in range(10)]
for t in threads: t.start()
for t in threads: t.join()
# 모두 동일한 id 출력 → 싱글톤 확인
싱글톤의 문제점과 대안
| 문제 | 설명 | 대안 |
|---|
| 전역 상태 | 테스트 격리 어려움 | 의존성 주입 |
| 멀티스레드 | 경쟁 조건 가능 | 잠금 또는 모듈 수준 변수 |
| 테스트 어려움 | 상태 공유로 결합 | 인터페이스 추출 |
관련 개념