티스토리 뷰

옵저버 패턴은 변화를 감지할 동작을 설정했을 때, 해당 동작이 이루어졌다는 것을 알려주는 이벤트 핸들러를 떠올리면 쉽게 이해가 될 것이다.

특정 객체에 변화가 있었는지 늘 검사하는 것 보다, 변화가 있었을 때만 그 변화를 통보 받는 것이 관리하기 쉽기 때문에 옵저버 패턴을 사용한다.

패턴 적용 전

class GameMonitor { public: GameMonitor(int nCurrentUserCount, int nRoomCount) : m_nCurrentUserCount(nCurrentUserCount) , m_nCurrentRoomCount(nRoomCount) { } void SetCurrentUserCount(int nCurrentUserCount) { m_nCurrentUserCount = nCurrentUserCount; } int GetCurrentUserCount() { return m_nCurrentUserCount; } void SetCurrentRoomCount(int nRoomCount) { m_nCurrentRoomCount = nRoomCount; } int GetCurrentRoomCount() { return m_nCurrentRoomCount; } private: int m_nCurrentUserCount; int m_nCurrentRoomCount; }; class UserManager { public: UserManager(int nCurrentUserCount) : m_nCurrentRoomCount(nCurrentUserCount) { } void ConnectUser() { m_nCurrentUserCount++; } void DisconnectUser() { m_nCurrentUserCount--; } void OnUpdate() //특정 주기마다 루프를 돌며 호출되는 함수 { //CGameMonitor클래스에SetCurrentUserCount를호출 } private: int m_nCurrentUserCount; }; class RoomManager { public: RoomManager(int nCurrentRoomCount) : m_nCurrentRoomCount(nCurrentRoomCount) { } void MakeRoom() { m_nCurrentRoomCount++; } void DestroyRoom() { m_nCurrentRoomCount--; } void OnUpdate() //특정 주기마다 루프를 돌며 호출되는 함수 { //CGameMonitor클래스에SetCurrentRoomCount를호출 } private: int m_nCurrentRoomCount; };


 패턴 적용 후


class IObserver
{
public:
	virtual void Display() = 0;
	virtual void OnUpdate() = 0;
};

class GameMonitor
{
	typedef boost::shared_ptr< IObserver > SHARED_PTR_OBSERVER;
	std::list < SHARED_PTR_OBSERVER > m_listObserver;
	int m_nCurrentUserCount;
	int m_nCurrentRoomCount;

public:
	GameMonitor(int nCurrentUserCount, int nRoomCount)
		: m_nCurrentUserCount(nCurrentUserCount)
		, m_nCurrentRoomCount(nRoomCount)
	{

	}

	void SetCurrentUserCount(int nCurrentUserCount)
	{
		m_nCurrentUserCount = nCurrentUserCount;
	}

	int GetCurrentUserCount()
	{
		return m_nCurrentUserCount;
	}

	void SetCurrentRoomCount(int nRoomCount)
	{
		m_nCurrentRoomCount = nRoomCount;
	}

	int GetCurrentRoomCount()
	{
		return m_nCurrentRoomCount;
	}
};

class UserManager : public IObserver
{
public:
	UserManager(int nCurrentUserCount)
		: m_nCurrentUserCount(nCurrentUserCount)
	{
	}

	void OnUpdate()
	{
		//변화가있었으므로, CGameMonitor클래스에SetCurrentUserCount를호출
	}

	void ConnectUser()
	{
		m_nCurrentUserCount++;
		OnUpdate();
	}

	void DisconnectUser()
	{
		m_nCurrentUserCount--;
		OnUpdate();
	}

private:
	int m_nCurrentUserCount;
};

class RoomManager : public IObserver
{
public:
	RoomManager(int nCurrentRoomCount)
		: m_nCurrentRoomCount(nCurrentRoomCount)
	{	
	}

	void OnUpdate()
	{
		//변화가있었으므로, CGameMonitor클래스에SetCurrentRoomCount를호출
	}

	void MakeRoom()
	{
		m_nCurrentRoomCount++;
		OnUpdate();
	}

	void DestroyRoom()
	{
		m_nCurrentRoomCount--;
		OnUpdate();
	}

private:
	int m_nCurrentRoomCount;
}; 


'Software Engineering > Design Pattern' 카테고리의 다른 글

컴포지트 패턴 (Composite)  (0) 2008.02.05
이터레이터 패턴 (Iterator)  (0) 2008.02.05
어댑터 패턴 (Adaptor)  (0) 2008.02.04
프로토타입 패턴 (Prototype)  (0) 2008.02.04
빌더 패턴 (Builder)  (2) 2008.02.03
댓글