今天回家做饭,时间就很紧张了,待会儿还要去洗澡,我有一个想法,就是买一个耳麦,这样在公司也能旁若无人的看书了,戴个耳机总是感觉不到那种隔离。
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 ListObserverList; private string temp; private string pressure; public WeatherData() { ObserverList = new List (); } 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数据,而不是被动的等待推送,这也是一个思路。