Ayden's journal

옵저버 패턴

옵저버 패턴(Observer Pattern)은 객체 간의 1:N 관계를 정의하여, 한 객체의 상태가 변경될 때 이를 의존하는 다른 객체들이 자동으로 갱신되도록 하는 디자인 패턴이다. 옵저버 패턴의 구조는 이벤트를 중앙에서 관리하는 디스패처(Dispatcher) 와, 특정 이벤트에 반응하는 리스너(Listener) 로 나눌 수 있다.

디스패처는 이벤트를 중앙에서 관리하고, 발생한 이벤트를 적절한 리스너에게 전달하는 역할을 한다. 반면 리스너는 특정 이벤트에 반응하는 객체로, 디스패처에 등록되어 특정 이벤트가 발생하면 정의된 동작을 수행한다. 예를 들어, 자바스크립트에서는 EventEmitter가 디스패처 역할을 하며, on 메서드를 사용해 이벤트 리스너를 등록하고, emit 메서드로 이벤트를 발생시킬 수 있다. 이를 활용하면 대규모 애플리케이션에서도 효율적인 이벤트 흐름을 설계할 수 있다.

// 디스패처 클래스
class PizzaShop {
  private customers: Array<Customer> = []; // 고객들을 저장할 배열

  // 고객 등록
  addCustomer(customer: Customer): void {
    this.customers.push(customer);
  }

  // 고객 제거
  removeCustomer(customer: Customer): void {
    const index = this.customers.indexOf(customer);
    if (index !== -1) {
      this.customers.splice(index, 1);
    }
  }

  // 주문 ID에 대해 고객에게 알림
  notifyCustomers(orderId: string): void {
    this.customers.forEach(customer => customer.update(orderId));
  }
}

// 리스너 클래스
class Customer {
  constructor(private name: string) {}

  // 주문 준비되었을 때 호출되는 메서드
  update(orderId: string): void {
    console.log(`${this.name} is excited! Your order with ID: ${orderId} is ready.`);
  }
}

// 주문 클래스를 추가하여 주문 관리
class OrderSystem {
  private orderId: string;
  private pizzaShop: PizzaShop;
  private customer: Customer;

  constructor(customer: Customer, pizzaShop: PizzaShop) {
    this.customer = customer;
    this.pizzaShop = pizzaShop;
    this.orderId = this.generateOrderId();
    this.pizzaShop.addCustomer(this.customer); // 고객을 피자 가게에 등록
  }

  // 고유의 주문 ID 생성
  private generateOrderId(): string {
    return `ORD${Math.floor(Math.random() * 1000000)}`;
  }

  // 주문 준비 완료 시 고객에게 알림
  completeOrder(): void {
    console.log(`Order ${this.orderId} is completed!`);
    this.pizzaShop.notifyCustomers(this.orderId); // 피자 가게가 고객에게 알림
  }

  // 주문 취소 시 피자 가게에서 고객 제거
  cancelOrder(): void {
    console.log(`Order ${this.orderId} is cancelled.`);
    this.pizzaShop.removeCustomer(this.customer); // 피자 가게에서 고객 제거
  }
}


위의 예시에서는 피자를 만드는 클래스와 피자를 배달하는 클래스 등에 대해서는 전혀 고려하지 않았다. 어쩌면 앞으로 다루게 될 책임 연쇄 패턴에서 이 예시를 다시 써먹으며 알바 클래스와 배달 클래스를 추가한 예시를 제공할 지도 모르겠다.

블로그의 정보

Ayden's journal

Beard Weard Ayden

활동하기