서울특별시 종로 5가 왕복 8차선 도로에 교통사고가 발생했다는 신고가 관계기관에 접수되었다고 가정하자.

그럼 신고를 받은 관계기관은 신속히 해당 사고지점으로 출동할 것이다.

아마도, 사고 유형이 '교통사고' 이기 때문에, 병원, 소방서, 경찰 등의 관계기관이 출동할 것이다.

 

그리고 옵저버 패턴에 대해서 잘 모르는 상태에서, 이를 구현해 보면 아마 아래와 비슷할 것이다.

void 119()
{
    while ( NULL != (신고유형 = 사고접수()) )
    { 
        switch ( 신고유형 )
        {
        case 교통사고:
            Notify(경찰);
            Notify(소방서);
            Notify(병원);
            break;
        case 응급상황:
            Notify(병원);
            break;
        case 간첩신고:
            Notify(경찰);
            break;
        default:
            break;
        }
    }
}

지금도 깔끔해 보이지만, 옵저버 패턴을 사용하게 될 경우 더 깔끔해진다.

그리고 아래는 위에서 언급한 예제를 옵저버 패턴을 사용하여 구현한 예제 이다.

void 119()
{
    교통사고.registerObserver(경찰, 소방서, 병원);
    화재신고.registerObserver(소방서, 병원);
    간첩신고.registerObserver(경찰);
    응급신고.registerObserver(병원);

    while ( NULL != (신고유형 = 사고접수() )
    {
        Observers *observers = GetObservers(신고유형);
        foreach ( o in observers )
            o->Notify();
    }
}

즉, 옵저버 패턴은 한 객체의 상태가 바뀌면(혹은 관심 주제가 변경되면) 

그 객체에 의존하는 다른 객체들한테 연락이 가게됨으로서

자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의할 때

종종 사용되어지는 패턴이다. 

 

 

끝으로, 위에서 언급한 옵저버 패턴 예제에서 각각의 클래스들을 좀 더 구체화 시키면 아래와 같다.

 

class 소방서 : public CObserver {}

class 경찰 : public CObserver {}

class 병원 : public CObserver {}

 

class 교통사고 : public Subject {  private: std::vector<CObserver *> m_vObservers; }

class 화재신고 : public Subject {  private: std::vector<CObserver *> m_vObservers; }

 

여기서 주의깊게 살펴봐야 할 사항은 서로 다른 객체사이에 통신을 하기 위해서

Observer 라는 클래스를 사용하고 있다는 점이다. (느슨한 연결 + 역활분리)

 

[생각할 꺼리]

 

1. 옵저버 패턴에서 서로 다른 클래스 사이에서 통신을 위해서 사용하는 CObserver 클래스를

   사용하는 이유는 무엇일까?

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,