옵저버패턴(Observer Pattern)

박재현·2022년 5월 17일
0

FE 톺아보기

목록 보기
5/10
post-thumbnail

옵저버패턴이란?

객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴이다.

어떤 객체의 상태가 변할 때 그와 연관된 객체들에게 알림을 보내는 디자인 패턴

옵저버 패턴에는 주체 객체와 상태의 변경을 알아야 하는 관찰 객체(Observer Object)가 존재하며 이들의 관계는 1:1이 될 수도 있고 1:N이 될 수도 있다.

옵저버 패턴의 장단점

장점

  1. 실시간으로 한 객체의 변경사항을 다른 객체에 전파할 수 있다.
  2. 느슨한 결합으로 시스템이 유연하고 객체 간의 의존성을 제거할 수 있다.

단점

  1. 너무 많이 사용하게 되면, 상태 관리가 힘들 수 있다.
  2. 데이터 배분에 문제가 생기면 자칫 큰 문제로 이어질 수 있다.

옵저버패턴의 간단한 예시

크루(Crew)는 코치(Coach)를 observing 하고 있고, 코치가 하는 일을 모두 notify 받아야 한다. Singco라는 코치와 Loopy, Mimmi, Fry 라는 크루들이 있다고 가정해보자.

코치는 크루들을 등록하고, 해제하고, 크루들에게 행동을 알리는 세가지 행동을 가지고 있다.

먼저 코치와 크루는 아래와 같은 인터페이스를 갖는다.

interface Crew {
  update(msg: String);
}

interface Coach {
  subscribe(crew: Crew);
  unsubscribe(crew: Crew);
  notifyCrew(msg: String);
}

다음은 코치인 Singco 클래스를 만들어보자.

class Singco implements Coach {
  private crews = [];

  public eatFood(): void {
    console.log("Singco가 밥을 먹는다.");
    this.notifyCrew("나 밥먹었다.");
  }

  public runaway(): void {
    console.log("Singco가 도망간다.");
    this.notifyCrew("나 도망갔다.");
  }

  public sleep(): void {
    console.log("Singco가 잔다.");
    this.notifyCrew("나 잔다.");
  }

  public subscribe(crew: Crew): void {
    this.crews.push(crew);
  }

  public unsubscribe(crew: Crew): void {
    this.crews = this.crews.filter((member) => member !== crew);
  }

  public notifyCrew(msg: String): void {
    this.crews.forEach((crew) => crew.update(msg));
  }
}

Singco 클래스는 밥먹기, 도망가기, 잠자기라는 세가지 행동을 갖는다. 그리고 크루들의 update 메서드를 각각 호출한다.

옵저버인 Loopy, Mimmi, Fry 크루들은 코치인 Singco가 행동을 관찰하다가 Singco가 행동을 할 때, update 로직을 실행한다.

class Loopy implements Crew {
  public update(msg: String): void {
    console.log(`Loopy 수신 : ${msg}`);
  }
}

class Mimmi implements Crew {
  public update(msg: String): void {
    console.log(`Mimmi 수신 : ${msg}`);
  }
}
class Fry implements Crew {
  public update(msg: String): void {
    console.log(`Fry 수신 : ${msg}`);
  }
}

singco가 sleep이라는 행동을 하게되면

const singco = new Singco();
const loopy = new Loopy();
const mimmi = new Mimmi();
const fry = new Fry();

singco.subscribe(loopy);
singco.subscribe(mimmi);
singco.subscribe(fry);

singco.sleep();

// Singco가 잔다.
// Loopy 수신 : 나 잔다.
// Mimmi 수신 : 나 잔다.
// Fry 수신 : 나 잔다.

Loopy 구독을 해지한 뒤에 sleep을 다시 실행하면

singco.unsubscribe(loopy);
singco.sleep();

// Singco가 잔다.
// Mimmi 수신 : 나 잔다.
// Fry 수신 : 나 잔다.

구독한 크루들만 코치의 행동에 로직을 실행하게 된다.


참조

[디자인패턴] 옵저버 패턴 (Observer Pattern) 아주 간단하게 정리해보기
[Design Pattern] 옵저버 패턴(Observer Pattern)에 대하여

profile
공동의 성장을 추구하는 개발자

0개의 댓글