JavaScript 디자인 패턴 — 그리고 실제로 사용해야 할 때
I’m happy to translate the article for you, but I’ll need the full text you’d like translated. Could you please paste the content (excluding the source line you already provided) here? Once I have the text, I’ll translate it into Korean while preserving all formatting, markdown, and technical terms.
Source:
JavaScript 디자인 패턴 — 프론트‑엔드 개발에서 정말 중요한 것
JavaScript 애플리케이션은 빠르게 성장합니다 — 기능이 늘고, 모듈이 늘고, 복잡도가 증가합니다. 구조가 없으면 시니어 개발자조차도 기술 부채에 빠지게 됩니다.
디자인 패턴이 도와주는 점
- ✅ 코드 정리
- ✅ 중복 방지
- ✅ 유지보수성 향상
- ✅ 기능을 안전하게 확장
- ✅ 예측 가능한 아키텍처 구축
모든 고전적인 디자인 패턴이 JavaScript에 적합한 것은 아닙니다. 아래는 실제로 JavaScript와 프론트‑엔드 프로젝트에서 유용하게 쓰이는 패턴들입니다.
1. Singleton Pattern
정의
객체 인스턴스가 하나만 존재하도록 보장하는 패턴.
예시
class AuthService {
constructor() {
if (AuthService.instance) return AuthService.instance;
this.user = null;
AuthService.instance = this;
}
}
사용 시점
- 인증 관리자
- 테마 관리자
- 앱 설정
- 전역 캐시 레이어
실제 적용 사례
React/Angular 앱에서 인증 핸들러를 여러 개 만들지 않아야 합니다. 싱글톤은 사용자 세션에 대한 단일 진실 소스를 보장합니다.
2. Module Pattern
정의
프라이빗 로직을 캡슐화하고 필요한 부분만 외부에 노출하는 패턴.
예시
const Cart = (() => {
let items = [];
function add(item) { items.push(item); }
function get() { return items; }
return { add, get };
})();
사용 시점
- 유틸리티 헬퍼
- 데이터 서비스
- 로컬스토리지 래퍼
- 분석 모듈
실제 적용 사례
storageService가 내부 키나 프리픽스를 외부에 노출하면 안 됩니다. 모듈 패턴은 이러한 세부 사항을 비공개로 유지하면서 깔끔한 공개 API를 제공합니다.
3. Observer Pattern
정의
하나의 객체가 변화가 있을 때 여러 리스너에게 알릴 수 있게 하는 패턴.
예시
class Observable {
constructor() { this.subscribers = []; }
subscribe(fn) { this.subscribers.push(fn); }
notify(value) { this.subscribers.forEach(fn => fn(value)); }
}
사용 시점
- 이벤트 시스템
- UI 업데이트
- 실시간 데이터 스트림
- Pub‑sub 기반 앱
실제 적용 사례
- 바닐라 JS에서 UI 상태 업데이트
- 알림 센터
- WebSocket 실시간 업데이트
- React, Vue, Node.js에서 커스텀 이벤트 emitter
4. Factory Pattern
정의
객체 생성 로직을 감추고 객체를 만들어 반환하는 패턴.
예시
function createUser(type) {
if (type === "admin") return { role: "admin", canDelete: true };
return { role: "user", canDelete: false };
}
사용 시점
- 조건에 따라 객체를 만들 때
- 여러 API 버전 지원
- 데이터 어댑터
실제 적용 사례
결제 연동(Stripe, PayPal, Razorpay)에서는 서로 다른 응답 형태를 반환합니다. 팩토리를 사용하면 이를 공통 인터페이스로 정규화해 애플리케이션 전반에서 일관되게 사용할 수 있습니다.
5. Strategy Pattern
정의
교체 가능한 알고리즘을 정의하고 실행 시 동적으로 선택하도록 하는 패턴.
예시
const feeStrategies = {
credit: amt => amt * 0.02,
upi: amt => amt * 0,
debit: amt => amt * 0.01,
};
function calculateFee(method, amount) {
return feeStrategies[method](amount);
}
사용 시점
- 동적인 비즈니스 로직
- 긴
if‑else체인 대체 - 가격·할인 계산
실제 적용 사례
- 결제 수수료 계산
- 리스트 정렬 함수
- 기능 토글에 따른 동작 변화
6. Decorator Pattern
정의
함수나 객체를 감싸서 원본 코드를 수정하지 않고 행동을 확장하는 패턴.
예시
function withLog(fn) {
return (...args) => {
console.log("Running", fn.name);
return fn(...args);
};
}
사용 시점
- 로깅
- 캐싱
- Throttling / Debouncing
- 권한 검사 래퍼
실제 적용 사례
- React 고차 컴포넌트(
withAuth) - Axios 인터셉터
- 성능 측정 래퍼
7. Proxy Pattern
정의
객체와의 상호작용을 가로채는 패턴.
예시
const user = { name: "Ani" };
const proxy = new Pr
```js
oxy(user, {
get(target, prop) {
console.log("Access:", prop);
return target[prop];
}
});
사용 시점
- 검증
- 접근 제어
- 반응성
- 메모이제이션
실제 적용 사례
Vue 3의 전체 반응성 시스템은 Proxy를 기반으로 구축됩니다.
8. Command Pattern
정의
동작을 객체로 캡슐화합니다 (실행 + 취소).
예시
class Command {
constructor(execute, undo) {
this.execute = execute;
this.undo = undo;
}
}
사용 시점
- 실행 취소/다시 실행 기능
- 히스토리 추적
- 매크로 동작
실제 적용 사례
- Figma의 실행 취소 스택
- VS Code 명령 팔레트
- 브라우저와 같은 탐색 히스토리
9. Adapter Pattern
정의
호환되지 않는 인터페이스를 사용 가능한 형태로 변환합니다.
예시
function axiosToFetch(response) {
return {
status: response.status,
data: response.data,
};
}
사용 시점
- 코드베이스 마이그레이션
- 서드파티 API 통합
- 일관되지 않은 데이터 정규화
실제 적용 사례
axios 응답을 통합된 형식으로 래핑하여 API를 표준화합니다.