-
JavaScript 디자인 패턴: 실제 예시와 함께 배우기Javascript 2023. 11. 18. 21:07
JavaScript 개발에 있어 디자인 패턴은 코드를 보다 효율적이고 유지보수하기 쉽게 만들어 줍니다. 일상적인 개발 과제에 적용할 수 있는 몇 가지 중요한 디자인 패턴과 그 예시를 살펴보겠습니다.
1. 싱글톤 (Singleton) 패턴
클래스의 인스턴스가 하나만 생성되도록 보장합니다.
class Auth { constructor() { if (!Auth.instance) { Auth.instance = this; } return Auth.instance; } login(username, password) { // 로그인 로직 } } const auth = new Auth(); Object.freeze(auth); export default auth;
로그인 시스템에서 하나의 인스턴스만 유지되어야 하는 사용자 인증 정보 관리.
2. 팩토리 (Factory) 패턴
객체 생성을 위한 인터페이스를 제공하고, 서브클래스가 생성할 객체의 클래스를 결정하게 합니다.
class NotificationFactory { createNotification(type) { if (type === "email") return new EmailNotification(); if (type === "sms") return new SMSNotification(); } } class EmailNotification { send() { // 이메일 전송 로직 } } class SMSNotification { send() { // SMS 전송 로직 } } const factory = new NotificationFactory(); const notification = factory.createNotification("email"); notification.send();
다양한 유형의 알림 메시지 생성.
3. 옵저버 (Observer) 패턴
객체의 상태 변화를 관찰하고, 상태 변화 시 자동으로 다른 객체들에게 알림을 줍니다.
class User { constructor() { this.observers = []; } subscribe(observer) { this.observers.push(observer); } notify() { this.observers.forEach(observer => { observer.update(this); }); } updateStatus(status) { this.status = status; this.notify(); } } class Logger { update(user) { console.log(`사용자 상태 변경: ${user.status}`); } } const user = new User(); const logger = new Logger(); user.subscribe(logger); user.updateStatus('온라인');
사용자의 상태 변화를 추적하여 관련 업데이트를 처리하는 시스템.
4. 데코레이터 (Decorator) 패턴
객체에 동적으로 새로운 책임을 추가합니다. 상속을 사용하지 않고 객체의 기능을 확장할 수 있습니다.
class DataSource { writeData(data) { // 데이터 쓰기 로직 } } class DataSourceDecorator extends DataSource { constructor(dataSource) { super(); this.wrappee = dataSource; } writeData(data) { // 추가 기능 또는 로직 this.wrappee.writeData(data); } } class EncryptionDecorator extends DataSourceDecorator { writeData(data) { // 데이터 암호화 super.writeData(data); } } const source = new DataSource(); const encryptedSource = new EncryptionDecorator(source); encryptedSource.writeData("secret data");
로깅, 유효성 검사, 상태 관리 등의 추가 기능을 동적으로 객체에 부여.
5. 컴포지트 (Composite) 패턴
객체들의 그룹을 트리 구조로 구성하여 개별 객체와 복합 객체를 클라이언트가 동일하게 다룰 수 있도록 합니다.
class Component { constructor(name) { this.name = name; } add(component) {} remove(component) {} display(depth) {} } class Leaf extends Component { display(depth) { console.log('-'.repeat(depth) + this.name); } } class Composite extends Component { constructor(name) { super(name); this.children = []; } add(component) { this.children.push(component); } remove(component) { this.children = this.children.filter(child => child !== component); } display(depth) { console.log('-'.repeat(depth) + this.name); this.children.forEach(child => child.display(depth + 2)); } } const root = new Composite('root'); const leaf1 = new Leaf('Leaf 1'); const leaf2 = new Leaf('Leaf 2'); const comp = new Composite('Composite'); comp.add(leaf1); comp.add(leaf2); root.add(comp); root.display(1);
파일 시스템의 디렉토리와 파일을 표현하는 경우.
6. 전략 (Strategy) 패턴
알고리즘을 클래스의 행동으로 정의하고 이를 동적으로 바꿔 사용할 수 있게 합니다.
class SortStrategy { sort(dataset) { // 정렬 로직 } } class BubbleSortStrategy extends SortStrategy { sort(dataset) { console.log('Bubble sort'); // 버블 정렬 알고리즘 } } class QuickSortStrategy extends SortStrategy { sort(dataset) { console.log('Quick sort'); // 퀵 정렬 알고리즘 } } class Sorter { constructor(strategy) { this.strategy = strategy; } sort(dataset) { return this.strategy.sort(dataset); } } const dataset = [1, 5, 4, 3, 2, 8]; const sorter = new Sorter(new BubbleSortStrategy()); sorter.sort(dataset);
다양한 정렬 또는 검색 알고리즘 중 하나를 선택하여 사용.
디자인 패턴은 복잡한 소프트웨어 설계 문제를 해결하는 데 도움을 줍니다. 위에서 살펴본 패턴 외에도 많은 디자인 패턴들이 있으며, 각각의 패턴은 특정 상황에 최적화된 솔루션을 제공합니다. 코드의 재사용성, 유지보수성 및 확장성을 높이려면 이러한 패턴들을 적절히 활용하는 것이 중요합니다.
JavaScript 개발의 심화 단계로 나아가려면 이러한 패턴들을 이해하고 실제 프로젝트에 적용하는 능력을 기르는 것이 필수적입니다. 따라서 이 글에서 제시된 패턴들을 참고하여 자신만의 프로젝트에 적용해 보시기 바랍니다.
'Javascript' 카테고리의 다른 글
JavaScript의 try, catch, finally (0) 2023.11.20 JavaScript에서 반드시 마스터해야 할 19가지 필수 팁과 트릭 (1) 2023.11.19 pnpm을 써야하는 이유 (npm, yarn 잘가) (1) 2023.11.14 JavaScript 코드 품질 향상을 위한 8가지 고급 함수 (1) 2023.11.13