티스토리 뷰
[DesignPattern] 2. Observer Pattern에 대한 고민
Observer Pattern이란?
옵서버 패턴(observer pattern)은 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴이다. 주로 분산 이벤트 핸들링 시스템을 구현하는 데 사용된다. 발행/구독 모델로 알려져 있기도 하다.
- 출처 : 위키피디아 -
결국은 Observer Pattern은 중심 객체에서 여러 객체들을 한번에 관리하는데 사용하는걸 말합니다. 이렇게 함으로서 한번에 모든 객체에게 상태 변화를 알려 줄 수 있습니다.
왜 Observer 라고 이름 붙였을까?
Observer의 사전적인 의미는 관측자 정도가 됩니다. 사실 전 처음에 메인 컨트롤러가 다른 여러 객체를 관찰한다는 의미인줄 알았는데 인터페이스 구성을 보니 반대더군요. 이 패턴을 명명한 사람은 여러 관측자 객체들이 공통의 주제를 관측하고 있다는 의미를 전달하고 싶었던 것 같습니다.
즉, Subject는 여러 Observer에게 자신의 상태 정보를 알려줘야 합니다. 이를 위해 Subject는 자신을 관찰하는 Observer들의 리스트를 갖게 됩니다. 또한 특정 Observer를 리스트에 추가, 제거하는 기능은 물론 자신의 상태정보를 모두에게 알려줄 수 있는 기능도 갖고 있어야 합니다. 반대로 Observer는 Subject가 보내는 정보를 처리할 수 있는 기능이 있어야 합니다.
다이어그램
어떻게 구현할까?
크게 Observer와 Subject가 필요합니다.
Observer 구현
1. notify() : Subject로부터 정보를 받아 처리할 메소드. update()라는 이름으로도 자주 사용
Subject 구현
1. observerCollection : 관리 할 Observer 리스트를 보관.
2. registerObserver(observer) : Observer를 리스트에 추가하는 메소드.
3. unregisterObserver(observer) : Observer를 리스트에서 삭제하는 메소드.
4. notifyObservers() : 관리하는 Observer들에게 자신의 정보를 일괄적으로 보내는 메소드.
고민
처음 이 패턴에 대해 고민해보면서 든 생각은 왜 굳이 패턴을 사용하고 정보를 보내주는 함수를 만들었을지 입니다. 각 옵저버가 서브젝트 클래스에 접근해서 바로 정보를 사용하면 실시간으로 정보가 동기화 되는데 굳이 이렇게 만들 이유가 있는지 의문이었습니다. 그런데 생각해보면 이유는 간단한 것 같습니다. 의존성을 최대한 줄이는 것. 그게 제일 중요한 이유 같습니다.
서브젝트는 어느 옵저버가 올지도 모르고 어떠한 옵저버가 와도 코드를 수정 할 일이 없습니다. 옵저버 또한 어느 서브젝트에 들어갈지 관심도 없고 코드를 수정 할 일도 없습니다. 만약 직접 클래스에 접근해서 해당 변수를 사용했다면 후에 변수의 수정 여부에 따라 해당하는 객체를 다 찾아서 수정해야 하는데, 이 패턴을 사용하면 그럴일을 최소화 할 수 있습니다.
물론 최소한의 의존은 필요합니다. 서로가 정보를 주고 받아야 하기 때문에 정보를 어떻게 줄지, 받은 정보를 어떻게 처리할지는 객체에 맞춰서 구현해야 합니다. 하지만 이 부분은 인터페이스에 정의된 부분이고 나머지 부분은 건드릴 필요가 없게 되겠죠. ( 만약 건드려야 한다면 다른 코드가 외부 클래스에 의존하는 것이기에 잘못된 설계라고 생각합니다. )
그렇지만 이 방법도 단점은 있다고 생각합니다. 의존성을 제거하려고 서로간의 참조를 끊어놨기 때문에 실시간으로 정보가 반영되지 않습니다. 그러한 특성에 맞춰서 가장 적절한 사용처는 웹이 아닌가 싶습니다. 웹 상에서는 실시간이 아니라 사용자의 요청에 따라 정보를 조회하고 뷰를 렌더링하기 때문입니다. ( 실시간 통신 기능은 논외로 치겠습니다. )
언제 사용하면 좋을까?
처음 정의한데로 한 객체가 다른 객체를 여러개 관리하고 싶을 때 사용하는 것이 정석인 것 같습니다. 하지만 실시간으로 정보가 업데이트 되야 하는 경우라면 의존성을 높여서 객체를 직접 참조할지를 고민해봐야 할 것 같습니다.
예제
MVC 모델을 옵저버 패턴으로 한번 만들어 보았습니다.
우선 Controller가 Model을 갖고 있고 여러 View를 관리하게 됩니다.
Subject -> Controller
Observer -> View
Subject가 갖고 있는 정보 -> Model
observerList로 관리 할 옵저버를 저장합니다.
addObserver와 removeObserver로 옵저버를 추가 제거 합니다.
updateObserver로 현재 컨트롤러가 갖고있는 모델 정보를 각 옵저버에게 보내줍니다.
간단하게 어떤 value 값을 갖고 있는 모델입니다.
옵저버는 서브젝트의 정보를 받을 update와 제가 임의로 받은 정보를 출력해줄 수 있는 display 메소드로 이루어져있습니다.
위에서 설명한 3가지 기능입니다.
옵저버에서 그 내용을 구현합니다.
이제 컨트롤러가 자신이 갖고있는 정보가 될 모델 객체를 받고, 자신이 관리할 여러 뷰를 받습니다.
정보가 바뀌고 뷰가 바뀌는 과정을 출력해보면서 결과를 테스트합니다.
결과입니다.
'Dev Story > DesignPattern' 카테고리의 다른 글
[DesignPattern] 1. Strategy Pattern에 대한 고민 (0) | 2015.01.24 |
---|