싱글톤 패턴(singleton pattern)은 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴으로, 보통 데이터베이스 연결 모듈에 많이 사용됩니다.
하나의 인스턴스를 다른 모듈들이 공유하며 사용하기 떄문에 인스턴스를 생성할 때 드는 비용이 줄어들지만, 의존성이 높아진다는 단점이 있습니다.
객체 : 소프트웨어 세계에 구현할 대상
클래스 : 구현을 위한 설계도
인스턴스 : 설계도에 따라 소프트웨어 세계에 구현된 실체
// js
// DB 연결을 하는 것이기 때문에 비용이 더 높은 작업
const URL = 'mongodb://localhost:27017/kundolapp'
const createConnection = url => ({"url" : url})
class DB {
constructor(url) {
if (!DB.instance) {
DB.instance = createConnection(url)
}
return DB.instance
}
connect() {
return this.instance
}
}
const a = new DB(URL)
const b = new DB(URL)
console.log(a === b) // true
이렇게 DB.instance라는 하나의 인스턴스를 기반으로 a, b를 생성합니다.
이를 통해 데이터베이스 연결에 관한 인스턴스 생성 비용을 아낄 수 있습니다.
싱글톤 패턴은 TDD(Test Driven Development)를 할 때 걸림돌이 됩니다. TDD를 할 때 단위 테스트를 주로 하는데, 단위 테스트는 서로 독립적이어야 하며 테스트를 어떤 순서로든 실행할 수 있어야 합니다.
하지만 싱글톤 패턴은 하나의 인스턴스를 기반으로 구현하는 패턴이므로 각 테스트마다 '독립적인' 인스턴스를 만들기가 어렵습니다.
싱글톤 패턴은 모듈 간의 결합을 강하게 만들 수 있다는 단점이 있습니다. 이때 의존성 주입(DI, Dependency Injection)을 통해 모듈 간의 결합을 좀 더 느슨하게 만들어 해결할 수 있습니다.
의존성(종속성) : A가 B에 의존성이 있다는 것은 B의 변경 사항을 A도 따라야 한다는 것
위 그림처럼 의존성 주입자(dependency injector)가 중간에 의존성을 가로채 메인 모듈이 간접적으로 의존성을 주입하는 방식입니다.
이를 통해 메인 모듈(상위 모듈)은 하위 모듈에 대한 의존성이 떨어지게 됩니다.
이를 '디커플링이 된다'고도 합니다.
마이그레이션 : 데이터나 소프트웨어를 한 시스템에서 다른 시스템으로 이동하는 것
의존성을 주입할 때는 위 세 가지 원칙을 지켜주면서 만들어야 합니다.