Template을 이용한 Observer 패턴 – 1단계

C++의 template을 이용해서 Observer를 구현하는 것에 대한 단계적 설명입니다. 원본은 데브피아에서 김태현(tipani)님이 올려 놓으신 글을 기반으로 작성했으며 한단계 더 업그레이드 했습니다. 제가 늘 느껴오는 것이지만 C++의 template은 기존의 클래스간 관계도에 한정해 볼적에 그 디자인을 획기적으로 개선한다는 점에서 그 판도를 확 바꿀 수 있는 강력한 개념이라고 생각합니다. 아무쪼록 제가 김태현님의 글을 보고 매우 재미있게 template에 한발짝 다가섯듯이 여러분도 제 글을 통해 template에 한발짝 다가 설수있다면 정말 기쁘겠습니다. 참고로 이 글을 읽기 전에 Observer 패턴이 무엇인지 패턴입문서를 살펴보시길 바랍니다. 또한 이 글의 진행은 단계 단계 개선해 나가는 흐름으로 진행된다는 점에 유의하시길 바랍니다.

먼저 1단계입니다. 아래의 코드는 Observer들의 관리에 대한 책임을 맡고 있는 Observed 클래스입니다.

template 
class Observed {
public:
    Observed() {}
    typedef std::list typeObservers;
    virtual ~Observed() {}

    void RegisterObserver(T *pOb) {
        m_listObserver.push_back( pOb );
    }

    void UnRegisterObserver(T *pOb) {
        m_listObserver.remove(pOb);
    }

protected:
    typeObservers m_listObserver;

};

Observed가 관리하는 Observer 클래스인 Observabe 입니다. 단순히 Observed가 호출할 Observer의 OnEvent 함수가 순수가상함수로 선언되어 있습니다.

class Observable {
    virtual void OnEvent(int a) = 0;
};

그리고 아래는 Obserable를 상속받아 구현한 클래스들입니다.

class Observable_A : public Observable
{
    virtual void OnEvent(int a) {
        std::cout << "Fire_A -> " << a << std::endl;
    }
};

class Observable_B : public Observable
{
    virtual void OnEvent(int a) {
        std::cout << "Fire_B -> " << a << std::endl;
    }
};

이제 마지막으로 Observed가 자신이 관리하고 있는 Observable의 OnEvent를 호출해 줘야 하는데, Observed 클래스는 자신이 관리하고 있는 Observable의 타입을 모르기 때문에 Observed와 Observable의 관계를 연결해 주기 위한, Observed로부터 상속받은 EventSrc 클래스가 필요합니다.

class EventSrc : public Observed
{
    void Fire(int a)
    {
        typeObservers::itrator it;
        for(it=m_listObserver.begint(); it!=m_listObserver.end; ++it) {
            (*it)->OnEvent(a);
        }
    }
};

드디어 1단계의 Observer 패턴의 구현이 완성되었습니다. 실제 사용하는 예는 다음과 같습니다.

int main() {
    EventSrc *pES = new EventSrc();
    Observable *pO_A = new Observale_A();
    Observable *pO_B = new Observale_B();

    pES->RegisterObserver(pOA);
    pES->RegisterObserver(pOB);

    pES->Fire(99);


    delete pO_B;
    delete pO_A;
    delete pES;

    return 0;
}

1단계에서 산출된 소스만으로도 충분할 수도 있겠지만, 큰 문제점이 하나 있습니다. 그것은 바로 SRP(Single Responsiblity Principle)를 위반한다는 사실입니다. 즉, Obserable를 관리하는 책임을 Observed와 EventSrc라는 두개의 클래스가 책임을 나눠서 지고 있다는 점입니다. 그럴수밖에 없는 이유는 본문에 언급을 했구요.

이제 다음 2단계 이후부터는 이러한 SRP의 원칙을 지켜나가는 것을 해결문제로 다뤄나가면서 점차적으로 개선된 Observer 패턴을 구현해보겠습니다.

[여행] 제부도

날짜는 10월 14일. 대학교 시절에 같은 학교울타리에 있다가, 몇년전에 나는 서울로, 하나는 대전으로.. 또 하나는 경기도 화성으로 각자의 길을 찾아 떠났던 친구들.. 지난 추석때 모두 함께 만나지 못하다가, 어쩐일로 모이게 되어 떠난 제부도 여행. 제부도 조개가 유명하다고 해서 갔다..








조개를 케는 사람들도 제법 있었고, 연인.. 가족들과 나들이 나오신 분들도 많았고.. 주말이라 많은 사람들로 붐볐다. 서로 자기집에서 조개구이를 먹으라고 문앞에서 호객행위를 하는 환하게 웃으며 우스꽝스러운 행동을 하던 아저씨들. 사람들이 그냥 지나가면 한마디 뱃는데.. ㅅㅂㄹㅁ라고.. 똑똑히 봤어요.. ㅡ_ㅡ ㅅㅂㄹㅁ!

조개는 실망. 니가 정녕 제부도 조개냐.. 그냥 저기 앞바다 조개냐.. 묻고 싶었다. 서울 신림에서 먹었던 조개구이보다 별로였다. 너도 중국산이냐? 조개구이 맛에 대한 아쉬움을 뒤로 하고 돌아오는 길의 순대국밥은 정말 맛있었다. 오던 길에 도로에서 산 포도도 맛있었고…

처음 출발때 약속 시간을 지키지 못하고 늦어, 친구들에게 너무 미안했었다.. 찍고 싶었던 갈매기는 못찍었지만, 집에서 몇년 묶은 디카를 꺼내들었고, 오랜만에 쏘인 바다바람과 날씨까지 좋았고.. 친구들과 오랜만에 모여 기분 좋은 여행이 되었다.