본문으로 바로가기

싱글톤


싱글톤(singleton) 패턴은 전체 시스템에서 하나의 인스턴스만 존재하도록 보장하는 객체 생성패턴을 말합니다. 

따라서 객체 리터럴도 싱글톤 패턴이라고 할 수 있습니다.


javascript
var singletonObj = {
    a : '값',
    b : function () {
    }
}

그러나 객체 리터럴로는 비공개 상태 및 함수를 정의할 수는 없습니다. 규모가 큰 라이브러리에서는 흔히 외부에서 접근할 수 없는 비공개 멤버를 가지고 있습니다. 자바스크립트에서 비공개 멤버가 필요하다면 먼저 클로저(closure) 를 염두에 두어야 합니다.

즉, 비공개 멤버를 가진 싱글톤 객체를 생성하려면 클로저를 이용해야 합니다.




다음은 클로저를 이용한 싱글톤 패턴을 구현하는 예제입니다.

javascript
var Singleton = (function () {

    /**
     * --------------------------------
     * 싱글톤 패턴 구현 코드
     * --------------------------------
     */

    // 비공개 변수, 메서드 정의
    var instantiaed;

    function init() {

        // 싱글톤 객체 정의
        return {
            // 공개 메서드 정의
            publicMethod : function () {
                return 'hello Singleton Pattern!!!';
            },
            // 공개 프로퍼티 정의
            publicProp : 'single value'
        }

    }

    // 공개 메서드인 getInstance() 를 정의한 객체.
    // 렉시컬 특성으로 인해 비공개 변수, 메서드에 접근 가능(클로저)
    return {
        getInstance : function () {
            if (!instantiaed) {
                instantiaed = init();
            }
            return instantiaed;
        }
    }

})();

// 싱글톤 객체 생성하여 publicMethod 호출 가능해짐
var first = Singleton.getInstance();
first.publicMethod();
console.log(first.publicMethod()); // hello Singleton Pattern!!!

var second = Singleton.getInstance();
second.publicMethod();
console.log(second.publicMethod()); // hello Singleton Pattern!!!

console.log(first === second); // true

위의 예제 코드에서 먼저 비공개 함수인 init() 의 return 문에서 객체 리터럴로 정의되는 객체가 싱글톤 객체입니다.

이 객체는 프로그램 전체에서 하나만 존재하게 됩니다. 외부에 공개되는 익명함수의 return 문에서는 싱글톤 객체를 구하는 공개 메서드인 getInstance 가 포함된 객체를 반환합니다. getInstance 메서드에서는 내부 변수로 정의된 instantiaed 변수의 값을 확인해서 아직 싱글톤 객체가 생성되지 않았다고 판단하면 내부 함수인 init 를 호출하여 싱글톤 객체를 생성해서 반환하게 됩니다. 그런 다음 instantiaed 번수에 싱글톤 객체를 할당하게 됩니다.


이렇게 일반적으로 싱글톤 패턴에서는 이미 객체가 생성됐는지 여부를 알려주는 instantiaed 와 같은 내부 변수가 필요합니다.

그리고 싱글톤 패턴에서는 내부 변수에 접근할 수 있는 객체를 반환하는 클로저를 이용해야 합니다.


위 코드에서는 변수의 렉시컬한 특성으로 인해 내부의 getInstance 함수에서 비공개 변수인 instantiaed 에 접근할 수 있다는 것과 getInstane() 호출이 끝나더라도 instantiaed 값은 계속 유지되는 특성(클로저)을 이용해 publicMethod(), publicProp 이 포함된 객체를 유일하게 생성하게 됩니다.


그래서 singleton.getInstance 를 몇 번 호출하더라도 결과로 얻는 객체는 모두 동일한 싱글톤 객체를 가리키게 됩니다.



Jaehee's WebClub