Observer pattern (JavaScript)
개요
MVC(Model-View-Controller)
패턴을 이용하여 프로젝트를 개발하던 중, 상태(Model
)가 변경되면, 화면(View
)이 리렌더링되도록 해야하는 부분이 있었다.
단순히 상태가 변경될 때, html
을 render
하는 함수를 호출하면 되지만,
그렇게 되면 Model
과 호출될 render
함수의 종속성이 강해지기도 하고,
잘못 설계하는 경우 Model
과 View
사이가 상호 참조가 될 가능성이 있기 때문에 결론적으로 옵저버 패턴을 사용하기로 결정하였다.
옵저버 패턴에 대한 이해도를 높이기 위해 포스팅을 남기고, 이를 간단하게 구현해보도록 하겠다.
이벤트 드리븐 프로그래밍
웹 애플리케이션을 개발하려면, 애플리케이션 구동중에 비동기적으로 발생할 다양한 사용자 이벤트(click, keyup, …)에 대해 미리 고려하고, 브라우저가 이를 감지하고 적절한 동작을 수행할 수 있도록 설계해야 한다.
그리고 이렇게 이벤트에 반응하여, 동적으로 동작이 수행되도록 하는 프로그래밍 방식을 이벤트 드리븐(event-driven) 프로그래밍이라고 한다.
그런데, 기본적으로 이벤트는 비동기적으로 발생한다.
즉, 개발자는 사용자가 언제 애플리케이션과 상호작용(interaction)할지 모른다는 뜻이다.
이를 해결하기 위해, JavaScript에서는 addEventListener
또는 DOM 요소의 이벤트 핸들러 프로퍼티
에 handler를 바인딩
하는 방식으로 브라우저에게 이벤트 감지를 맡기고, 동작 수행을 위임한다.
상태 변화 감지
위와 같은 이벤트 드리븐 방식이 바로 옵저버 패턴(Observer pattern)이 적용된 대표적인 예 인데, 이처럼 상태변화에 대해서 관찰자(observer)가 상태변화를 관찰(observe)하게 하고, 변화가 생길때 마다 관찰자(observer)들에게 변경사항이 있음을 알려주는 것이 옵저버 패턴이다.
Observer pattern
옵서버 패턴(observer pattern)은 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴이다 - Wikipedia, 옵저버 패턴
위키백과에서는 옵저버 패턴을 위와 같이 정의하고 있다.
이를 구체화하여 다이어 그램으로 나타내면 아래와 같다.
위 다이어그램은 객체지향을 기반으로 작성된 다이어그램이다.
객체지향을 조금 덜어내고, JavaScript 기반의 MVC
형태로 간소화한다면, 아래와 같이 나타낼 수 있을 것 같다.
위 다이어그램을 보면, 구현에 따라 Model
을 참조하고 있는 View
또는 Controller
에서 observer로 등록할 함수(메서드)를 subscribe(listener)
로 등록하게 된다.
그리고 Model
에서는 상태변경이 일어날 때 마다 notify()
메서드를 호출하여, 상태가 변경되었음을 observer에 알려 observer 함수가 후처리되도록 구현할 수 있다.
이벤트 핸들러의 호출을 브라우저에게 위임하는 것과 같이 observer의 호출을 상태(model) 객체에게 위임한다고 이해하면 더 쉽게 이해가 가능할 것 같다.
첨언하자면 개인적으로 View에서 observer를 등록하는 것이 맞다고 생각한다.
구현
이를 기반으로 TODO - 할일 목록 관리 프로그램을 만든다고 생각해보자.
TODO객체가 갱신될 때 마다, View 또한 함께 갱신되어야 한다.
1 | // Model |
이렇게 구현하면, state
(상태)가 갱신될 때마다, listeners
(observers)에 등록된 함수들이 호출되게 될 것 이다.
이제 html을 렌더링하는 함수 render()
가 있다면, subscribe(render)
와 같이 등록하여, observer 패턴이 정상적으로 동작하게 할 수 있다.
참고