读书人

《Head.First设计方式》的学习笔记(3

发布时间: 2012-09-22 21:54:54 作者: rapoo

《Head.First设计模式》的学习笔记(3)--观察者模式

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

结构:

《Head.First设计方式》的学习笔记(3)--观察者模式

例子:

下面以模拟气象站系统来加以说明。

需求分析:

该系统的需求如下:

1、气象站能够追踪目前的天气状况,包括温度、湿度、气压、

2、气象站能够提供三种布告板,分别显示目前天气状况、气象统计和简单的预报。

3、布告板上的数据必须实时更新。

4、气象站必须提供一组API,供其他开发人员开发其他的布告板。

设计部分:

基于以上需求,该系统可以设计成3部分:气象站(获取实际气象数据的物理装置)、WeatherData对象(追踪来自气象站的数据,并更新布告板)和布告板(显示目前的天气状况给用户看)。效果图如下:

《Head.First设计方式》的学习笔记(3)--观察者模式

错误的类图设计(即没有学过设计模式时的第一感觉)可能如下:

《Head.First设计方式》的学习笔记(3)--观察者模式

相应的代码实现部分:

?1《Head.First设计方式》的学习笔记(3)--观察者模式public?void?MeasurementsChanged()
?2《Head.First设计方式》的学习笔记(3)--观察者模式????????{
?3《Head.First设计方式》的学习笔记(3)--观察者模式????????????temperature?=?this.GetTemperature();???//?获得温度
?4《Head.First设计方式》的学习笔记(3)--观察者模式????????????humidity?=?this.GetHumidity();?????????//?获得湿度
?5《Head.First设计方式》的学习笔记(3)--观察者模式????????????pressure?=?this.GetPressure();?????????//?获得气压?
?6《Head.First设计方式》的学习笔记(3)--观察者模式
?7《Head.First设计方式》的学习笔记(3)--观察者模式????????????MyCurrentConditionsDisplay.Update(temperature,?humidity,?pressure);?????//?更新目前天气状态板
?8《Head.First设计方式》的学习笔记(3)--观察者模式????????????MyStatisticsDisplay.Update(temperature,?humidity,?pressure);????????????//?更新气象统计板
?9《Head.First设计方式》的学习笔记(3)--观察者模式????????????MyForcastDisplay.Update(temperature,?humidity,?pressure);???????????????//?更新天气预报板????????????
10《Head.First设计方式》的学习笔记(3)--观察者模式????????}

这个类图设计的缺点:

1)、该设计是针对具体实现编程,而非针对接口。

2)、对于每个新的布告板,我们都得修改代码。

3)、我们无法在运动时动态得增加或删除布告板。

4)、我们尚未封装改变的部分。

那么如何改正这些缺点呢?

首先我们必须明白这些缺点的根源在哪里。很明显,我们在类图设计时依赖关系错了,应该依赖倒置。 CurrrentConditionsDisplay类、StatisticsDisplay类和ForcastDisplay类应该依赖 WeatherData类,而不是相反,这样就可以起到解耦的目的。

其次,CurrrentConditionsDisplay类、StatisticsDisplay类和ForcastDisplay类都有一个 Update()方法,因此应该提炼一个接口,这样可以实现“针对接口编程”,使代码更加灵活,也方便其他开发人员开发其他的布告板。

进一步思考:

1)、改正这些缺点后,我们的类图已经与观察者模式的结构有点类似了。

2)、我们的气象站系统的最大问题其实就是一对多的依赖引起的,而观察者模式正是解除一对多关系的不二法门,因此我们有必要采用观察者模式。

采用了观察者模式后设计的类图应该是这样:
《Head.First设计方式》的学习笔记(3)--观察者模式
WeatherDatea实现ISubject接口,CurrentConditionsDisplay、ForcastDisplay、 StatisticsDisplay实现IObserver接口,ISubject调用 IObserver,CurrentConditionsDisplay、ForcastDisplay、StatisticsDisplay调用 ISubject。

相应的代码实现部分:

?1《Head.First设计方式》的学习笔记(3)--观察者模式public?class?WeatherData?:?ISubject
?2《Head.First设计方式》的学习笔记(3)--观察者模式????{
?3《Head.First设计方式》的学习笔记(3)--观察者模式????????private?float?temperature;
?4《Head.First设计方式》的学习笔记(3)--观察者模式????????private?float?humidity;
?5《Head.First设计方式》的学习笔记(3)--观察者模式????????private?float?pressure;
?6《Head.First设计方式》的学习笔记(3)--观察者模式????????private?List<IObserver>?myList?=?new?List<IObserver>();
?7《Head.First设计方式》的学习笔记(3)--观察者模式
?8《Head.First设计方式》的学习笔记(3)--观察者模式????????public?void?SetWeatherData(float?paramTemp,?float?paramHumidity,?float?paramPressure)
?9《Head.First设计方式》的学习笔记(3)--观察者模式????????{
10《Head.First设计方式》的学习笔记(3)--观察者模式????????????this.temperature?=?paramTemp;
11《Head.First设计方式》的学习笔记(3)--观察者模式????????????this.humidity?=?paramHumidity;
12《Head.First设计方式》的学习笔记(3)--观察者模式????????????this.pressure?=?paramPressure;
13《Head.First设计方式》的学习笔记(3)--观察者模式????????????MeasurementsChanged();
14《Head.First设计方式》的学习笔记(3)--观察者模式????????}
15《Head.First设计方式》的学习笔记(3)--观察者模式
16《Head.First设计方式》的学习笔记(3)--观察者模式????????public?void?MeasurementsChanged()
17《Head.First设计方式》的学习笔记(3)--观察者模式????????{
18《Head.First设计方式》的学习笔记(3)--观察者模式????????????this.NotifyObservers();
19《Head.First设计方式》的学习笔记(3)--观察者模式????????}
20《Head.First设计方式》的学习笔记(3)--观察者模式???????
21《Head.First设计方式》的学习笔记(3)--观察者模式????????public?void?RegisterObserver(IObserver?paramIObserver)
22《Head.First设计方式》的学习笔记(3)--观察者模式????????{
23《Head.First设计方式》的学习笔记(3)--观察者模式????????????myList.Add(paramIObserver);
24《Head.First设计方式》的学习笔记(3)--观察者模式????????}
25《Head.First设计方式》的学习笔记(3)--观察者模式
26《Head.First设计方式》的学习笔记(3)--观察者模式????????public?void?RemoveObserver(IObserver?paramIObserver)
27《Head.First设计方式》的学习笔记(3)--观察者模式????????{
28《Head.First设计方式》的学习笔记(3)--观察者模式????????????myList.Remove(paramIObserver);
29《Head.First设计方式》的学习笔记(3)--观察者模式????????}
30《Head.First设计方式》的学习笔记(3)--观察者模式
31《Head.First设计方式》的学习笔记(3)--观察者模式????????public?void?NotifyObservers()
32《Head.First设计方式》的学习笔记(3)--观察者模式????????{
33《Head.First设计方式》的学习笔记(3)--观察者模式????????????foreach?(IObserver?observer?in?myList)
34《Head.First设计方式》的学习笔记(3)--观察者模式????????????{
35《Head.First设计方式》的学习笔记(3)--观察者模式????????????????observer.Update(temperature,?humidity,?pressure);
36《Head.First设计方式》的学习笔记(3)--观察者模式????????????}
37《Head.First设计方式》的学习笔记(3)--观察者模式????????}
38《Head.First设计方式》的学习笔记(3)--观察者模式????}

读书人网 >软件开发

热点推荐