이 글은 헤드퍼스트 디자인 패턴(한빛 미디어, 에릭 프리먼 외)를 읽고 정리한 것입니다.
옵저버 패턴이란?
옵저버 패턴은 한 객체의 상태가 바뀌면 해당 객체에 의존하는 다른 객체에 연락이 가고, 자동으로 내용이 갱신되는 방식의 "일대다 의존성"을 정의하는 패턴이다.
책에 나온 예시에 따르면 옵저버 패턴은 신문사와 구독자로 이루어진 신문 구독 서비스와 비슷하다. 즉, 신문사가 주제 객체이며 구독자가 옵저버 객체가 된다.
- 주제 객체
- 구독자에게 전달할 중요 데이터를 관리한다.
- 주제의 데이터가 바뀌면 옵저버에게 그 소식을 전한다.
- ex) 신문사
- 옵저버 객체
- 바뀐 주제의 데이터 갱신 내용을 전달 받는다.
- ex) 신문을 구독하는 개인/ 호텔/ 회사 등이 이에 해당한다.
만약 주제를 구독하고 있는 옵저버가 아니라면 주제의 데이터 갱신 내용을 전달 받을 수 없다.
구현 방식
- 보통 주제 인터페이스 & 옵저버 인터페이스를 갖는 클래스 디자인으로 구현 된다.
- 주제와 옵저버는 일대다 관계로 구현 된다. 즉, 한 주제에 여러 개의 옵저버가 있을 수 있다.
- 옵저버는 데이터가 변경되었을 경우 주제에서 데이터를 갱신해 주길 기다려야 하기 때문에 주제에 의존적이다.
(아래의 인터페이스와 구상 클래스는 책에서 든 예시를 가져온 것입니다.)
인터페이스
- Subject
- registerObserver(): 옵저버로 등록하고 싶을 때 사용하는 메소드
- removeObserver(): 옵저버에서 탈퇴하고 싶을 때 사용하는 메소드
- notifyObserver(): 주제에 변경 사항이 생겼을 때 옵저버에게 알리기 위해 사용하는 메소드
- Observer
- update(): 주제의 상태가 바뀌었을 때 데이터를 갱신하기 위해 사용하는 메소드
구상 클래스
- ConcreteSubject
- registerObserver() {}
- removeObserver() {}
- notifyObserver() {}
- getState(): 주제의 옵저버가 알고 싶을 경우 옵저버는 주제의 상태를 pull 할 수 있다.
- setState(): 주제가 옵저버에게 상태를 알리고 싶을 경우 옵저버는 주제에게 상태를 push 할 수 있다.
- ConcreteObserver
- update(): 옵저버가 특정 주제에 등록되어 있다면 주제의 상태 변경을 갱신하기 위해 사용할 수 있다.
옵저버 패턴의 느슨한 결합
느슨한 결합은 객체들이 상호작용 하며 서로에 대해 잘 알지 못하는 관계를 말한다.
옵저버 패턴은 주제와 옵저버가 느슨한 결합을 이루고 있다. 느슨한 결합을 이용하면 시스템에 변경 사항이 생겨도 오류를 최소화 한 유연한 객체지향 시스템을 만들 수 있다.
아래에 나열된 내용은 이러한 느슨한 결합의 장점이다.
- 주제는 옵저버의 구상 클래스가 무엇인지, 그리고 어떤 일을 하는지 알지 못한다.
- 주제는 옵저버가 특정 인터페이스를 구현한다는 것만 안다.
- 실행 중에 하나의 옵저버를 바꾸거나 새로 추가해도 계속해서 다른 옵저버에게 데이터를 보낼 수 있다.
- 주제와 옵저버는 서로 독립적이며 재사용 가능하다.
- 주제와 옵저버의 변화가 서로에게 영향을 미치지 않는다.
- 단, 주제와 옵저버는 각각에 맞는 인터페이스를 구현해야 한다.