본문 바로가기
공부/디자인패턴

Observer Pattern (옵저버 패턴)

by 개발자5 2023. 2. 2.
Observer Pattern (옵저버 패턴)

Observer는 Subject가 소유하는 정보의 변화에 관심을 갖으며, 변화가 일어났을 때 자신에게 알려주길 바란다. 이를 옵저버(Observer) 패턴이라고 한다.

 

  • Observer : 정보의 변화에 관심이 있는 객체
  • Subject : 정보 자체와 정보의 변화에 관심을 갖는 observer들의 목록을 갖고있는 객체

 

 

Example 1

AS센터에 노트북 수리를 맡긴다고 하자. 수리를 맡긴 후 수리 완료된 노트북을 돌려받기까지의 과정이다.

  1. AS센터에 노트북 수리를 맡김 → AS센터에 계속 전화를 걸어 AS 수리 완료여부를 확인 → 3일동안 전화한 끝에 수리완료를 확인 받고 노트북을 찾음.
  2. AS센터에 노트북 수리를 맡김 (연락처 남김) → 3일 뒤 AS센터로 부터 연락을 받음 (AS센터는 수리가 완료될 때만 고객에게 전화함) → 노트북을 찾음. < Observer Pattern >

사용자는 2와 같이 AS센터에 수리완료알림을 등록한 뒤, AS센터로 부터 알람이 오면 노트북을 찾으러 가면 된다.

 

Observer들의 의지에 따라 Subject에 추가/삭제 가능하다. 다시 말해, 정보의 변화를 알고 싶다면 등록하고 관심이 없다면 제거하는 형태를 갖는다. 이와 같은 모습 때문에 Publish(출판)-Subscribe(구독) 관계를 형성하기도 한다.

 

 

Example 2

아래 코드는 Traffic 정보를 필요로 하는 곳에서 필요 시 계속 정보를 요청해서 결과값을 받아오는 방식(정보 변화가 없음에도 계속 요청해야 하는 문제가 있음)이 아닌, 정보의 변화가 있을때만 등록된 Observer들에게 정보를 업데이트 할 수 있도록 알려주는 방식으로 구현된 코드이다.

/// observer ///
class ITrafficObserver
{
  public:
    virtual void OnTrafficUpdate(int nDownSpeed, int nUpSpeed) = 0;
};

class CTrafficDisplay : public ITrafficObserver
{
...
  public:
    virtual void OnTrafficUpdate(int nDownSpeed, int nUpSpeed);
};
class CNetworkMonitor
{
  ...
  public:
    // observer 추가
    void Attach(ITrafficObserver* pobjObserver); 
    // observer 삭제
    void Detach(ITrafficObserver* pobjObserver);
    // observer에게 상태변경을 알림
    void Notify(); 
  private:
    // observer 목록
    CList m_objObserverList;
};

void CNetworkMonitor::Notify()

    // 여기에서, m_objObserverList에 등록된 모든 observer들의 OnTrafficUpdate()를 호출
}

 

 

Example 3

이 외에도 어떠한 Event가 발생할 때 기 등록된 Event Listener들에게 정보를 전달해 주도록 하는 방식도 Observer Pattern을 사용한 예라고 할 수 있다. 

/// observer ///
class IEventListener
{
  public:
    virtual void OnHandleEvent(...) = 0;
};

class CXXX : public IEventListener
{
...
  public:
    virtual void OnHandleEvent(...);
};
class Event
{
  ...
  public:
    void AddListener(IEventListener* pobjListener); 
    void RemoveListener(IEventListener* pobjListener);
    void Notify(); 
  private:
    // Event listener list (observer list)
    CList m_objEventListener;
};

void Event::Notify()

    // 여기에서, m_objEventListener에 등록된 모든 listener(observer)들의 OnHandleEvent()를 호출
}