GGym's Practice Notes

4장. 관찰자 패턴 본문

Design Pattern/게임 디자인패턴

4장. 관찰자 패턴

GGym_ 2020. 4. 17. 20:42

책 : 게임 프로그래밍 패턴 (https://book.naver.com/bookdb/book_detail.nhn?bid=10615724)

참고 블로그 글 : https://boycoding.tistory.com/107?category=959177  

 

C++ 디자인 패턴 03. 관찰자 패턴, 옵저버 패턴, Observer Pattern

관찰자 패턴, 옵저버 패턴, Observer Pattern 객체 사이에 일 대 다의 의존 관계를 정의해두어, 어떤 객체의 상태가 변할 때 그 객체에 의존성을 가진 다른 객체들이 그 변화를 통지 받고 자동으로 업에이트될 수..

boycoding.tistory.com

관찰자 패턴은 이대로 사용하면 종속성 문제와 같은 문제들도 클 것 같다...

C++ 디자인 패턴 책에서 이러한 문제에 대해 다루었으니 책을 참고해서 추후에 코드를 수정해야겠다. 

 

전체 코드 :

더보기
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define MAX_OBSERVERS 10

enum State{
    IDLE, MOVE, GRAVITY};
enum Event{
    EVENT_START_FALL
};
enum Achivement{
    ACHIVEMENT_FELL_OF_BRIDGE
};

class Unit{
public:
    Unit(int x, int y) : x_(x), y_(y){}
    int x_, y_;
};

class Entity{
public:
    Entity(Unit* unit): unit(unit){}
    bool isOnSurface(){
        if(this->unit->y_==0)
            return true;
        else 
            return false;
    }
    void accelerate(State id){
        switch(id){
        case GRAVITY:
            unit->y_ -= 1;
        }
    }
    void update(){

    }
    bool isHero(){return true;}
private:
    Unit* unit;
};

class Observer{
public:
    virtual void onNotify(Entity& entity, Event event) = 0;
};

class Achivements : public Observer{
public:
    Achivements():heroIsOnBridge_{true}{}
    ~Achivements(){}
    void onNotify(Entity& entity, Event event) override{
        switch(event){
        case EVENT_START_FALL:
            if(entity.isHero() && heroIsOnBridge_)
                unlock(ACHIVEMENT_FELL_OF_BRIDGE);
            break;
        // 그 외 다른 이벤트를 처리하고..
        // heroIsOnBridge_ 값을 업데이트 한다. 
        default:
            break;
        }
    }
    
private:
    void unlock(Achivement achivement){
        // 아직 업적이 잠겨있다면 잠금해제한다.
        switch(achivement){
        case ACHIVEMENT_FELL_OF_BRIDGE:
            cout << "다리에서 떨어지는 업적 성공" << endl;
            break;
        default:
            break;
        }
    }
    bool heroIsOnBridge_;    
};

class Subject{
public: 
    void addObservers(Observer* observer){
        if(find(begin(observers_), end(observers_), observer) == end(observers_))
            observers_.push_back(observer); 
    } 
    void removeObservers(Observer* observer){
        if (observers_.empty()) return;
		for (auto it = observers_.begin(); it != observers_.end(); ++it){
			if (*it == observer){
				*it = nullptr; // 그냥 nullptr로 표시한다
			}
		}
    }
protected:
    void notify(Entity& entity, Event event){
        for(auto ob : observers_){
            ob->onNotify(entity, event);
        }
    }
private:
    vector<Observer*> observers_;
};

class Physics : public Subject{
public:
    void updateEntity(Entity& entity);
};

void Physics::updateEntity(Entity& entity){
    bool wasOnSurface = entity.isOnSurface();
    entity.accelerate(GRAVITY);
    entity.update();

    if(wasOnSurface && !entity.isOnSurface()){
        notify(entity, EVENT_START_FALL);
    }
}

int main(){
    Entity hero{new Unit(0,0)};
    
    Achivements cpfall;
    Physics heroPhy;
    heroPhy.addObservers(&cpfall);
    heroPhy.updateEntity(hero);
    return 0;
}

'Design Pattern > 게임 디자인패턴' 카테고리의 다른 글

2장. 명령 패턴  (0) 2020.05.07
6장. 싱글턴 패턴  (0) 2020.05.07
5장. 프로토타입 패턴  (0) 2020.04.27
11장. 바이트코드 패턴  (0) 2020.03.25
11장. 바이트코드(인터프리터 패턴)  (0) 2020.03.25