2025. 2. 3. 19:36ㆍTech Insights/Design Pattern
싱글톤 패턴이란?
싱글톤 패턴(Singleton Pattern)은 특정 클래스의 인스턴스를 하나만 생성하고, 이를 전역적으로 공유하는 디자인 패턴입니다. 이를 통해 불필요한 객체 생성을 방지하고, 시스템 자원을 효율적으로 사용할 수 있습니다.
싱글톤 패턴의 특징
- 유일한 인스턴스 유지: 애플리케이션 전반에서 단 하나의 객체만 유지됩니다.
- 전역 접근 가능: 인스턴스를 여러 곳에서 공유하여 동일한 데이터를 사용할 수 있습니다.
- 메모리 절약: 동일한 객체를 여러 번 생성하는 비용을 줄일 수 있습니다.
싱글톤 패턴이 사용되는 경우
사용 사례설명
로깅 시스템 | 모든 모듈에서 동일한 로깅 인스턴스를 사용 |
환경 설정(Config) | 어플리케이션 설정 값을 싱글톤 객체에서 관리 |
이벤트 버스 | 이벤트 리스너를 관리하는 객체를 싱글톤으로 유지 |
싱글톤 패턴 구현 방법
1️⃣ 기본적인 싱글톤 패턴 (ES6)
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
}
return Singleton.instance;
}
sayHello() {
console.log("Hello from Singleton!");
}
}
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true
instance1.sayHello();
2️⃣ Node.js 모듈을 활용한 싱글톤 패턴
// singleton.js
class Singleton {
constructor() {
if (!Singleton.instance) {
this.data = "초기화된 데이터";
Singleton.instance = this;
}
return Singleton.instance;
}
}
module.exports = new Singleton();
// main.js
const singleton1 = require("./singleton");
const singleton2 = require("./singleton");
console.log(singleton1 === singleton2); // true
singleton1.data = "변경된 데이터";
console.log(singleton2.data);
싱글톤 패턴의 단점과 해결 방법
단점: 동기화 문제
싱글톤 객체가 여러 프로세스 또는 멀티 스레드 환경에서 동시에 접근될 경우, 데이터 동기화 이슈가 발생할 수 있습니다.
Node.js 는 싱글쓰레드/비동기 기반이기 때문에 문제가 발생할 가능성이 거의 없지만, 저자의 편의를 위해 예시는 Node.js 코드입니다.
해결 방법:
- Mutex(뮤텍스) 활용: 단일 프로세스에서 공유 자원의 접근을 제어합니다.
Mutex를 활용한 싱글톤 객체 보호
const { Mutex } = require('async-mutex');
const mutex = new Mutex();
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
this.counter = 0;
}
return Singleton.instance;
}
async safeIncrement() {
const release = await mutex.acquire();
try {
this.counter++;
console.log(`Counter: ${this.counter}`);
} finally {
release();
}
}
}
const singleton = new Singleton();
singleton.safeIncrement();
singleton.safeIncrement();
실제 서비스 사례
1️⃣ 싱글톤을 활용한 캐시 시스템
싱글톤 패턴은 대규모 웹 서비스에서 캐시 시스템을 구현할 때 유용하게 사용됩니다. 예를 들어, 인기 있는 API 요청 결과를 캐싱하여 성능을 최적화할 수 있습니다.
class CacheManager {
constructor() {
if (!CacheManager.instance) {
this.cache = new Map();
CacheManager.instance = this;
}
return CacheManager.instance;
}
set(key, value) {
this.cache.set(key, value);
}
get(key) {
return this.cache.get(key);
}
}
const cache1 = new CacheManager();
cache1.set('user_1', { name: 'Henry', age: 30 });
const cache2 = new CacheManager();
console.log(cache2.get('user_1')); // { name: 'Henry', age: 30 }
이처럼 싱글톤 패턴을 사용하면, 여러 부분에서 동일한 캐시 데이터를 활용할 수 있어 API 요청 부담을 줄이고 성능을 향상시킬 수 있습니다.
2️⃣ 싱글톤을 활용한 로깅 시스템
로그 기록은 대부분의 애플리케이션에서 중요한 역할을 합니다. 싱글톤 패턴을 사용하면 모든 요청에서 동일한 로깅 인스턴스를 사용하여 일관된 로그를 유지할 수 있습니다.
class Logger {
constructor() {
if (!Logger.instance) {
Logger.instance = this;
}
return Logger.instance;
}
log(message) {
console.log(`[LOG]: ${message}`);
}
}
const logger1 = new Logger();
const logger2 = new Logger();
logger1.log("첫 번째 로그");
logger2.log("두 번째 로그");
console.log(logger1 === logger2); // true
이처럼 싱글톤 패턴을 활용하면, 여러 모듈에서 동일한 로깅 인스턴스를 공유하여 로그의 일관성을 유지하고, 중복된 인스턴스 생성 비용을 줄일 수 있습니다.
3️⃣ 싱글톤을 활용한 환경 설정 관리
대규모 애플리케이션에서는 환경 설정을 한 곳에서 중앙 집중식으로 관리하는 것이 중요합니다. 싱글톤 패턴을 활용하면 설정 값을 한 번만 로드하고, 애플리케이션 전반에서 동일한 값을 공유할 수 있습니다.
class ConfigManager {
constructor() {
if (!ConfigManager.instance) {
this.config = {
apiBaseUrl: "https://api.example.com",
maxConnections: 10,
};
ConfigManager.instance = this;
}
return ConfigManager.instance;
}
get(key) {
return this.config[key];
}
set(key, value) {
this.config[key] = value;
}
}
const config1 = new ConfigManager();
const config2 = new ConfigManager();
console.log(config1.get("apiBaseUrl")); // "https://api.example.com"
config1.set("apiBaseUrl", "https://new-api.example.com");
console.log(config2.get("apiBaseUrl")); // "https://new-api.example.com"
console.log(config1 === config2); // true
이처럼 싱글톤 패턴을 활용하면, 환경 설정 값을 한 곳에서 관리하고 여러 모듈에서 쉽게 접근할 수 있으며, 설정 값이 변경되더라도 모든 인스턴스에 즉시 반영됩니다.
결론: 싱글톤 패턴을 언제 사용해야 할까?
- 상태를 유지해야 하는 공통 서비스 (ex. 로깅, 설정)
- 전역적으로 동일한 인스턴스를 공유해야 할 때 (ex. 이벤트 버스)
- 멀티 스레드 또는 프로세스 환경에서 주의가 필요함
하지만 무조건 싱글톤을 적용하면 오히려 문제를 일으킬 수 있으므로, 필요할 때만 적절하게 활용해야 합니다.
'Tech Insights > Design Pattern' 카테고리의 다른 글
빌더 패턴이란? Node.js와 함께 배우는 구현과 활용법 (0) | 2025.02.13 |
---|---|
팩토리 메서드 패턴이란? Node.js와 함께 배우는 구현과 활용법 (0) | 2025.02.12 |