⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subjectobserver.h

📁 设计模式模板源码
💻 H
字号:
/////////////////////////////////////////////////////////////////////////////
// SubjectObserver.h : Subject/observer interfaces.
//

#ifndef _XP_SUBJECTOBSERVER_H__
#define _XP_SUBJECTOBSERVER_H__


#include <vector>
#include <list>

#include "..\GuidCast.h"
#include "..\RefCount.h"

#define XP_IMESSAGE_IID     \
{ 0x19f2eb66, 0x2df7, 0x443a, { 0xa9, 0x3c, 0xa2, 0x77, 0x73, 0xb5, 0xa3, 0xdf } };

#define XP_ISUBJECT_IID     \
{ 0x19f2eb67, 0x2df7, 0x443a, { 0xa9, 0x3c, 0xa2, 0x77, 0x73, 0xb5, 0xa3, 0xdf } };

#define XP_IOBSERVER_IID     \
{ 0x19f2eb68, 0x2df7, 0x443a, { 0xa9, 0x3c, 0xa2, 0x77, 0x73, 0xb5, 0xa3, 0xdf } };

class IObserver;

//@doc IMessage 
//@mfunc XPUint32  | IMessage | GetTypeID  | The type ID of the message.  Used for safe typecasting
//@xref <c IMessage>

//@doc IMessage 
//@mfunc void  | IMessage | Sprint | Print a description of the message for logging purposes
//@parm CString& | strCmd | A string to receive the message text
//@xref <c IMessage>

//@doc IMessage
//@class Message interface.  Classes which implement this interface can be sent from subject
// to observer as a notification of change.
class IMessage : public IQueryGuid, public IRefCount
{
public:
	//@cmember
	/* The type ID of the message.  Used for safe typecasting*/
	virtual XPUint32 GetTypeID() const = 0;

	XP_IMPL_IID(XP_IMESSAGE_IID)	
};

//@doc ISubject
//@mfunc void  | ISubject | AddObserver | Adds a observer to the list of dependents on this object.  When a change in state occurs, all observers are notified.
//@parm IObserver* | pObserver | The observer to add
//@xref <c ISubject>

//@doc ISubject
//@mfunc void  | ISubject | RemoveObserver | The dependent identified by the argument is removed from this objects list of dependents
//@parm IObserver* | pObserver | The observer to remove
//@xref <c ISubject>

//@doc ISubject
//@mfunc void  | ISubject | UpdateAllObservers | All objects dependent on this object are sent a notification indicating what aspect of this object has changed
//@parm IObserver* | pSender | The observer that triggered the update
//@parm IMessage* | pMsg | The message to send to all observers
//@xref <c ISubject>

//@doc ISubject
//@class ISubject is an interface that can be mixed into any object through
// multiple inheritance.  An object that incorporates this interface can
// be observed by any object that incorporates the IObserver interface.
// All observers of a subject are notified of changes to the subject
// state via a change notification protocol.  This notification can be
// any object whose class mixes in the IMessage interface.
//
// NOTE: the ISubject interface implements the subject part of the
// Observer design pattern.  See the book "Design Patterns: Elements of
// reusable Object-oriented software."
class ISubject : public IQueryGuid, public IRefCount
{
public:
	//@cmember
	/* Adds a observer to the list of dependents on this object.  When a change in state occurs, all observers are notified.*/
	virtual void AddObserver(IObserver* pObserver) = 0;

	//@cmember
	/* The dependent identified by the argument is removed from this objects list of dependents*/
	virtual void RemoveObserver(IObserver* pObserver) = 0;

	//@cmember
	/* All objects dependent on this object are sent a notification indicating what aspect of this object has changed*/
	virtual void UpdateAllObservers(IObserver* pSender, IMessage* pMsg) = 0;

	XP_IMPL_IID(XP_ISUBJECT_IID)
};


//@doc IObserver
//@mfunc void  | IObserver | OnUpdate | The function reacts to notifications of change on the subject it is observing
//@parm ISubject* | pSubject | The subject sending the update
//@parm IMessage* | pMsg | The message indicating what change has occurred
//@xref <c IObserver>

//@doc IObserver
//@class IObserver is an interface that can be mixed into any object through
// multiple inheritance.  An object that incorporates this interface can
// observe any object that incorporates the ISubject interface.
// All observers of a subject are notified of changes to the subject
// state via a change notification protocol.
//
// NOTE: the ISubject interface implements the subject part of the
// Observer design pattern.  See the book "Design Patterns: Elements of
// reusable Object-oriented software."
class IObserver : public IQueryGuid, public IRefCount
{
public:
	//@cmember
	/* The function reacts to notifications of change on the subject it is observing*/
	virtual void OnUpdate(ISubject* pSubject, IMessage* pMsg) = 0;

	XP_IMPL_IID(XP_IOBSERVER_IID)
};

typedef std::vector<IObserver*> ObserverVector;
typedef std::list<IObserver*> ObserverList;

//@doc ISubjectImpl
//@class The ISubjectImpl class provides a default implementation of the
// ISubject interface
class ISubjectImpl : public ISubject
{
// Constructors/destructor
public:
	virtual ~ISubjectImpl()
	{
		while (m_observers.size() > 0)
		{
			IObserver* pObserver = m_observers.back();
			pObserver->Release();
			m_observers.pop_back();
		}
	}

// Attributes
protected:
	ObserverVector m_observers;

// Operations
public:
	virtual void AddObserver(IObserver* pObserver)
	{
		if (pObserver != NULL) {
			pObserver->AddRef();
			m_observers.push_back(pObserver);
		}
	}

	virtual void RemoveObserver(IObserver* pObserver)
	{
		ObserverVector::iterator itObserver = m_observers.begin();
		while (itObserver != m_observers.end()) {
			if (pObserver == *itObserver) {
				(*itObserver)->Release();
				itObserver = m_observers.erase(itObserver);
			}
			else
			{
				itObserver++;
			}
		}
	}

	virtual void UpdateAllObservers(IObserver* pSender = NULL, IMessage* pMsg = NULL)
	{
		ObserverVector::iterator itObserver;

		for (itObserver = m_observers.begin(); itObserver != m_observers.end(); itObserver++) {
			if ((*itObserver) != pSender) {
				(*itObserver)->OnUpdate(this, pMsg);
			}
		}
	}

	BEGIN_GUID_MAP(ISubjectImpl)
		GUID_ENTRY(ISubject)
		GUID_ENTRY(IQueryGuid)
		GUID_ENTRY(IRefCount)
	END_GUID_MAP
};


#endif  // #ifndef _XP_SUBJECTOBSERVER_H__


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -