클래스의 인스턴스를 하나로 제한하고 그 인스턴스에 접근할 전역 지점을 주는 패턴. 생성자를 막고 정적 메서드로 하나뿐인 인스턴스를 돌려준다.
class Config {
private static instance?: Config
private constructor(readonly values: Record<string, string>) {}
static get() {
return (this.instance ??= new Config(loadValues()))
}
}남용을 조심한다
- 사실상 전역 변수라서 숨은 결합을 만든다. 어디서든 꺼내 쓸 수 있으니 의존 관계가 코드에 드러나지 않는다
- 테스트끼리 상태를 공유해 순서에 따라 결과가 달라지고, 가짜로 바꿔 끼우기 어렵다
- 그래서 대안을 먼저 본다. 필요한 곳에 인스턴스를 넘겨주는 의존성 주입(Dependency Injection, DI)이나, 모듈을 한 번만 평가하는 언어 특성을 쓰는 방법이다. ES 모듈과 파이썬 모듈은 처음 import될 때 한 번만 실행되므로 모듈 수준 객체가 이미 싱글턴 역할을 한다(모듈 패턴과 노출 모듈 패턴, 파이썬 모듈과 패키지)
스프링 빈은 기본이 싱글턴 스코프(Singleton Scope)지만, 클래스가 스스로 하나임을 강제하는 게 아니라 컨테이너가 하나만 만들어 주입하는 방식이라 위 문제가 덜하다(빈 스코프). 대신 상태를 가진 싱글턴 빈은 여러 요청이 동시에 공유하니 조심해야 한다. 생성 패턴 전체는 생성 패턴.