이미지 로딩 중...
CodeDeck AI
2025. 11. 8. · 3 Views
JavaScript 디자인 패턴 완벽 가이드
실무에서 자주 사용되는 JavaScript 디자인 패턴을 실제 코드와 함께 학습합니다. 싱글톤, 팩토리, 옵저버 등 핵심 패턴을 마스터하여 유지보수가 쉬운 코드를 작성하세요.
들어가며
이 글에서는 JavaScript 디자인 패턴 완벽 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- Singleton_패턴
- Factory_패턴
- Observer_패턴
- Module_패턴
- Strategy_패턴
- Decorator_패턴
- Proxy_패턴
- Command_패턴
- Chain_of_Responsibility_패턴
- Builder_패턴
1. Singleton_패턴
개요
클래스의 인스턴스가 오직 하나만 존재하도록 보장하는 패턴입니다. 데이터베이스 연결, 로거 등에 활용됩니다.
코드 예제
class Database {
static instance = null;
static getInstance() {
if (!this.instance) {
this.instance = new Database();
}
return this.instance;
}
}
const db1 = Database.getInstance();
const db2 = Database.getInstance();
console.log(db1 === db2); // true
설명
getInstance 메서드를 통해 항상 동일한 인스턴스를 반환하므로, 여러 번 호출해도 하나의 객체만 생성됩니다.
2. Factory_패턴
개요
객체 생성 로직을 캡슐화하여 유연한 객체 생성을 가능하게 하는 패턴입니다. 조건에 따라 다른 타입의 객체를 생성할 때 유용합니다.
코드 예제
class UserFactory {
static createUser(type) {
if (type === 'admin') {
return { role: 'admin', permissions: ['read', 'write', 'delete'] };
}
return { role: 'user', permissions: ['read'] };
}
}
const admin = UserFactory.createUser('admin');
const user = UserFactory.createUser('user');
설명
타입에 따라 다른 권한을 가진 사용자 객체를 생성합니다. 객체 생성 로직이 한 곳에 집중되어 관리가 쉽습니다.
3. Observer_패턴
개요
객체의 상태 변화를 관찰하고, 변화가 있을 때 구독자들에게 자동으로 알림을 보내는 패턴입니다. 이벤트 핸들링에 널리 사용됩니다.
코드 예제
class Subject {
constructor() { this.observers = []; }
subscribe(observer) { this.observers.push(observer); }
notify(data) { this.observers.forEach(obs => obs(data)); }
}
const subject = new Subject();
subject.subscribe(data => console.log(`받은 데이터: ${data}`));
subject.notify('업데이트!'); // 받은 데이터: 업데이트!
설명
subscribe로 관찰자를 등록하고, notify로 모든 관찰자에게 데이터를 전달합니다. React의 상태 관리와 유사한 개념입니다.
4. Module_패턴
개요
코드를 캡슐화하여 private 변수와 public 메서드를 구분하는 패턴입니다. 전역 스코프 오염을 방지합니다.
코드 예제
const Calculator = (function() {
let result = 0; // private
return {
add: (x) => { result += x; return result; },
subtract: (x) => { result -= x; return result; },
getResult: () => result
};
})();
Calculator.add(10); // 10
Calculator.subtract(3); // 7
설명
즉시 실행 함수로 private 변수 result를 보호하고, 반환된 객체의 메서드만 외부에서 접근 가능합니다.
5. Strategy_패턴
개요
알고리즘을 캡슐화하여 런타임에 동적으로 교체할 수 있게 하는 패턴입니다. 다양한 처리 방식을 유연하게 전환할 수 있습니다.
코드 예제
const strategies = {
card: (amount) => amount * 0.02,
cash: (amount) => amount * 0.01,
crypto: (amount) => amount * 0.05
};
function applyDiscount(amount, method) {
return amount - strategies[method](amount);
}
console.log(applyDiscount(1000, 'card')); // 980
설명
결제 방법에 따라 다른 할인 전략을 적용합니다. 새로운 결제 방법 추가 시 strategies 객체에만 추가하면 됩니다.
6. Decorator_패턴
개요
기존 객체에 새로운 기능을 동적으로 추가하는 패턴입니다. 상속 없이 객체의 기능을 확장할 수 있습니다.
코드 예제
function withTimestamp(fn) {
return function(...args) {
console.log(`[${new Date().toISOString()}]`);
return fn(...args);
};
}
const greet = (name) => console.log(`안녕, ${name}!`);
const greetWithTime = withTimestamp(greet);
greetWithTime('철수'); // [2025-01-15T...] \n 안녕, 철수!
설명
원본 함수를 수정하지 않고 타임스탬프 기능을 추가합니다. 로깅, 인증 등 부가 기능 추가에 유용합니다.
7. Proxy_패턴
개요
객체에 대한 접근을 제어하고, 접근 전후에 추가 작업을 수행하는 패턴입니다. ES6 Proxy를 활용합니다.
코드 예제
const user = { name: '김철수', age: 30 };
const handler = {
get: (target, prop) => {
console.log(`${prop} 속성 접근`);
return target[prop];
}
};
const proxy = new Proxy(user, handler);
console.log(proxy.name); // "name 속성 접근" \n "김철수"
설명
Proxy를 통해 객체 속성 접근을 가로채고, 접근 로그를 남깁니다. 유효성 검사나 캐싱에도 활용 가능합니다.
8. Command_패턴
개요
요청을 객체로 캡슐화하여 실행 취소, 재실행 등을 구현할 수 있는 패턴입니다. 작업 히스토리 관리에 유용합니다.
코드 예제
class Command {
constructor(execute, undo) {
this.execute = execute;
this.undo = undo;
}
}
const history = [];
const cmd = new Command(
() => console.log('실행'),
() => console.log('취소')
);
history.push(cmd);
cmd.execute(); // 실행
설명
실행과 취소 로직을 Command 객체로 캡슐화합니다. history 배열에 저장하여 undo/redo 기능을 쉽게 구현할 수 있습니다.
9. Chain_of_Responsibility_패턴
개요
요청을 처리할 수 있는 객체들을 체인으로 연결하여, 순차적으로 처리를 시도하는 패턴입니다. 미들웨어 구현에 활용됩니다.
코드 예제
function createMiddleware(fn) {
return (req, next) => {
fn(req);
if (next) next(req);
};
}
const auth = createMiddleware(r => r.auth = true);
const log = createMiddleware(r => console.log(r));
auth({ url: '/api' }, (req) => log(req, null));
설명
각 미들웨어가 요청을 처리한 후 다음 미들웨어로 전달합니다. Express.js의 미들웨어 체인과 동일한 개념입니다.
10. Builder_패턴
개요
복잡한 객체의 생성 과정을 단계별로 분리하여, 가독성 높은 객체 생성을 가능하게 하는 패턴입니다.
코드 예제
class QueryBuilder {
constructor() { this.query = {}; }
where(field, value) {
this.query.where = { field, value };
return this;
}
orderBy(field) {
this.query.order = field;
return this;
}
}
const query = new QueryBuilder().where('age', 30).orderBy('name');
설명
메서드 체이닝을 통해 직관적으로 쿼리를 구성합니다. 각 메서드가 this를 반환하여 연속 호출이 가능합니다.
마치며
이번 글에서는 JavaScript 디자인 패턴 완벽 가이드에 대해 알아보았습니다. 총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#JavaScript #DesignPatterns #Singleton #Factory #Observer