디자인패턴중 하나인 싱글톤패턴은 객체지향 프로그래밍에서도 자주 사용되는 패턴중 하나이다. 예전에 자바스크립트를 공부했었는데 리마인드하고자 다시 정리를 해봤다. 자바스크립트로는 싱글턴 패턴을 어떻게 구현할 수 있을까. 코드와 함꼐 살펴보자.
싱글톤 패턴?
특정 클래스의 인스턴스를 런타임동안 오직 하나만 유지하는 것을 의미한다. 자바스크립트는 클래스가 없고 _오직 객체_만 존재. 즉 새로 객체를 만들면 다른 객체와도 같지않아 이미 싱글톤이다.
var a = {
k: 1
};
var b = {
k: 1
};
a == b // false
a === b // false
값이 같아도 다른 객체 취급.객체 리터럴을 이용해 객체 생성할 때마다 싱글톤 만드는 것이다.
스태틱 프로퍼티에 인스턴스 저장
function Singleton() {
if (typeof Singleton.instance === "object") {
return Singleton.instance;
}
// 정상적으로 진행
this.a = 0;
..
// 인스턴스 캐시
Singleton.instance = this;
return this;
}
클래스 프로퍼티 instance를 이용한 방법이다. instance가 공개되어 있다는 것이 단점이다. 다른 시점에서 변경될 수 있음.
클로저에 인스턴스 저장
클로저를 이용해 단일 인스턴스를 보호하는 방법이다.
function Singleton() {
// 캐싱
var instance = this;
// 정상적으로 진행
this.a = 0;
..
// 생성자 재작성
Singleton = function() {
return instance;
}
}
첫 호출 시 캐싱을 하고, 클로저를 통해 생성자 재정의한다. 다음 호출 시 재작성된 생성자로 호출되는데 클로저로 물고있는 instance를 참조한다.
단점 : 재작성된 함수는 재정의 시점 이전에 원본 생성자에 추가된 프로퍼티를 잃어버린다는 점
Singleton
클래스의 프로토타입에 뭔가를 추가해도 연결되지 않는다.
Singleton.prototype.m = true;
var a = new Singleton();
Singleton.prototype.test = function() {
return "test";
}
var b = new Singleton();
a, b 는 미리 정의한 프로토타입 m을 가지고 있다. 한 번 호출 후 추가로 정의한 test 메서드는 반영되지 않는다.
한번 생성된 constructor가 재정의된 생성자가 아닌 원본 생성자를 가리키고 있기 때문
이를 해결하는 방법에는
- 생성자 메서드에서 prototype과 constructor를 재지정
- 즉시 실행함수로 감싸는 방법
두 가지가 있다.
1. 생성자 메서드에서 prototype과 constructor를 재지정
function Singleton() {
var instance;
Singleton = function Singleton() {
return instance;
}
// prototype 프로퍼티 변경
Singleton.prototype = this;
instance = new Singleton();
instance.constructor = Singleton;
...
return instance;
}
2. 즉시 실행함수로 감싸는 방법
비공개 instance를 가르키는 방식이다.
var Singleton;
(function() {
var instance;
Singleton = function Singleton() {
if (instance) {
return instance;
}
instance = this;
...
};
})();
참고
- 자바스크립트 디자인패턴 책
'Programming > Javascript' 카테고리의 다른 글
자바스크립트(Javascript) 디자인패턴 - 데코레이터 패턴(decorator pattern)( (0) | 2020.06.02 |
---|---|
자바스크립트(Javascript) - 반복자(Iterator) 패턴 (0) | 2020.05.29 |
자바스크립트(Javascript) 함수의 기본 패턴들 (콜백, 메모이제이션, 커리) (0) | 2020.05.29 |
자바스크립트(Javascript) 클래스, 생성자, 프로토타입에 대하여 (0) | 2020.05.29 |
자바스크립트(Javascript) 객체와 배열 (0) | 2020.01.08 |
댓글