[게임 프로그래밍 패턴] 3. 관찰자 패턴

WIGWAG·2023년 2월 14일

관찰자 패턴이란?

객체 사이에 일 대 다의 의존 관계를 정의해두어, 어떤 객체의 상태가 변할 때 그 객체에 의존성을 가진 다른 객체들이 그 변화를 통지 받고 자동으로 업데이트될 수 있게 만듭니다.(GoF의 디자인 패턴 382p)

서로 다른 클래스의 메서드라도 바인드되어 연쇄적으로 함수가 실행되도록 해준다.
알람메서드를 통해 다른 클래스에게 특정메서드가 실행되었다는 것을 알린다.


관찰자 패턴 예시 코드

#include <iostream>

using namespace std;

class C_Entity{
public:
	bool Is_Hero() const { return true; }
	bool Is_On_Surface() const { return true; }
	void Accelerate() {}
	void Update() {}
};

enum C_Event {
	EVENT_ENTITY_FELL,
	EVENT_START_FALL
};

enum C_Achievement {
	ACHIEVEMENT_FELL_OFF_BRIDGE
};

class C_Observer {
public:
	virtual ~C_Observer() {}
	virtual void On_Notify(const C_Entity& entity, C_Event event) = 0;
};

class C_Achievements : public C_Observer{
public:
	virtual void On_Notify(const C_Entity& entity, C_Event event) override {
		switch (event) {
		case EVENT_ENTITY_FELL:
			if (entity.Is_Hero() && hero_is_on_bridge_)
			{
				Unlock(ACHIEVEMENT_FELL_OFF_BRIDGE);
			}
			break;

			// 그외 다른 이벤트 처리
			//heroIsOnBridge_ 업데이트
		}
	}
private:
	void Unlock(C_Achievement achievement) {
		//업적 잠금해제
	}
	bool hero_is_on_bridge_;
};

//관찰 당하는 객체의 클래스
class C_Subject {
public:
	void Add_Observer(C_Observer* observer) {
		//배열에 추가
	}
	void Remove_Observer(C_Observer* observer) {
		//배열에서 제거
	}

protected:
	void Notify(const C_Entity& entity, C_Event event) {
		for (int i = 0; i < num_observers_; i++)
		{
			observers_[i]->On_Notify(entity, event);
		}
	}

private:
	static const int MAX_OBSERVERS = 10;
	C_Observer* observers_[MAX_OBSERVERS];
	int num_observers_;
};

class C_Physics : public C_Subject {
public:
	void Update_Entity(C_Entity& entity);
};

void C_Physics::Update_Entity(C_Entity& entity) {
	bool was_on_surface = entity.Is_On_Surface();
	entity.Accelerate();
	entity.Update();
	if (was_on_surface && !entity.Is_On_Surface()) {
		Notify(entity, EVENT_START_FALL);
	}
}

int main()
{
	C_Physics physics;
	C_Entity entity;
	physics.Update_Entity(entity);
}
profile
프로그래밍 공부 기록 노트

0개의 댓글