[JavaScript] 자바스크립트 모듈 패턴
모듈 패턴이란?
모듈이란 전제 어플리케이션의 일부를 독립된 코드로 분리하여 만들어 놓은 것이다.
모듈화를 했을 때 장점
- 자주 사용되는 코드를 별도의 파일로 만들어서 필요할 때마다 활용할 수 있다.
- 코드를 개선하면 이를 사용하고 있는 모든 애플리케이션의 동작이 개선된다.
- 코드 수정 시에 필요한 로직을 빠르게 찾을 수 있다.
- 필요한 로직만을 로드해서 메모리의 낭비를 줄일 수 있다.
- 한번 다운로드된 모듈은 웹브라우저에 의해서 저장되기 때문에 동일한 로직을 로드할 때 시간과 네트워크 트래픽을 절약할 수 있다.(브라우저에서만 해당)
객체 리터럴을 사용한 모듈 패턴
자바스크립트에서 모듈을 구현하는 가장 쉬운 방법은 객체 리터럴을 사용하는 방법이다.
var module = {
key: 'data',
publicMethod: function() {
return this.key;
}
}
console.log(module.key); // data
console.log(module.publicMethod()); // data
객체 리터럴은 모듈 패턴이기도 하며, 하나의 객체라는 점에서 싱글톤 패턴이라고도 할 수 있다. 동일한 코드를 어떠한 관점에서 보느냐에 따라 다양한 패턴이 될 수 있다. 객체 리터럴은 간단하지만 모든 속성이 공개되어있다는 단점이 있다. 독립된 모듈은 자체적으로 필요한 내부 변수 및 내부 함수를 모두 갖고 있어야 하므로 클로저를 이용해야 한다.
아래는 클로저를 활용한 모듈패턴이다.
클로저를 활용한 모듈 패턴
var module = (function() {
/**
* -----------------------
* 모듈 패턴을 구현할 클로저 코드
* -----------------------
*/
// 은닉될 멤버 정의
var privateKey = 0;
function privateMethod() {
return privateKey++;
}
// 공개될 멤버(특권 메서드) 정의
return {
publicKey: privateKey,
publicMethod: function() {
return privateMethod();
}
}
})();
console.log(module.publicMethod()); // 0
console.log(module.publicMethod()); // 1
모듈 패턴의 반환값은 함수가 아닌 객체이다. 위의 코드를 순서대로 보면 익명함수가 자동으로 실행되고 반환된 객체를 module 변수에 할당한다. 따라서 module.publicMethod()처럼 메서드를 호출할 수 있다. 자동 호출되는점을 제외하고 클로저와 유사하다.
클로저 경우
function func() {
var private = 0;
return function() {
private++;
return private;
}
}
var val = func();
console.log(val()); // 1
console.log(val()); // 2
그리고 인스턴스를 여러개 만들어 낼 수 있는 구조라는 점에서 싱글톤 패턴과 차이가 있다.
싱글톤 패턴 경우
var singleton = (function() {
var instance;
var private = 0;
function init() {
return {
publicKey: private,
publicMethod: function() {
return publicKey;
}
}
}
return function() {
// 싱글톤 패턴은 아래 조건문에서 처음 인스턴스가 선언되면 다시 인스턴스를 만들지 않고 기존의 인스턴스를 리턴한다.
if (!instance) {
instance = init();
}
return instance;
}
})()
var singleton1 = singleton();
var singleton2 = singleton();
console.log(singleton1 === singleton2); // true
하나의 인스턴스를 선언하지 않고 여러개의 인스턴스를 생성하려면 익명함수를 사용하지 않고 생성자 함수 방식으로 만들면 된다.
var Module = function() {
var privateKey = 0;
function privateMethod() {
return privateKey++;
}
return {
publicKey: privateKey,
publicMethod: function() {
return privateMethod();
}
}
}
var obj1 = Module();
console.log(obj1.publicMethod()); // 1
console.log(obj1.publicMethod()); // 2
var obj2 = Module();
console.log(obj2.publicMethod()); // 1
console.log(obj2.publicMethod()); // 2
위처럼 Module 함수를 정의하여 함수를 호출하면 여러개의 인스턴스를 생성할 수 있다. 클로저 인스턴스와 유사하지만, 한가지 차이점은 내부의 익명함수에서 반환값이 함수가 아니라 객체를 반환한다는 점이다.
모듈 패턴과 네임 스페이스 패턴을 함께 사용하면 더욱 깔끔한 코드가 완성된다.
var app = app || {};
app.module = (function() {
var privateKey = 0;
function privateMethod() {
return privateKey++;
}
return {
publicKey: privateKey,
publicMethod: function() {
return privateMethod();
}
}
})();
console.log(app.module.publicMethod()); // 0
console.log(app.module.publicMethod()); // 1
References
module pattern (모듈패턴) #1
[JS_Design Pattern] 2. 모듈 패턴 (Module Pattern)