Observer模式

原创 2006年05月29日 17:26:00

Observer模式
观察者模式
观察/监视

软件设计的一个重要目标就是模块的高内聚,低耦合
代码设计的一个重要目标就是设计可重用的代码

在OO设计中,一个类往往包含一组成员函数和成员变量。成员变量记录类的状态,成员函数对外提供执行接口
有时候某些类的状态的改变依赖于另一个类的状态的改变

假设要设计这样一个应用:
存在类O,类C,类C的状态改变依赖类O的状态改变

一般的OO方法:
在类O中保存一个类C的指针,类O的状态改变通知类C改变状态。这样做是没有错误的
但是存在如下问题:如果我们又有一个类B,它的状态改变同样依赖类O的状态改变,OK,同理,我们在类O中同样保存一个类B的指针,O的状态改变的时候通知B改变自己的状态,如果又有了类,D,E,F……

随着依赖类的增加,类O要保存大量的类指针,O状态改变时要依次通知依赖它的每个类改变自己的状态,代码不够灵活,麻烦
更重要的是,它违背了我们一开始就提出的程序设计的一个重要的规则:高内聚,低耦合和设计可重用的代码
因为类O保存了类B,C,D,E……的指针,所以,类O不能脱离这些依赖类单独实现,我们必须在类O实现的时候定义这些依赖类的头文件(高耦合,不可重用)

Observer模式解决了这一问题
观察者模式包含了三个协作类:
客户类:即依赖于被观察类状态而改变状态的类
监视类:负责监视被观察类的状态改变,通知客户类改变自己的状态。被监视类保存监视类的指针,监视类保存所有客户类的指针(用列表保存)
被监视类:它的状态改变影响客户类的状态

用下面的代码说明(注:代码来自CodeProject)

///////////////////////////////////////////////////
// 头文件
// .h
// File   : - ObserverPattern.h
// Author : - Nilesh K. Karkhanis
//

#include <list>

using namespace std;

/*==============================
*  观察者模式分析
*  被观察者 保存 一个 观察类的指针
*  观察类保存一个客户类的指针的列表数组
*  如果被观察类状态改变,将通知观察类
*  观察类依次通知客户类修改状态
================================*/
//////////////////////////////////////////////////////

// Client class who is interested in getting notification
// when the observerable changes
//
//
// 客户端,观察类监视被观察类的改变,修改客户端状态
//
class Client
{
public:
 Client() { cout << endl << "C'tor Client"; }
 ~Client() { cout << endl << "D'tor Client "; }
 void Update() { cout << "Update" << endl; }
};

//////////////////////////////////////////////////////
// Observer class which monitors the changes of observerable
// and notifies the client of any change
//
//
// 观察者,观察被观察类的改变
//
class Observer
{
public:
 Observer() { cout << endl << "C'tor Observer ";myClient.erase(myClient.begin(), myClient.end()); }
 ~Observer();
 bool Attach(Client* );
 bool Detach(Client* );
 void Notify( );

private:

 list<Client*> myClient;
};

//////////////////////////////////////////////////////
// Class that is to be observered
//
//
// 被观察者
//
class Observerable
{
public:
 Observerable() { cout << endl << "C'tor Observerable "; myObserver = NULL; }
 ~Observerable() {cout << endl << "D'tor Observerable "; }

 bool SetObserver(Observer* apObserver )
 {
  if ( !apObserver )
   return false;

  myObserver = apObserver;

  return true;
 }

 void StateChanged( )
 {
  cout << endl << "State Changed";
  myObserver->Notify();
 }

private:
 Observer* myObserver;
};

 

// 实现文件
//.cpp

///////////////////////////////////////////////////
// File   : - ObserverPattern.cpp
// Author : - Nilesh K. Karkhanis
//
/*==============================
*  观察者模式分析
================================*/

#include <stdio.h>
#include <iostream.h>

#include "ObserverPattern.h"


//////////////////////////////////////////////////////
// Does the client cleanup while getting destoryed
//
Observer::~Observer()
{
 cout << endl << "D'tor Observer ";

 list<Client*>::iterator aIterator;

 for ( aIterator = myClient.begin(); aIterator != myClient.end(); aIterator++ )
 {
  if ( *aIterator)
  {
   delete *aIterator;
   *aIterator = NULL;
  }
 }

 myClient.erase(myClient.begin(), myClient.end());

}

//////////////////////////////////////////////////////
// Adds the client to the list of clients
//
bool Observer::Attach(Client* apListner )
{
 if ( !apListner )
  return false;

 myClient.push_front ( apListner );

 return true;
}

//////////////////////////////////////////////////////
// Removes the client from the list
//
bool Observer::Detach(Client* apListner )
{
 if ( !apListner )
  return false;

 list<Client*>::iterator aIterator;

 for ( aIterator = myClient.begin(); aIterator != myClient.end(); aIterator++ )
 {
  if ( *aIterator == apListner )
  {
   delete *aIterator;
   *aIterator = NULL;
  }
 }

 return true;
}

//////////////////////////////////////////////////////
// Updates the clients when notified
//
void Observer::Notify( )
{
 list<Client*>::iterator aIterator;

 for ( aIterator = myClient.begin(); aIterator != myClient.end(); aIterator++ )
 {
  if ( *aIterator)
  {
   (*aIterator)->Update();
  }
 }
}

int main()
{
 Observer* myObserver = new Observer();
 Observerable* myObserverable = new Observerable();


 // set the observer in the observerable class
 // which allows to notiy the clients whenever there
 // is any change in the observerable class
 if ( !myObserverable->SetObserver( myObserver ) )
 {
  cout << "Could not set the observer" << endl;
  return 1;
 }

 // Attach the clients to the observers

 for ( int i = 0; i<= 5; i++ )
 {
  Client* aClient = new Client();
  if ( !myObserver->Attach(aClient) )
  {
   cout << "Could not attach" << endl;
   return 1;
  }
 }

 // change the state
 myObserverable->StateChanged();

 delete myObserverable;
 delete myObserver;

 return 0;
}

Observer模式的应用

  • 2017年12月03日 16:10
  • 134KB
  • 下载

Observer设计模式

  • 2015年05月20日 16:50
  • 3KB
  • 下载

观察者模式(observer)之委托(delegate) c#简单例子

观察者模式(observer)之委托(delegate) c#简单例子 几个要点:模式使目标与观察都之间的依赖关系达到松耦合、通知会自动传播 例子:玩家击中敌人后发生一系列变化:发后爆炸、敌人少1个....

Observer观察者模式

  • 2012年09月20日 16:36
  • 6KB
  • 下载

C#,由委托到Observer设计模式,再到事件机制

原文章:传送      1. 什么是委托? 处理诸如int,bool等基本数据类型,它们是数据的类型。委托,是方法的类型。 如 int a; //a可以是1,2,3,4,5.......

Observer设计模式

  • 2014年01月06日 14:31
  • 134KB
  • 下载

observer观察者模式

  • 2017年01月19日 11:50
  • 1.17MB
  • 下载

Android之观察者/被观察者模式Observer/Observable

Android之观察者Observer初探 文章链接: 知识点: 1、Android观察者模式的简介; 2、Observer和Observable的使用实例; 3、(abstract)抽象类和抽象方法...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Observer模式
举报原因:
原因补充:

(最多只允许输入30个字)