📄 subjectobserver.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 + -