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 Pattern) 详解

观察者模式(Observer Pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权...
  • u012515223
  • u012515223
  • 2014年05月22日 14:37
  • 2983

设计模式----Observer模式

在以下任一情况下可以使用观察者模式: 1、当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中以使他们可以各自独立的改变和复用 2、当对一个对象的改变需要同时改变其他...
  • fly542
  • fly542
  • 2011年08月25日 00:00
  • 4701

使用js实现observer模式

在yui中,大量使用customEvent。何为customEvent,实际就是一个观察者observer。下面给出这个observer的实现html>    head>        meta ht...
  • kentchenj
  • kentchenj
  • 2007年01月19日 10:52
  • 1508

observer、listener模式的推与拉

导读: 1. observer模式简介 2. 两种实现方式:推与拉 observer模式简介 observer模型,又被称作listener模式。这里统一用observer来称呼。...
  • viewcode
  • viewcode
  • 2012年12月05日 17:47
  • 3992

javascript实现Observer模式来管理多个事件回调

《实战ajax》第四章介绍了这样的一个模型,与java中的事件处理模型相一致,观察者——监听者模式,感觉很酷:)。比如,我要对ID为mousemat的div标签的onclick事件增加两个事件writ...
  • killme2008
  • killme2008
  • 2006年07月28日 20:24
  • 1838

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

1. 什么是委托? 开始处理诸如int,bool等基本数据类型,它们是数据的类型。委托,是方法的类型。 如  int a; a可以是1,2,3,4,5......... 那么 delegate D; ...
  • u013781568
  • u013781568
  • 2014年03月01日 11:30
  • 998

MVC模型中的Observer模式

Symbian----MVC模型中的Observer模式------------------------------------------------------------------------...
  • luobonet
  • luobonet
  • 2008年01月14日 15:35
  • 351

观察者模式(Observer 模式)

一、 概述  观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(D...
  • l_lhc
  • l_lhc
  • 2016年02月25日 18:12
  • 559

Observer 模式及JAVA内置的observer示例

关于观察者模式 假设今天您设计一个图形分析算表程序,当中有一个资料物件,您可以用表格图形物件、柱状图形物件、圆饼图形物件等方式来 呈现物件,无论您是用哪种图形物件,重点是若资料物件的内容作了更改,则图...
  • hu1020935219
  • hu1020935219
  • 2014年09月22日 12:42
  • 2428

nodejs 设计思想杂记 三 observer模式

观察者模式:一个对象,当其状态改变时能够通知一系列的观察者。 EventEmitter 看图说话 使用方法: var EventEmitter = require('events').Event...
  • oZuoQi
  • oZuoQi
  • 2016年07月06日 12:55
  • 832
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Observer模式
举报原因:
原因补充:

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