今天回家做饭,时间就很紧张了,待会儿还要去洗澡,我有一个想法,就是买一个耳麦,这样在公司也能旁若无人的看书了,戴个耳机总是感觉不到那种隔离。
1.1 定义
观察者模式:
在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖他的对象都会受到通知,并且自动更新。
OO原则:
为交互对象之间的松耦合设计而努力。
ps:
大量的GUI框架都使用了这个设计模式。
2.1 需求
- 有一个WeatherData对象,是一个气象站提供的气象数据对象。里面包括温度属性,压力属性等等
- 需要对外展示几种不同的布告板,包括温度类的,压力类的等等。
- WeatherData更新后,需要及时更新布告,同时,布告版可以随时增加和取消,也可能在现有基础上添加新的布告板。
2.2 分析
1.这个模式所体现出的设计原则就是为了交互对象的松耦合而努力,最主要耦合的地方,就是WeatherData和观察者Obererve之间的耦合。
2.解决办法就是用接口,就是面向抽象编程而不是面对实现编程,把Subject主题和Observer都抽象为接口,使用通用的方法来进行注册,更新等等一致的行为。
3.这也是动态类型的一种思想吧,像什么比是什么好用
3.1实现
首先是接口的构造:
public interface IObserver
{
//主题为变量是方便观察者知道是哪个主题更新的他
void update(ISubject sub, string temp, string pressure);
}
public interface IDisplayElement
{
void display();
}
public interface ISubject
{
void registerObserver(IObserver observer);
void removeObserver(IObserver observer);
void notifyObserver();
}
显示功能和观察监视是两个功能,虽然在这个具体的业务场景里面他们是一同出现的,但是还是要用两个接口分别表示,不然无法复用,而且强耦合了。
然后就是Observer的具体类的实现:
public class Temperature : IObserver, IDisplayElement
{
private string temp;
private string pressure;
private WeatherData weatherData;
public Temperature(WeatherData w)
{
weatherData = w;
weatherData.registerObserver(this);
}
public void display()
{
Console.WriteLine(" i am temperatureObserver,now temp is {0} and pressure is {1}", temp, pressure);
}
public void update(ISubject sub, string temp, string pressure)
{
this.temp = temp;
this.pressure = pressure;
display();
}
}
这里就放了一个,其他的结构基本一致。
然后就是最复杂的WeatherData,Subject的具体实现
public class WeatherData : ISubject
{
private bool ischanged = false;
private List<IObserver> ObserverList;
private string temp;
private string pressure;
public WeatherData()
{
ObserverList = new List<IObserver>();
}
public void setMeasurement(string temp, string pressure)
{
this.temp = temp;
this.pressure = pressure;
this.changed();
}
private void setChanged()
{
ischanged = true;
}
public string getTemperature()
{
Random r = new Random();
return r.Next(0, 100) + "℃";
}
public string getPressure()
{
Random r = new Random();
return r.Next(0, 100) + "p";
}
public void changed()
{
setChanged();
notifyObserver();
}
public void notifyObserver()
{
if (ischanged == true)
{
foreach (var item in ObserverList)
{
item.update(this, this.temp, this.pressure);
}
}
ischanged = false;
}
public void registerObserver(IObserver observer)
{
if (ObserverList.IndexOf(observer) < 0)
{
ObserverList.Add(observer);
}
else
{
Console.WriteLine("不可以重复注册");
}
}
public void removeObserver(IObserver observer)
{
if (ObserverList.IndexOf(observer) >= 0)
{
ObserverList.Remove(observer);
}
}
}
其中ischanged 属性是后加上去的,为了框架可以更加灵活,比如WeatherData更新非常频繁,而布告板不需要如此频繁和精度的更新,我们就可以在ischanged 属性上做文章,把不需要更新情况过滤掉就可以了。
在Java的内置支持的观察者模式中,数据的更新其实有两种,一种是push推,一种是pull拉,就是Oberver对象自己去按需get数据,而不是被动的等待推送,这也是一个思路。