[typescript] 타입스크립트로 작성하는 Node.js 디자인 패턴 예시

Node.js 어플리케이션을 개발할 때 디자인 패턴을 적용하는 것은 유지보수 가능한 코드를 작성하는 데 도움이 됩니다. 타입스크립트를 사용하여 Node.js 어플리케이션을 개발할 때 다양한 디자인 패턴을 적용하는 방법에 대해 알아보겠습니다.

목차

  1. 싱글톤 패턴
  2. 팩토리 메서드 패턴
  3. 옵저버 패턴

싱글톤 패턴

싱글톤 패턴은 어플리케이션 전반에서 하나의 인스턴스만 생성하고 이에 전역적인 접근을 허용하는 패턴입니다. 타입스크립트로 싱글톤 패턴을 구현할 때는 다음과 같이 클래스를 작성할 수 있습니다.

class Singleton {
  private static instance: Singleton;

  private constructor() {
    // 생성자를 private으로 선언하여 외부에서 인스턴스화를 막음
  }

  public static getInstance(): Singleton {
    if (!Singleton.instance) {
      Singleton.instance = new Singleton();
    }
    return Singleton.instance;
  }
}

const singletonInstance1 = Singleton.getInstance();
const singletonInstance2 = Singleton.getInstance();

console.log(singletonInstance1 === singletonInstance2); // 출력: true

위 예시에서 보듯이, getInstance 메서드를 통해 항상 동일한 인스턴스를 반환하는 싱글톤을 구현할 수 있습니다.

팩토리 메서드 패턴

팩토리 메서드 패턴은 객체를 생성하는 인터페이스를 정의하고, 객체의 인스턴스화를 서브 클래스로 미루는 패턴입니다. 타입스크립트로 팩토리 메서드 패턴을 구현할 때는 다음과 같이 인터페이스와 서브 클래스를 활용할 수 있습니다.

interface Product {
  operation(): string;
}

class ConcreteProduct1 implements Product {
  public operation(): string {
    return 'ConcreteProduct1';
  }
}

class ConcreteProduct2 implements Product {
  public operation(): string {
    return 'ConcreteProduct2';
  }
}

interface Creator {
  factoryMethod(): Product;
}

class ConcreteCreator1 implements Creator {
  public factoryMethod(): Product {
    return new ConcreteProduct1();
  }
}

class ConcreteCreator2 implements Creator {
  public factoryMethod(): Product {
    return new ConcreteProduct2();
  }
}

const creator1 = new ConcreteCreator1();
const product1 = creator1.factoryMethod();
console.log(product1.operation()); // 출력: ConcreteProduct1

const creator2 = new ConcreteCreator2();
const product2 = creator2.factoryMethod();
console.log(product2.operation()); // 출력: ConcreteProduct2

위 예시에서는 ProductCreator 인터페이스를 정의하고, 각각의 구현 클래스를 통해 객체를 생성하는 방식으로 팩토리 메서드 패턴을 구현했습니다.

옵저버 패턴

옵저버 패턴은 한 객체(주제)의 상태 변화에 따라 다수의 객체(옵저버)에게 알림을 전달하는 패턴입니다. 타입스크립트에서 옵저버 패턴을 구현하는 방법은 다음과 같습니다.

interface Observer {
  update(message: string): void;
}

class Subject {
  private observers: Observer[] = [];

  public addObserver(observer: Observer): void {
    this.observers.push(observer);
  }

  public notifyObservers(message: string): void {
    this.observers.forEach((observer) => observer.update(message));
  }
}

class ConcreteObserver implements Observer {
  public update(message: string): void {
    console.log(`Received message: ${message}`);
  }
}

const subject = new Subject();
const observer1 = new ConcreteObserver();
const observer2 = new ConcreteObserver();

subject.addObserver(observer1);
subject.addObserver(observer2);

subject.notifyObservers('Hello, observers!');
// 출력:
// Received message: Hello, observers!
// Received message: Hello, observers!

위 예시에서는 Subject 클래스와 Observer 인터페이스를 정의하고, ConcreteObserver 클래스를 통해 옵저버를 구현하여 옵저버 패턴을 적용했습니다.

이렇게 타입스크립트를 사용하여 Node.js 어플리케이션에 싱글톤, 팩토리 메서드, 그리고 옵저버 패턴을 적용할 수 있습니다. 이러한 디자인 패턴을 활용하면 보다 모듈화되고 유지보수가 용이한 코드를 작성할 수 있습니다.

참고 자료