根据四人帮解释,观察者模式解决当某些其他对象改变状态时,如果一组对象要进行更新,那么将这两个对象分别封装在两个独立的对象中。
个人理解,在观察者模式中,最重要的要理解哪个对象是主动的,也就是事件源,那么观察者模式就很简单了。
以下是我实现侦听器模式,可以生成广播信息。
代码如下:
头文件如下:
/*! @file Liserner.h
\brief
文件功能: 侦听器模式 <br>
<br>
文件名称: Liserner.h <br>
模块名 : <br>
\author wenglj
\version 1.0.1
\remark <br>
修改记录 : <br>
日 期 版本 修改人 修改内容<br>
YYYY/MM/DD 1.0.0 <XXX> 创建 <br>
******************************************************************************** <br>
版权:浙江傲雪工作室 保留所有权利
*******************************************************************************/
#pragma once
#include <vector>
using std::vector;
/*! @class abstract Event
********************************************************************************
\brief
功能 : 事件<br>
类名称 : abstract Event
\exception
\author wenglj
\date 2006-9-23
\remark <br>
典型用法 :
******************************************************************************/
class Event
{
public:
enum
{
ADD,
DEL
}TYPE;
//
/*! @function public pure virtual OnAdd
********************************************************************************
\brief
功能 : 添加对象事件<br>
函数名 : OnAdd
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
virtual void OnAdd( void ) = 0;
//
/*! @function public pure virtual OnDel
********************************************************************************
\brief
功能 : 对象删除事件<br>
函数名 : OnDel
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
virtual void OnDel( void ) = 0;
}; // Event
/*! @class CDictograph
********************************************************************************
\brief
功能 : 侦听器,事件源<br>
类名称 : CDictograph
\exception
\author wenglj
\date 2006-9-23
\remark <br>
典型用法 :
******************************************************************************/
class CDictograph
{
public:
CDictograph(){};
~CDictograph(){};
public:
typedef vector<Event*> Liseners;
typedef vector<Event*>::iterator LisenersIteraor;
/*! @function public AddLisener
********************************************************************************
\brief
功能 : 添加侦听对象<br>
函数名 : AddLisener
@param pLisener Event * < 侦听对象 >
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void AddLisener( Event* pLisener );
/*! @function public DelLisener
********************************************************************************
\brief
功能 : 删除侦听对象<br>
函数名 : DelLisener
@param pLisener Event * < 侦听对象 >
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void DelLisener( Event* pLisener );
/*! @function public ToNotify
********************************************************************************
\brief
功能 : 通知侦听对象事件发生<br>
函数名 : ToNotify
@param nCode int < 事件类型 >
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void ToNotify( int nCode );
protected :
// 侦听对象集合
Liseners m_vtLiseners;
}; // CDictograph
/*! @class CLisener
********************************************************************************
\brief
功能 : 侦听实体, 事件的接受者<br>
类名称 : CLisener
\exception
\author wenglj
\date 2006-9-23
\remark <br>
典型用法 :
******************************************************************************/
class CLisener : public Event
{
public:
CLisener(void);
~CLisener(void);
public :
//
/*! @function public virtual OnAdd
********************************************************************************
\brief
功能 : 添加事件响应 <br>
函数名 :
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
virtual void OnAdd( void );
//
/*! @function public virtual OnDel
********************************************************************************
\brief
功能 : 删除事件响应<br>
函数名 :
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
virtual void OnDel( void );
}; //CLiserner
/*! @class CClient
********************************************************************************
\brief
功能 : 客户对象, 触发事件<br>
类名称 : CClient
\exception
\author wenglj
\date 2006-9-23
\remark <br>
典型用法 :
******************************************************************************/
class CClient
{
public :
typedef vector<int> Objects;
typedef vector<int>::iterator ObjectsIterator;
CClient();
~CClient();
public :
/*! @function public AddObject
********************************************************************************
\brief
功能 : 添加事件触发 <br>
函数名 :
@param i int < insert parameter description here>
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void AddObject( int i );
/*! @function public DelObject
********************************************************************************
\brief
功能 : 删除事件触发 <br>
函数名 :
@param i int < insert parameter description here>
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void DelObject( int i );
/*! @function public SetLiseners
********************************************************************************
\brief
功能 : 设置侦听器 <br>
函数名 :
@param pObject CDictograph * < insert parameter description here>
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void SetLiseners( CDictograph* pObject );
protected :
Objects m_vtObjects;
CDictograph* m_pDictograph;
}; // CClient
实现文件如下:
/*! @file Liserner.cpp
\brief
文件功能: 侦听器模式实现 <br>
<br>
文件名称: Liserner.cpp <br>
模块名 : <br>
\author wenglj
\version
\remark <br>
修改记录 : <br>
日 期 版本 修改人 修改内容<br>
YYYY/MM/DD 1.0.0 <XXX> 创建 <br>
******************************************************************************** <br>
版权:浙江傲雪工作室 保留所有权利
*******************************************************************************/
#include "StdAfx.h"
#include ".\liserner.h"
#include <algorithm>
/*! @function public AddLisener
********************************************************************************
\brief
功能 : 添加侦听对象 <br>
函数名 :
@param pLisener Event * < insert parameter description here>
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void CDictograph::AddLisener( Event* pLisener )
{
m_vtLiseners.push_back( pLisener );
std::cout<<"Add Lisener Object"<<std::endl;
}
/*! @function public DelLisener
********************************************************************************
\brief
功能 : 删除侦听对象 <br>
函数名 :
@param pLisener Event * < insert parameter description here>
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void CDictograph::DelLisener( Event* pLisener )
{
LisenersIteraor it;
it = std::find( m_vtLiseners.begin(), m_vtLiseners.end(), pLisener );
if ( it != m_vtLiseners.end() )
m_vtLiseners.erase( it );
std::cout<<"Delete Lisener Object"<<std::endl;
}
/*! @function public ToNotify
********************************************************************************
\brief
功能 : 通知侦听对象 <br>
函数名 :
@param nCode int < insert parameter description here>
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void CDictograph::ToNotify( int nCode )
{
std::cout<<"ToNotify Event"<<std::endl;
for( LisenersIteraor it = m_vtLiseners.begin(); it != m_vtLiseners.end(); ++it )
{
Event* p = *it;
switch( nCode )
{
case Event::ADD:
p->OnAdd();
break;
case Event::DEL:
p->OnDel();
break;
default:
break;
}
}
}
CLisener::CLisener(void)
{
}
CLisener::~CLisener(void)
{
}
/*! @function public virtual OnAdd
********************************************************************************
\brief
功能 : 添加事件响应 <br>
函数名 :
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void CLisener::OnAdd()
{
std::cout<<"Add Object Event "<<std::endl;
}
/*! @function public virtual OnDel
********************************************************************************
\brief
功能 : 删除事件响应 <br>
函数名 :
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void CLisener::OnDel()
{
std::cout<<"Del Object Event"<<std::endl;
}
CClient::CClient()
: m_pDictograph( NULL )
{
}
CClient::~CClient()
{
}
/*! @function public AddObject
********************************************************************************
\brief
功能 : 触发添加事件 <br>
函数名 :
@param i int < insert parameter description here>
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void CClient::AddObject( int i )
{
m_vtObjects.push_back( i );
std::cout<<"CClient Object AddObject"<<std::endl;
m_pDictograph->ToNotify( Event::ADD );
}
/*! @function public DelObject
********************************************************************************
\brief
功能 : 触发删除事件 <br>
函数名 :
@param i int < insert parameter description here>
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void CClient::DelObject( int i )
{
ObjectsIterator it;
it = std::find( m_vtObjects.begin(), m_vtObjects.end(), i );
if ( it != m_vtObjects.end() )
{
m_vtObjects.erase( it );
std::cout<<"CClient Object DelObject"<<std::endl;
m_pDictograph->ToNotify( Event::DEL );
}
}
/*! @function public SetLiseners
********************************************************************************
\brief
功能 : 设置侦听器对象 <br>
函数名 :
@param pObject CDictograph * < insert parameter description here>
\return void <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
void CClient::SetLiseners( CDictograph* pObject )
{
m_pDictograph = pObject;
}
主程序如下:
// DictaphonePattern.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Liserner.h"
/*! @function global _tmain
********************************************************************************
\brief
功能 : 主程序 <br>
函数名 :
@param argc int < insert parameter description here>
@param argv _TCHAR *[] < insert parameter description here>
\return int <insert return value description here>
\exception
\author wenglj
\remark <br>
典型用法: <br>
复杂度 :
*******************************************************************************/
int _tmain(int argc, _TCHAR* argv[])
{
CClient clientObject;
CDictograph liseners;
CLisener lisener;
liseners.AddLisener( &lisener );
clientObject.SetLiseners( &liseners ) ;
clientObject.AddObject( 1 );
clientObject.AddObject( 2 );
clientObject.AddObject( 3 );
clientObject.AddObject( 4 );
clientObject.AddObject( 5 );
clientObject.DelObject( 3 );
return 0;
}
具体的函数实现解释都有注释了。