(C++ : Design-pattern) Observer Pattern

Posted by : at

Category : Cpp   Design-pattern


Observer

객체 사이의 1:N의 종속성을 정의 하고 한 객체의 상태가 변하면 종속된 다른 객체에 통보가 가고 자동으로 수정이 일어나게 한다.

// Observer 패턴의 기본적 구조
#include <iostream>
#include <vector>
using namespace std;

struct IGraph
{
    virtual void update(int) = 0;
    virtual ~IGraph() {}
}

class Table
{
    vector<IGraph*> v;
    int data;
public:
    void attach(IGraph* p) { v.push_back(p); }
    void detach(IGraph* p) { }

    void SetData(int d) { 
        data = d;
        for( auto p : v )
            p->update(data);
    }
};

class PieGraph : public IGraph
{
public:
    virtual void update(int n)
    {
        Draw(n);
    }

    void Draw(int n)
    {
        cout << "Pie Graph : ";
        for(i = 0; i < n; i++)
            cout << "*";
    }
};

class BarGraph : public IGraph
{
public:
    virtual void update(int n)
    {
        Draw(n);
    }
    
    void Draw(int n)
    {
        cout << "Bar Graph : ";
        for(i = 0; i < n; i++)
            cout << "+";
        cout << endl;
    }
};

int main()
{
    BarGraph bg;
    PieGraph pg;

    Table t;
    t.attach(&bg);
    t.attach(&pg);

    while(1)
    {
        int n;
        cin >> n;
        t.SetData(n);
    }
}

Example

// 새로운 table을 만들고 싶다
class Table3D
{
    vector<IGraph*> v;
    int data[10];       // 다른데는 모두 동일하고 데이터만 다르다면??
public:
    void attach(IGraph* p) { v.push_back(p); }
    void detach(IGraph* p) { }

    void SetData(int d) { 
        data = d;
        for( auto p : v )
            p->update(data);
    }
};
class Subject
{
    vector<IGraph*> v;
public:
    void attach(IGraph* p) { v.push_back(p); }
    void detach(IGraph* p) { }
    void notify(int data)
    {
        for( auto p : v )
            p->update(data);
    }
};
class Table3D : public Subject
{
    int data[10];
public:

    void SetData(int d) { 
        data = d;
        notify(data);
    }
};
class Subject;

struct IGraph
{
    virtual void update(Subject*) = 0;
    virtual ~IGraph() {}
};

class Subject
{
    vector<IGraph*> v;
public:
    void attach(IGraph* p) { v.push_back(p); }
    void detach(IGraph* p) { }
    void notify()
    {
        for( auto p : v )
            p->update(this);
    }
};

class Table3D : public Subject
{
    int data[10];
public:
    int GetData() { return data; }

    void SetData(int d) { 
        data = d;
        notify();
    }
};

class PieGraph : public IGraph
{
public:
    virtual void update(Subject* p)
    {
        // table에 접근해서 data를 꺼내온다.
        int n = static_cast<Table3D*>(p)->GetData();
        Draw(n);
    }

    void Draw(int n)
    {
        cout << "Pie Graph : ";
        for(i = 0; i < n; i++)
            cout << "*";
    }
};

About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links