您的位置:首页 > 其它

HeadFirst 设计模式-观察者模式

2014-02-19 19:19 417 查看
观察者模式
主要是定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。不用被动的实时去查询被主题的状态。交互对象之间是松耦合的。

这是一种主动将新消息通知。随后我们将看到由观察者自身判定是否需要最新的数据,主动的去获取通知。

具体的代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Observer
{

interface Observer
{
void update(float temperature, float humidity, float pressure);
}
interface Subject
{
void registObserver(Observer o);
void removeObserver(Observer o);
void notifyObserver();
}
interface DisplayElement
{
void dispaly();
}

class WeatherData : Subject
{
private System.Collections.ArrayList observers;//这种方式类必须管理一个数据结构,当信息发生改变,通知每一个观察者
//而这种行为应该独立出来,不是针对特殊的应用,在WeatherData中仅有自己的私有内部成员变量
private float temperature;
private float humidity;
private float pressure;
public WeatherData()
{
observers = new ArrayList();
}
public void registObserver(Observer o)//添加的对象是Observer
{
observers.Add(o);
}
public void removeObserver(Observer o)
{
int index = observers.IndexOf(o);
if (index >= 0)
{
observers.RemoveAt(index);
}
}

//通知所有的观察者
public void notifyObserver()
{
foreach (Object o in observers)
{
Observer observer = (Observer)o;
observer.update(temperature, humidity, pressure);
}
}
public void setMeasurements(float temperature, float humidity, float pressure)
{
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
notifyObserver();
}
}

//实现两个接口
class CurrentConditionsDisplay : Observer, DisplayElement
{
private float temperature;
private float humidity;
private float pressure;
private Subject subject;

public CurrentConditionsDisplay(Subject subject)//以Subject 作为参数,可为之后删除观察者提供对象
{
this.subject = subject;
subject.registObserver(this);
}
public void update(float temperature, float humidity, float pressure)
{
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
this.dispaly();

}
public void dispaly()
{
Console.WriteLine("Current conditions:" + temperature + " F degrees and " + humidity + " % humidity");
}
}

//但是上面的方法是不是没有问题了呢,有一个关键的是,观察者是被动的接受信息,如果观察者只是想知道一些想了解的信息???
//观察者模式的关键是每个观察者的内部都有一个更新函数。在主题对象中有一个列表控制着所有的观察者
//修改方式如下

}


//@Author tj
//@Date:2014-2-19
//@Observer Model

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Observer
{
class Program
{
static void Main(string[] args)
{
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentConditionDisplay = new CurrentConditionsDisplay(weatherData);
weatherData.setMeasurements(80, 90, 30.4f);

//以下使用接口
Console.WriteLine("using Observable");

WeatherData1 weatherData1 = new WeatherData1();
CurrentConditionsDisplay1 currentConditionDisplay1= new CurrentConditionsDisplay1(weatherData1);
weatherData1.setMeasurements(78, 80, 30.4f);
Console.ReadLine();
}
}

////////////////////////////////////////////////////////////////////////
class Observer1
{
public virtual void update(Observable obj, Object arg){}//实现多态的方式
}
class Observable
{
bool changed;
ArrayList observers;//对结构进行管理,可以独立于当前的天气预报的应用。
public Observable()
{
changed = false;
observers = new ArrayList();
}
public void addObserver(Observer1 o)
{
observers.Add(o);
}
public void deleteObservers(Observer1 o)
{
int index = observers.IndexOf(o);
if (index >= 0)
{
observers.RemoveAt(index);
}
}
public void notifyObservers(Object arg)
{
if (changed)
{
foreach(Object obj in observers)
{
Observer1 observer = (Observer1)obj;
observer.update(this, arg);
}
changed = false;
}
}
public void notifyObservers()
{
notifyObservers(null);
}
public void setChanged()
{
changed = true;
}

//为什么上面的不能采取这种方式呢,直接的在Subject中定义,因为我们要对观察者进行更新,更新的几个参数如何的能够显示在Subject中
//这个类很巧妙的将参数换做为Observable,WeatherData继承此,那么当调用update时实质是调用WeatherData1中的数据于观察者中
}
class WeatherData1 : Observable
{
private float temperature;
private float humidity;
private float pressure;

public WeatherData1() {}
public float getTemperature()
{
return temperature;
}
public float getHumidity()
{
return humidity;
}
public float getPressure()
{
return pressure;
}
public void setMeasurements(float temperature,float humidity,float pressure)
{
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public void measurementsChanged()//观察者可以通过在类里面调用此函数,再触发状态的改变。也就是观察者主动获取数据的过程
{
setChanged();
notifyObservers();
}
}
class CurrentConditionsDisplay1:Observer1
{
Observable observerable;//观察对象
private float temperature;
private float humidity;
public CurrentConditionsDisplay1(Observable observable)
{
this.observerable = observable;
observable.addObserver(this);//
}

public  override void update(Observable obj, Object arg)
{
if (obj is WeatherData1)
{
WeatherData1 weatherData = (WeatherData1)obj;
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
display();
}
}

public void display()
{
Console.WriteLine("new current conditions:" + temperature + " F degrees and " + humidity + "%humidity");
}
}
}

运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: