반응형

감시자 패턴은, 서로 의존되어 있는 다수의 개체에서 하나의 개체의 상태가 바뀜에 따라 나머지 개체에 변화를 알려주는 패턴이다.


감시자 패턴은 주제 개체에 등록하여 변화를 주고, 받기 때문에 느슨한 결합으로 연결된 패턴이다.


때문에 개체를 추가하고 삭제하는 데에 유연성이 높으며, 각 각의 개체 또한 독립적이다.


감시자 패턴은 두 가지 개체로 구성되어 있다.


변화를 알려주는 개체는 주제 개체 (Subject)

변화를 받는 개체는 구독 개체 (Observer)


주제 개체는 변화를 알려주기 위하여 구독 개체들을 가지고 있다.

구독 개체는 변화를 받기 위해서 자신의 정보를 가진 주제 개체를 가지고 있다.


주제 개체는 구독 개체를 이루는 , 구독 개체개인으로 알아두면 쉽게 이해할 수 있다.



아래의 예제는 보스의 등장 알람으로 주제 개체가 구독 개체들에게 상태 변화를 알려주는 것과, 구독 개체가 주제 개체로부터 상태를 요청하는 예제이다.


#pragma once
#include "Base.h"
class Observer
{
public:
virtual void Notify(string name) = 0;
};
class BossAlarm
{
vector<Observer*> players;
string name;
public:
BossAlarm(string name) : name(name) { }
void AddPlayer(Observer* player)
{
players.push_back(player);
}
void RemovePlayer(Observer* player)
{
vector<Observer*>::iterator seek = find(players.begin(), players.end(), player);
players.erase(seek);
}
void Notification()
{
vector<Observer*>::iterator seek = players.begin();
vector<Observer*>::iterator end = players.end();
while (seek != end)
{
(*seek)->Notify(name);
seek++;
}
}
void Notification(Observer* player)
{
if (isAppear)
{
player->Notify(name);
}
}
protected:
bool isAppear;
};
class BossDragon : public BossAlarm
{
public:
BossDragon() : BossAlarm("드래곤")
{
isAppear = false;
}
void SpawnBoss()
{
isAppear = true;
Notification();
}
};
class BossTwinHeadOrc : public BossAlarm
{
public:
BossTwinHeadOrc() : BossAlarm("트윈 헤드 오크")
{
isAppear = false;
}
void SpawnBoss()
{
isAppear = true;
Notification();
}
};
class Player : public Observer
{
string name;
BossAlarm* bossAlarm;
bool alarmState;
public:
Player(string name) : name(name) { }
void Notify(string name) override
{
if (alarmState)
{
cout << "# " << this->name.c_str() << "에게 알림 #" << endl;
cout << name.c_str() << " 보스 등장!" << endl << endl;
}
else
{
cout << "# " << this->name.c_str() << " 알람 해제 상태 #" << endl << endl;
}
}
void SetBossAlarm(BossAlarm* alarm, bool alarmOn = true)
{
bossAlarm = alarm;
alarmState = alarmOn;
bossAlarm->AddPlayer(this);
}
void GetBossState()
{
cout << "# " << name.c_str() << " 보스 알림 요청 #" << endl;
alarmState = true;
bossAlarm->Notification(this);
}
};
view raw [0]_Alarm.h hosted with ❤ by GitHub
#include "Alarm.h"
int main()
{
BossDragon* dragon = new BossDragon();
BossTwinHeadOrc* orc = new BossTwinHeadOrc();
Player* player1 = new Player("다루");
Player* player2 = new Player("까망");
Player* player3 = new Player("하양");
player1->SetBossAlarm(dragon);
player2->SetBossAlarm(orc, false);
player3->SetBossAlarm(orc);
dragon->SpawnBoss();
orc->SpawnBoss();
player2->GetBossState();
delete dragon;
delete orc;
delete player1;
delete player2;
delete player3;
}
view raw [1]_Main.cpp hosted with ❤ by GitHub
# 다루에게 알림 #
드래곤 보스 등장!
# 까망 알람 해제 상태 #
# 하양에게 알림 #
트윈 헤드 오크 보스 등장!
# 까망 보스 알림 요청 #
# 까망에게 알림 #
트윈 헤드 오크 보스
view raw [2]_Result hosted with ❤ by GitHub



반응형

+ Recent posts