💡 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴
하나의 인스턴스를 기반으로 해당 인스턴스를 다른 모듈들이 공유
데이터베이스 연결모듈에 많이 쓰임.
장점 : 인스턴스 생성할 때 드는 비용이 줄어듬
단점 : 의존성이 높아지고, TDD에 단점
해결 : 의존성 주입으로 간접적으로 의존성을 주입하여 모듈간의 결합을 느슨하게 만듬
- 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴
- 하나의 클래스를 기반으로 여러 개의 개별적인 인스턴스를 만들 수 있지만 그렇게 하지 않고
- 하나의 클래스기반으로 단 하나의 인스턴스를 만드는 일반적이다.
- 데이터베이스 연결모듈에 많이 쓰인다.
싱글톤이 아닌 클래스
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
const a = new Rectangle(1, 2)
const b = new Rectangle(1, 2)
console.log(a === b) // false
싱글톤패턴 - JS
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this
}
return Singleton.instance
}
getInstance() {
return this
}
}
const a = new Singleton()
const b = new Singleton()
console.log(a === b) // true
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
장점
- 하나의 인스턴스를 기반으로 해당 인스턴스를 다른 모듈들이 공유
- 인스턴스 생성할 때 드는 비용이 줄어든다.
- 인스턴스 생성에 많은 비용이 드는 I/O바운드 작업에 많이 사용
- I/O바운드란?
- 입출력(I/O) 작업이 시스템의 성능을 제한하는 상황을 말한다.
- 일반적으로 데이터를 읽거나 쓰는 작업을 수행
- 대표적인 예로는 파일 입출력, 네트워크 통신, 데이터베이스 쿼리 등
- CPU가 대기하는 동안에도 I/O 작업이 수행한다.
- 그러므로 프로그램의 성능은 I/O 작업의 속도에 영향을 받는다.
- 성능을 개선 방법
- I/O 바운드 프로그램의 경우에는 I/O 작업을 최적화
- 입출력 자원을 추가로 사용
- 다른 프로세스와의 경쟁을 줄이기
- 성능을 개선 방법
단점
- 의존성이 높아진다.
- TDD(Test Driven Development)를 할 때 걸림돌이 된다.
- 싱글톤 패턴은 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴으로 테스트마다 ‘독립적인’ 인스턴스를 만들기 어렵다.
- TDD를 할 때 단위 테스트를 주로 하는데, 단위 테스트는 테스트가 서로 독립적이어야 하며 테스트를 어떤 순서로든 실행할 수 있어야 한다.
의존성 주입
- 싱글톤 패턴은 사용하기 쉽고 실용적이지만 모듈 간의 결합이 강하게 만들 수 있다.
- 의존성 주입(DI, Dependency Injection)을 통해 모듈 간의 결합을 느슨하게 만들기
- 의존성이란 종속성이라고도 한다.
- 직접 다른 하위 모듈에 대한 의존성을 주기보다는 중간에 의존성 주입자가 간접으로 의존성을 주입하는 방식
- 메인 모듈은 하위 모듈에 대한 의존성이 떨어지게 된다.
- 이를 ‘디커플링이 된다’ 고도한다.
- 의존성 주입의 장점
- 모듈을 쉽게 교체할 수 있는 구조가 된다.
- 테스팅하기 쉽다.
- 마이그레이션 하기 수월해진다.
- 의존성 주입의 단점
- 복잡성이 증가 : 모듈들이 더욱 분리되면서 클래스 수가 늘어난다.
- 약간의 런타임 패널티가 생기기도 한다.
- 의존성 주입 원칙
- 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야 한다.
- 둘 다 추상화에 의존해야 한다.
- 추상화는 세부사항에 의존하지 말아야 한다.