싱글톤 패턴이란? 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴
생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이우에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴
- 프로그램 내에서 하나의 객체만 존재
- 프로그램 내에 여러 곳에서 해당 객체를 공유받아 사용해야하는 경우
싱글톤 패턴의 장점
1. 메모리 측면의 이점
싱글톤 패턴을 사용하게 될 경우 한 개의 인스턴스만을 사용하기 때문에 메모리 낭비를 방지할 수 있다.
2. 속도 측면의 이점
생성된 인스턴스를 사용할 때마다 이미 생성된 인스턴스를 활용함으로 속도 측면에 이점이 있다.
3. 데이터 공유가 쉽다.
전역으로 사용하는 인스턴스이기 때문에 다른 여러 클래스에서 데이터를 공유하여 사용할 수 있다.
💡 경험
웹 사이트 크롤링을 위해 여러 개의 크롤러를 띄워논 상황.
여러 명이 크롤러를 돌리는데 이 때 DB 접근을 할 때 매 번 DB Instance를 만들어서 사용했었다.
여러 명과 여러 개의 크롤러에서 매 번 DB Instance를 생성하여 사용했기 때문에 DB에 과도한 부하가 발생
👉 싱글톤 패턴을 사용하여 DB 접근을 위한 Instance를 만들고 그 Instance를 재 사용함으로서 DB 부하를 줄였던 경험
자바스크립트에서의 싱글톤 (간단하게)
자바스크립트에서 리터럴 {} 또는 new Object로 객체를 생성하게 되면 각각의 객체로서 생성된 것이여서 이 자체로 싱글톤 패턴을 구현할 수 있다.
const obj = { name: '전다훈' };
const obj2 = { name: '전다훈' };
console.log(obj === obj2) // false
흔히 싱글톤 패턴을 활용하는 곳은 데이터베이스 연결을 할 때 사용한다.
import {MongoClient} from "mongodb";
export class MongoConn {
private connection: string = '몽고 URL'
private static instance: MongoConn;
private db?: MongoClient;
static get getInstance () {
// DB Instance가 존재하지 않을 경우 DB Instace 생성
if(!MongoConn.instance) MongoConn.instance = new MongoConn();
return MongoConn.instance;
}
async connect (): Promise<MongoClient> {
try {
if(this.db && this.db.isConnected()) return this.db;
console.warn(this.connection);
this.db = new MongoClient(this.connection, {
autoReconnect: true,
useNewUrlParser: true,
reconnectTries: 3,
reconnectInterval: 2000,
poolSize: 40,
socketTimeoutMS: 360000,
keepAlive: true,
useUnifiedTopology: true,
});
console.warn('connect');
return await this.db.connect();
}catch (e) {
throw new Error(e);
}
}
}
싱글톤 패턴의 단점
1. 객체 지향 설계 원칙(SOLID) 중 개방-폐쇄 원칙(Open-Closed Principle)에 위배
만약 싱글톤 인스턴스가 혼자 많은 작업을 하거나, 많은 데이터를 공유시키면 다른 클래스들 간의 결함도가 높아지게 되는데 이 때 개방-폐쇄 원칙에 위배된다.
결합도가 높아지게 되면, 수정하기 어렵고 테스트도 원활하게 진행할 수 없는 문제점이 발생한다.
💡 결합도 문제의 경우 의존성 주입 (DI, Dependecy Injection)을 통하여 모듈 간의 결합을 좀 더 느슨하게 만들어 해결할 수 있다.
(그림 1)처럼 메인 모듈이 직접 하위 모듈에 대한 의존성을 주입 하기 보다는 (그림 2)처럼 중간에 의존성 주입자(Dependency Injector)가 이 부분을 담당하여 간접적으로 의존성을 주입하는 방식
의존성 주입의 장점
- 모듈 간 쉽게 교체할 수 있는 구조가 되어 테스트 및 마이그레이션에 용이
- 추상화 레이어를 넣고 이를 기반으로 구현체를 넣어 주기 때문에 애플리케이션 의존성 방향이 일관됨
- 애플리케이션을 쉽게 추론할 수 있으며, 모듈간의 관계가 명확해짐
의존성 주입의 단점
- 모듈들이 더 분리되기 때문에 클래스 수가 증가함
- 클래스 수 증가에 따른 복잡성이 증가될 수 있으며, 약간의 런타임 패널티가 발생
💡 의존성 주입 원칙
1. 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야한다.
2. 둘 다 추상화에 의존해야하며, 이 때 추상화는 세부 사항에 의존하지 말아야한다.
👉 추상화에 의존해야지 구현체에 의존하면 안된다. 그래야 유연하게 구현체를 변경할 수 있다.
2. 멀티 스레드 환경에서 동기화 처리를 하지 않았을 때, 인스턴스가 2 개 생성되는 문제도 발생할 수 있다.
❗ 싱글톤 패턴의 주의할 점
싱글톤 패턴을 활용하여 인스턴스를 생성할 때 이 인스턴스는 상태를 가져서는 안된다.
애플리케이션 내의 하나만 존재하고, 전역에서 쉽게 접근이 가능하기 때문에 인스턴스의 상태를 변경시킬 수 있기 때문
'CS > 디자인 패턴' 카테고리의 다른 글
선언형과 함수형 프로그래밍 (0) | 2023.09.11 |
---|---|
MVVM 패턴 (0) | 2023.09.11 |
옵저버 패턴 (Observer Pattern) (0) | 2023.09.11 |
전략 패턴 (Strategy Pattern) (0) | 2023.09.11 |
팩토리 패턴 (Factory Pattern) (0) | 2023.09.11 |