Observer 패턴

Taehun Jeong·2023년 3월 2일
0
post-thumbnail

Model ↔ View

옵저버 패턴에 관해 서술하기에 앞서 MVC 패턴에 대해 알아보도록 하겠다. MVC 패턴이란 사용자 인터페이스, 데이터 및 논리 제어를 구현하는데 널리 사용되는 소프트웨어 디자인 패턴으로 데이터 처리와 관리를 담당하는 Model, UI 처리를 담당하는 View, 명령과 상태의 변경을 Model과 View로 라우팅하는 Controller로 구분할 수 있다. Javascript에서는 객체 지향 프로그래밍이 가능하므로 MVC 패턴을 적용할 수 있지만, 프론트 엔드에서의 적용은 별로 효율적이지 못하다. 그 이유로는,

  • Model과 View의 강한 의존성
    프론트엔드에서의 View는 단순히 Model을 받아 보여주는 역할만을 수행하는 것이 아니라, View에서 이벤트가 발생하기도 하는 등 다양한 사건이 일어난다. 즉, View에서 기존의 역할과 Controller의 역할도 수행할 수밖에 없다. 또한, 사용자 입력 등으로 View가 변경되면 Model에서도 그 내용을 반영해야 한다. 하지만 서버로부터 데이터를 받아 처리하는 등으로 Model이 변경되면 View도 변경될 수 있다. 따라서 View와 Model간 양방향의 관계가 생긴다. 때문에 프로젝트의 규모가 커질수록 양방향으로 인해 관계가 더욱 복잡해진다.
  • View가 굉장히 많다.
    일반적인 경우, View는 다수가 존재한다. View와 Model이 양방향으로 데이터를 교환하면서, 또는 Model이 다수 있을 경우 의존성과 View-Model 간 복잡도도 증가하게 된다.
  • 만능 Controller
    강한 의존성 문제 해결을 위해 Controller를 두어 View와 Model 간의 처리를 해결할 수도 있다. 하지만 Controller도 그에 따른 복잡도를 모두 수용할 수 있어야 하므로 Controller도 굉장히 비대해질 수밖에 없다.
  • View는 계층적인 구조
    View는 DOM을 표현한다고 할 수 있다. 그에 따라 어느 정도 트리 구조를 가지며, 그를 제어하기 위해 잦은 re-rendering이 빈번하게 일어난다. 원래의 구조를 활용하기 위해 re-rendering을 최소화할 수 있는 방법이 필요하다.

따라서

  • 복잡한 View, Model 관계를 단순화할 수 있으면서,
  • View 계층처리로 쉽고 효율적인 DOM 처리를 할 수 있어야 한다.

Observer 패턴

옵저버 패턴이란 객체 지향 디자인 패턴 중의 하나로, 객체 간의 일대다 의존 관계를 정의하는 패턴이다. 한 객체의 상태 변화를 정해지지 않은 여러 다른 객체에 통지하고 싶을 때 사용되는 패턴이다. 옵저버 패턴의 목적은 모듈간의 의존성을 낮게 하여 결합도를 낮추는 데 있다.

옵저버 패턴은 주제(Subject) 객체와 옵저버(Observer) 객체를 갖는다.

  • 주제 객체 : 옵저버 목록을 관리하고, 옵저버를 등록하고 제거할 수 있는 메서드를 제공한다. 상태의 변경이 발생하면 등록된 옵저버에 변경 내역을 알린다.
  • 옵저버 객체 : 주제 객체의 상태 변화에 따라 처리할 동작을 구현하며, 주제 객체의 상태 변화에 따른 알림을 받아 처리를 수행한다.

위의 그림은 StatusChecker로부터 상태를 받아 상태에 변화가 있을 경우 메시지와 이메일을 보내는 것을 옵저버 패턴으로 구현하여 그림으로 나타낸 것이다. 주제 객체인 StatusSubject는 add, remove 메서드를 통해 각각 옵저버를 등록하고 삭제할 수 있다. 상태에 변화가 있을 경우 notifyStatus 메서드가 등록된 옵저버 객체의 onAbnormalStatus 메서드를 호출한다. 여기서 주제 콘크리트 클래스옵저버 콘크리트 클래스라는 것을 사용한다. 주제 콘크리트 클래스란 Subject 인터페이스를 구현하는 구체적인 클래스를 말한다. 추상 클래스인 Subject로부터 옵저버를 어떻게 등록하고 삭제할지, 옵저버에게 어떠한 상태 변화 알림을 보내는 방법을 포함한다. 옵저버 콘크리트 클래스는 주제 객체의 상태 변화에 따라 처리할 동작을 구현하며, 말 그대로 주제 객체의 상태 변화에 따른 알림을 받아 처리를 수행하는 메서드를 갖는다.


Publisher-Subscriber 패턴

발행-구독 패턴은 옵저버 패턴과 유사하다고 할 수 있다. 발행-구독 패턴은 주제(subject)와 옵저버(observer) 대신 발행자(publisher)와 구독자(subscriber)가 존재하는 방식이다. 발행-구독 패턴은

  • 구독 방법을 포함해야 하며,
  • 구독자 리스트를 담고 있어야 하고,
  • 이벤트를 발행하는 방법을 갖고 있어야 한다.

옵저버 패턴과 명칭의 차이만 있는 것처럼 보이지만, 발행-구독 패턴은 브로커를 갖는다. 브로커는 발행자-구독자 사이의 중개 역할을 수행하는 객체로서, 발행자가 메시지를 발행하면 등록된 구독자에게 해당 메시지를 전달하는 역할을 한다. 이로 인해 발행-구독 패턴은 옵저버 패턴과 다음과 같은 차이점을 갖는다.

  • 발행자와 구독자는 서로의 선언 위치, 존재를 알 필요가 없다.
    옵저버 패턴은 Subject에 Observer를 등록하고 Subject가 직접 Observer에 직접 알려주어야 한다. 하지만 발행-구독 패턴에서는 발행자는 브로커에게 메시지를 전달하기만 하면 되며, 구독자는 브로커에 할당된 작업만을 모니터링하다가 할당 받아 작업하면 된다. 때문에 발행-구독 패턴은 옵저버 패턴보다 더 낮은 결합도를 갖는다고 할 수 있다.

메시지 큐(Message Queue)

메시지 큐는 프로세스나 프로그램 인스턴스가 데이터 상호 교환 시 사용하는 통신 방법으로 메시지를 보내는 프로세스와 받는 프로세스 간에 비동기적인 통신을 도와주는 중간 매개체이다. 대용량 데이터를 처리하기 위한 배치 작업이나, 채팅 서비스, 비동기 데이터를 처리할 때 사용한다. 발행-구독 패턴에서 메시지 큐가 브로커의 역할을 수행할 수 있다.

메시지 큐의 장점으로는 아래와 같이 말할 수 있다.

  • 비동기 : Queue에 넣어서 나중에 처리할 수 있다.
  • 비동조 : 애플리케이션과 분리할 수 있다.
  • 탄력성 : 일부가 실패하더라도 전체에 영향이 가지 않는다.
  • 과잉 : 실패할 경우 재실행 가능하다.
  • 보증 : 작업의 처리 여부를 확인할 수 있다.
  • 확장성 : 다수의 프로세스들이 Queue에 메시지를 보낼 수 있다.

메시지 큐를 사용하면, 옵저버 패턴보다 발행자-구독자 간의 결합도를 낮출 수 있고, 비동기적인 작업이 가능하다는 장점을 갖는다. 때문에 메시지 큐를 브로커로 주로 사용한다.


References

프롱트) 프론트엔드에서 MVC보다 더 많이 쓰이는 패턴은 ?
imnotmoon.log) MVC Pattern (vanilla JavaScript)
한빛미디어) MVC 모델과 Observer 패턴
개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴
jistol.github.io) Observer 패턴과 Publisher/Subscriber(Pub-Sub) 패턴의 차이점
Go devlog) 발행-구독 패턴(Publisher-Subscriber Pattern)이란?

profile
안녕하세요

0개의 댓글