(Head First 设计模式)学习笔记(2) --观察者模式(气象站实例)

简介: 以下内容转载请注明来自"菩提树下的杨过(http://blog.sqlsky.com)" 应用概述: 某气象站通过传感器实时测量气温/湿度/压力等数据,要求设计一个系统,能让多种类型的公告栏自动更新这些数据(本例中有二类公告板:实时显示气温/温度公告板,动态统计最高/最低气温公告板) 解释: 应用观察者模式,把气温数据做为一个主题(也称为可观察者),让其它公告板当做观察者,通过订阅主题(也称通过观察"可观察者")来得知最新的信息(当然,观察者们也可以方便的退订,从而停止自动更新) 又一设计原则: 为了交互对象之间的松耦合设计而努力。

以下内容转载请注明来自"菩提树下的杨过(http://blog.sqlsky.com)"

应用概述:
某气象站通过传感器实时测量气温/湿度/压力等数据,要求设计一个系统,能让多种类型的公告栏自动更新这些数据(本例中有二类公告板:实时显示气温/温度公告板,动态统计最高/最低气温公告板)

解释:
应用观察者模式,把气温数据做为一个主题(也称为可观察者),让其它公告板当做观察者,通过订阅主题(也称通过观察"可观察者")来得知最新的信息(当然,观察者们也可以方便的退订,从而停止自动更新)

又一设计原则:
为了交互对象之间的松耦合设计而努力。


观察者接口
Code
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5
 6namespace WeatherForecast
 7{
 8    /**//// <summary>
 9    /// 观察者接口
10    /// </summary>

11    public interface Observer
12    {
13        void Update(float temperature,float humidity,float pressure);//用来更新各类公告板数据 
14    }

15}

公告板显示接口
Code
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5
 6namespace WeatherForecast
 7{
 8    /**//// <summary>
 9    /// 公告板"显示"功能接口
10    /// </summary>

11    interface DisplayElement
12    {
13        void Display();
14        
15    }

16}

主题接口
Code
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5
 6namespace WeatherForecast
 7{
 8    /**//// <summary>
 9    /// "主题"(也称为"被观察者")接口
10    /// </summary>

11    public interface Subject
12    {
13        void RegisterObserver(Observer o);
14        void RemoveObserver(Observer o);
15        void NotifyObservers();
16
17    }

18}

真正的气象数据"主题"
Code
 1using System;
 2using System.Collections.Generic;
 3using System.Collections;
 4using System.Linq;
 5using System.Text;
 6
 7namespace WeatherForecast
 8{
 9    /**//// <summary>
10    /// 实现"主题"接口的气象数据类
11    /// </summary>

12    public class WeatherData:Subject
13    {
14        private ArrayList observers;//订阅本主题的观察者列表
15        private float temperature;
16        private float humidity;
17        private float pressure;
18
19        public WeatherData() 
20        {
21            observers = new ArrayList();
22        }

23
24        /**//// <summary>
25        /// 注册观察者
26        /// </summary>
27        /// <param name="o"></param>

28        public void RegisterObserver(Observer o) 
29        {
30            observers.Add(o);
31        }

32
33        /**//// <summary>
34        /// 取消观察者
35        /// </summary>
36        /// <param name="o"></param>

37        public void RemoveObserver(Observer o) 
38        {
39            if (observers.Contains(o))
40            {
41                observers.Remove(o);
42            }

43        }

44
45        /**//// <summary>
46        /// 通知所有观察者
47        /// </summary>

48        public void NotifyObservers() 
49        {
50            for (int i = 0; i < observers.Count; i++)
51            {
52                (observers[i] as Observer).Update(temperature, humidity, pressure);
53            }

54        }

55
56        /**//// <summary>
57        /// 当数据变化时,该方法自动被调用(实际应用中由硬件自动控制)
58        /// </summary>

59        public void MeasurementsChanged() 
60        {
61            NotifyObservers();
62        }

63
64        /**//// <summary>
65        /// 设置气温/温度/压力(实际应用中,这些由数据探测器自动采集并自动设置)
66        /// </summary>
67        /// <param name="temperature"></param>
68        /// <param name="humidity"></param>
69        /// <param name="pressure"></param>

70        public void SetMeasurements(float temperature, float humidity, float pressure) 
71        {
72            this.temperature = temperature;
73            this.humidity = humidity;
74            this.pressure = pressure;
75            MeasurementsChanged();//因为测试环境中,没有硬件环境,只能手动模拟调用
76        }

77    }

78}

79

观察者之"实时气温/湿度公告板"
Code
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5
 6namespace WeatherForecast
 7{
 8    /**//// <summary>
 9    /// 实时气温/湿度公告板
10    /// </summary>

11    public class CurrentConditionDisplay:Observer,DisplayElement
12    {
13        private float temperature;
14        private float humidity;
15        private Subject weatherData;
16
17        public CurrentConditionDisplay(Subject weatherData) 
18        {
19            this.weatherData = weatherData;
20            weatherData.RegisterObserver(this);
21        }

22
23        public void Update(float temperature, float humidity, float pressure) 
24        {
25            this.temperature = temperature;
26            this.humidity = humidity;
27            Display();
28        }

29
30        public void Display() 
31        {
32            Console.WriteLine("当前:气温" + temperature + "度,湿度" + humidity + "%");
33        }

34    }

35}

36

观察者之"动态统计最高/最低气温公告板"
Code
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5
 6namespace WeatherForecast
 7{
 8    /**//// <summary>
 9    /// 动态统计最高/最低气温公告板
10    /// </summary>

11    public class StatisticDisplay:Observer,DisplayElement
12    {
13        private float temperature;
14        private float humidity;
15        private float maxTemperature;
16        private float minTemperature;
17        private Subject weatherData;
18
19        public StatisticDisplay(Subject weatherData) 
20        {
21            this.weatherData = weatherData;
22            weatherData.RegisterObserver(this);
23            //将下列变量初始化一个不可能达到的值
24            temperature = -99999;
25            maxTemperature = -99999;
26            minTemperature = 99999;
27        }

28
29        public void Update(float temperature, float humidity, float pressure) 
30        {
31            this.temperature = temperature;
32            this.humidity = humidity;
33                       
34            if (maxTemperature == -99999{ maxTemperature = temperature; }
35            if (minTemperature == 99999{ minTemperature = temperature; }            
36
37            maxTemperature = maxTemperature > temperature ? maxTemperature : temperature;
38            minTemperature = minTemperature > temperature ? temperature : minTemperature;
39
40            Display();
41        }

42
43        public void Display() 
44        {
45            Console.WriteLine("统计:最高气温 " + maxTemperature + "度 ,最低气温 " + minTemperature + "度\n");
46        }

47
48    }

49}


最终测试:
Code
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5
 6namespace WeatherForecast
 7{
 8    class Program
 9    {
10        static void Main(string[] args)
11        {
12            WeatherData weatherData = new WeatherData();
13
14            CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(weatherData);
15            StatisticDisplay statisticDisplay = new StatisticDisplay(weatherData);
16
17            weatherData.SetMeasurements(231520);
18            weatherData.SetMeasurements(281225);
19            weatherData.SetMeasurements(301423);
20            weatherData.SetMeasurements(252035);
21
22            weatherData.RemoveObserver(statisticDisplay);//取消"statisticDisplay"的主题订阅
23
24            weatherData.SetMeasurements(182233);
25
26            Console.Read();
27
28        }

29    }

30}

运行结果:
 
当前:气温23度,湿度15%
统计:最高气温 23度 ,最低气温 23度

当前:气温28度,湿度12%
统计:最高气温 28度 ,最低气温 23度

当前:气温30度,湿度14%
统计:最高气温 30度 ,最低气温 23度

当前:气温25度,湿度20%
统计:最高气温 30度 ,最低气温 23度

当前:气温18度,湿度22%

目录
相关文章
|
1月前
|
设计模式 监控 Java
Kotlin - 改良设计模式 - 观察者模式
Kotlin - 改良设计模式 - 观察者模式
51 3
|
1月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
|
20天前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
23天前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
36 1
|
1月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
28 3
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
36 9
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
35 2
|
2月前
|
设计模式 监控 UED
设计模式之观察者模式
【10月更文挑战第12天】 观察者模式是一种行为型设计模式,定义了一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动更新。主要由主题(被观察者)和观察者组成,实现对象间的松耦合,广泛应用于用户界面、事件驱动系统和数据监控等领域。
|
2月前
|
设计模式 Java Kotlin
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
30 2
|
2月前
|
设计模式 JavaScript Scala
Kotlin学习笔记 - 改良设计模式 - 责任链模式
Kotlin学习笔记 - 改良设计模式 - 责任链模式
45 0