자바스크립트에서 싱글톤 패턴
싱글톤패턴은 프로세스 내부에서 클래스가 단 하나의 인스턴스만 생성될 수 있도록 구현된 것을 의미한다.
기본적으로 static 영역에 인스턴스를 생성하고, 생성자가 실행되었을 때 기존에 생성된 인스턴스가 있으면 다시 인스턴스를 생성하지 않고 기존의 것을 반환하는 방식으로 구현된다.
자바스크립트에서는 클래스 문법으로 이를 구현할 수도 있지만, 함수형 프로그래밍으로 클로저 문법을 이용하여 이를 구현할 수도 있다.
Class 문법으로 구현
class Key {
static #_instance;
constructor() {
if(!Key.#_instance) {
Key.#_instance = this
}
return Key.#_instance;
}
static getInstance() {
return Key.#_instance;
}
}
const KeyOne = new Key();
const KeyTwo = new Key();
console.log(KeyOne === KeyTwo); // true
const KeyThree = Key.getInstance();
console.log(KeyOne === KeyThree); // true
클래스 내부에서 변수 하나에 this로 자기자신을 할당한다.
변수를 private(#)하게 선언하여 외부에서 접근할 수 없게 하고 static으로 선언함으로써 생성자 내부에서는 사용할 수 있게 한다.
이 클래스를 여러 번 생성자로 생성하여도 같은 메모리를 가리키므로 비교시 true가 반환된다.
생성자가 아닌 클래스 내부 함수로 기존에 생성된 인스턴스를 가져올 수도 있다. (getInstance 메서드)
타입스크립트로 작성하면, 다음과 같이 작성할 수 있다.
class Key {
private static instance: Key;
private constructor() {
Key.instance = this;
}
public static getInstance() {
if(!Key.instance) {
Key.instance = new Key();
}
return Key.instance;
}
}
const KeyOne = Key.getInstance();
const KeyTwo = Key.getInstance();
console.log(KeyOne === KeyTwo); // true
다만, 위의 코드에서 생성자가 private로 선언되어 오직 getInstance에서만 호출되고 외부에서는 호출될 수 없다.
getInstance로 인스턴스를 가져올 수 있는 구조이다.
Function 문법으로 구현
function Key() {
if(!Key._instance) {
Key._instance = this;
}
Key.getInstance = function() {
return this._instance;
}
return Key._instance;
}
const one = Key();
const two = Key();
console.log(one === two); // true
const three = Key.getInstance();
console.log(one === three); // true
함수형으로 다음과 같이 생성할 수 있는데 위와 같은 방법으로는 내부에 변수 접근을 private하게는 할 수 없다.
참고로 getInstance를 화살표 함수로 구현하면, this의 범위가 달라져 의도한 결과가 나오지 않는다.
내부의 변수를 숨기기 위해서는 다음과 같이 즉시 실행 함수로 구현할 수 있다.
const Key = (function(){
let instance;
let test;
function init() {
return {
getTest: function() {
return test;
},
setTest: function(data) {
test = data;
}
}
}
return {
getInstance: function() {
if(!instance) {
instance = init();
}
return instance;
}
}
})();
const one = Key.getInstance();
const two = Key.getInstance();
console.log(one === two); // true
Closure 개념을 이용하여 즉시 실행된 함수로 싱글톤 패턴을 구현한다.
이때는 내부의 getInstance 메서드를 통해서 단 하나의 인스턴스를 사용할 수 있다.
🍭 다만, 자바스크립트에서 객체를 export하고 외부에서 import로 이 객체를 불러온다면, 이 객체를 복사하는 것이 아니라 객체의 참조값으로 데이터에 접근하므로 싱글톤 패턴은 노드 환경이라면 자연스럽게 사용하고 있다고 할 수 있다.