본문으로 바로가기

Module Pattern

모듈 패턴을 알아보기 전에 네임스페이스란 용어부터 짚고 넘어가 보겠습니다.

네임스페이스란 수많은 함수, 객체, 변수들로 이루어진 코드가 전역 유효범위를 어지럽히지 않고, 애플리케이션이나 라이브러리를 위한 하나의 전역 객체를 만들고 모든 기능을 이 객체에 추가하는 것을 말합니다.

예를 들어 jQuery와 같은 라이브러리에서 jQuery가 네임스페이스를 가지며 jQuery 이름 내에 모든 기능을 추가하는 것을 말합니다.

다시 말해서, 코드에 네임스페이스를 지정해주며, 코드 내의 이름 충돌뿐만 아니라 이 코드와 같은 페이지에 존재하는 또 다른 자바스크립트 라이브러리나 위젯등 서드파티 코드와의 이름 충돌도 미연에 방지해 주는 것입니다.

우리는 이러한 네이스페이스 패턴을 작은 기능들 만을 모아 놓은 패턴으로 사용할 수가 있는데 모듈 패턴으로 이를 흉내낼 수가 있습니다.


모듈(module) 이라는 것은 전체 애플리케이션의 일부를 독립된 코드로 분리해서 만들어 놓은 것을 말합니다. 관련된 유용한 기능을 모아둔 모듈이라 할 수 있으며 크게는 jQuery 와 같은 라이브러리도 모듈이라 할 수 있습니다. 그리고 jQuery API 카테고리 분류를 보면 css, core, ajax 등등으로 API 를 제공하고 있는데 이 또한 카테고리 섹션을 모듈별로 관리를 하고 최종 빌드버전을 배포하고 있습니다. 물론 jQuery를 모듈별로 사용자가 다운받아 사용할 수도 있습니다. 

자바스크립트에서는 모듈을 구현하는 가장 쉬운 방법은 객체 리터럴을 사용하는 방법입니다.


javascript
var module = {
    key : 'value',
    pulicMethod : function () {
    }
}


전의 포스팅에서 객체 리터럴을 싱글톤이라고 언급한 바 있습니다. 객체 리터럴 표현이 싱글톤 패턴이라고 해서 다른 패턴이 되지 말라는 법은 없습니다.

즉, 동일한 코드를 어떤 관점에서 보느냐에 따라 다양한 패턴이 될 수 있습니다. 객체 리터럴이 하나의 객체라는 점에서 싱글톤 패턴이라고 할 수도 있고 독립된 모듈이라는 점에서 모듈 패턴의 하나라고도 할 수 있습니다.

리고 독립된 모듈은 자체적으로 필요한 내부 변수 및 내부 함수를 모두 갖고 있어야 합니다. 이와 같이 내부 변수와 내부 함수를 가지고 있는 객체를 생성한다고 했을 때 클로저를 이용해야 합니다.



다음은 클로저를 이용해 모듈 패턴을 구현한 코드입니다.

javascript
var module = (function () {
    /**
     * --------------------------------
     * 모듈 패턴을 구현한 클로저 코드
     * --------------------------------
     */
    // 은닉될 멤버 정의
    var privateKey = 0;
    function privateMethod() {
        return ++privateKey;
    }
    // 공개될 멤버 (특권 메소드) 정의
    return {
        publickey : privateKey,
        publicMethod : function () {
            return privateMethod();
        }
    }
})();

console.log(module.publicMethod()); // 1
console.log(module.publicMethod()); // 2 (클로저로 인한 결과)


모듈 패턴은 반환값이 함수가 아니라 객체이며, 자동 호출된다는 점만 제외하고 클로저와 유사합니다. 그리고 인스턴스를 여러 개 만들어 낼 수 있는 구조라는 점에서 싱글톤 패턴과 차이가 있습니다. 

위의 코드를 실행하면 익명함수가 자동으로 호출되어 익명함수가 반환하는 객체가 Module 변수에 할당되게 됩니다. /p>

따라서 위와 같이 module.publicMethod() 호출할 수 있습니다. 위의 코드는 하나의 인스턴스 객체만을 생성하고 있어서 싱글톤과 유사합니다.

하지만 아래와 같이 자동으로 호출(self-invoking) 되는  구조를 없애면 여러 개의 인스턴스를 생성하여 사용할 수 있습니다.<



자동 호출 구조를 없앤 코드입니다.

javascript
var Module = function () {
    /**
     * --------------------------------
     * 모듈 패턴을 구현한 클로저 코드
     * --------------------------------
     */
    // 은닉될 멤버 정의
    var privateKey = 0;

    function privateMethod() {
        return ++privateKey;
    }
    // 공개될 멤버 (특권 메소드) 정의
    return {
        publickey : privateKey,
        publicMethod : function () {
            return privateMethod();
        }
    }
};

// 두 개의 인스턴스 생성
var obj1 = Module();
obj1.publicMethod(); // 1 출력
obj1.publicMethod(); // 2 출력

var obj2 = Module();
obj2.publicMethod(); // 1 출력
obj2.publicMethod(); // 2 출력

위와 같이 Module 함수를 정의(즉시실행 X) 하여 함수를 호출하면 여러 개의 인스턴스인 객체를 생성하여 사용할 수 있습니다.

클로저 인스턴스와 유사하지만 한가지 차이점은 내부의 익명함수에서 반환값이 함수가 아니라 객체를 반환한다는 점입니다.



모듈 패턴의 장,단점

단점

- 전체적으로 코드량이 약간 더 많아지고 따라서 다운로드해야 하는 파일크기도 늘어난다.

- 전역 인스턴스가 단 하나뿐이기 때문에 코드의 어느 한 부분이 수정되어도 전역 인스턴스를  수정하게 된다. 

즉, 나머지 기능들도 갱신된 상태를 물려받게 된다.


장점

- 점점 더 늘어만 가는 코드를 정리할때 널리 사용되며 자바스크립트 코딩패턴에서 널리 권장되는 방법이기도 하다.




모듈 기본패턴 정의하기

javascript
// 1. 네임스페이스를 설정하고 모듈을 정의
var MyApp = {} // 전역 객체
MyApp.modules = {}

/*
 2. 공개범위(특권메소드 등..)와 비공개 유효범위를 만든다
 ==> 즉시 실행함수로 모듈이 될 객체를 반환하고 
 모듈 사용자에게 제공할 공개 인터페이스가 담기게 된다.
 */
MyApp.modules.libs = (function() {

    // 비공개 프로퍼티
    // var 선언 및 비공개 메소드등의 유효범위 (private 멤버)

    // 공개 API  (public, previlege 멤버)
    return {

    };
}());




Jaehee's WebClub