Observer Pattern

Ahyeon, Jung·2024년 1월 28일
0

Observer Pattern

옵저번 패턴은 객체 간의 일대다 의존 관계를 정의하는 패턴
어떤 객체의 상태가 변할 때, 그 객체에 의존하는 다른 객체들이 이 변화를 통지받아 자동으로 업데이트될 수 있도록 하는 구조
객체 간의 결합도를 낮추고, 확장성을 높이는데 도움을 줌

장점

비동기적인 이벤트 처리에 유용하며, 객체 간의 강한 결합을 피하고, 이벤트가 발생할 때마다 관련된 옵저버들이 동작할 수 있도록 해줌
새로운 옵저버를 추가하거나 기존의 옵저버를 제거하는 것이 간단해 코드의 유지보수성과 확장성을 높이는데 도움
주체와 옵저버가 각각 독립된 객체로 존재하기 때문에 코드의 재사용성과 모듈화가 강화됨
이벤트 기반의 자바스크립트에 적합

단점

옵저버가 등록된 순서대로 이벤트를 받기 때문에, 순서가 중요하지 않은 경우 번거로울 수 있음
주체에서 옵저버를 명시적으로 제거하지 않을 경우 메모리 누수가 일어날 수 있음
이벤트가 발생할 때마다 모든 옵저버에게 통지되므로, 성능에 영향을 줄 수 있음
규모가 커지면서 관리해야할 옵저버의 수가 많아질 경우 코드가 복잡해질 수 있음

Subject

상태를 관리하는 주체 객체
옵저버들을 등록하고, 상태가 변할 때 등록된 옵저버들에게 알림을 보냄

Observer

주체의 상태 변화를 감시하고, 변화가 있을 경우 특정 동작을 수행하는 객체
주체에 등록되어 있어야 하며, 주체로부터 상태 변화에 대한 통지를 받게 됨

class Observable {
  constructor() {
    this.observers = [];  // 이벤트가 일어날때 알릴 observers list
  }

  subscribe(func) {  // observers list에 observer를 추가하는 메서드
    this.observers.push(func);
  }

  unsubscribe(func) {  // observers list에서 observer를 제거하는 메서드
    this.observers = this.observers.filter((observer) => observer !== func);
  }

  notify(data) {  // 이벤트가 일어날 때 모든 observers에게 알리는 메서드
    this.observers.forEach((observer) => observer(data));
  }
}
export default function App() {
  return (
    <div className="App">
      <Button>Click me!</Button>
      <FormControlLabel control={<Switch />} />
    </div>
  );
}
import { ToastContainer, toast } from "react-toastify";

function logger(data) {
  console.log(`${Date.now()} ${data}`);
}

function toastify(data) {
  toast(data);
}

export default function App() {
  return (
    <div className="App">
      <Button>Click me!</Button>
      <FormControlLabel control={<Switch />} />
      <ToastContainer />
    </div>
  );
}
import { ToastContainer, toast } from "react-toastify";

function logger(data) {
  console.log(`${Date.now()} ${data}`);
}

function toastify(data) {
  toast(data);
}

observable.subscribe(logger);
observable.subscribe(toastify);

export default function App() {
  function handleClick() {
    observable.notify("User clicked button!");
  }

  function handleToggle() {
    observable.notify("User toggled switch!");
  }

  return (
    <div className="App">
      <Button>Click me!</Button>
      <FormControlLabel control={<Switch />} />
      <ToastContainer />
    </div>
  );
}

헤드 퍼스트 디자인 패턴

느슨한 결합의 위력

  • subject는 옵저버가 특정 인터페이스를 구현한다는 사실만 압니다.
  • 옵저버는 언제든지 새로 추가할 수 있습니다.
  • 새로운 형식의 옵저버를 추가할 때도 주제를 변경할 필요가 전혀 없습니다
  • 주제와 옵저버는 서로 독립적으로 재사용할 수 있습니다.
    주제나 옵저버가 달라져도 서로에게 영향을 미치지 않습니다.
profile
https://a-honey.tistory.com/

0개의 댓글