1、气象监测应用,错误示范

有一个气象站,分别有三个装置:温度感应装置,湿度感应装置,气压感应装置。WeathData对象跟踪气象站数据,WeathData有MeasurmentsChanged()方法,当感应装置数据变化后就会调用MeasurmentsChanged。目前需求是要三个布告板,分别是气象数据状况(CurrentConditionDisply),气象统计(StaisticsDisply),天气预报(ForcastDisply)用来显示各种的数据。按照这个需求我们可以设计出如下方式

public class WeatherData(){
    private float Temperature{get;set;}
    private float Humidity{get;set;}
    private float Pressure{get;set;}

    public void MeasurmentsChanged(){
        CurrentConditionDisply.Update(Temperature,Humidity,Pressure);
        StaisticsDisply.Update(Temperature,Humidity,Pressure);
        ForcastDisply.Update(Temperature,Humidity,Pressure);
    }
}

public class CurrentConditionDisply{
    public void Update(float temperature,float humidity,float Pressure){
        //更新公布数据
    }
}
public class StaisticsDisply{
    public void Update(float temperature,float humidity,float Pressure){
        //更新统计数据
    }
}
public class ForcastDisply{
    public void Update(float temperature,float humidity,float Pressure){
        //更新天气预报
    }
}

按照如上设计也能实现目前需求,但是如果新加入一种布告板或者删除一个布告板,那么我们需要去求改MeasurmentsChanged方法。

此例子带来的问题:

1、我们是针对实现编程,而非争对接口。

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

3、无法在运行是动态地增加或者删除布告板。

4、未封装改变的部分,违反了对修改关闭,对扩展开放。

2、使用观察者模式解耦

观察者模式:定义了对象之间的一对多依赖,当一个对象改变时,他的所有依赖都会收到通知并自动更新。

订阅报纸就是典型的观察者模式,出版社即为主题(subject),订阅者即是观察者(observer),当有新报纸时,报社就会派人送新报纸到订阅了该报纸的读者手上。这里先给出订阅模式类图,然后我们再对之前的气象站进行观察者模式封装。

3、利用观察者模式改进气象站

按照观察者模式进行设计和改进气象站代码并测试

    /// <summary>
    /// 主题
    /// </summary>
    public interface Subject
    {
        public void RegisterObserver(Observer o);
        public void RemoveObserver(Observer o);
        public void NotifyObserver();
    }
    /// <summary>
    /// 具体主题(气象站)
    /// </summary>
    public class WeatherData : Subject
    {
        private List<Observer> observers;
        private float Temperature { get; set; }
        private float Humidity { get; set; }
        private float Pressure { get; set; }

        public WeatherData()
        {
            observers = new List<Observer>();
        }
        public void RegisterObserver(Observer o)
        {
            observers.Add(o);
        }

        public void RemoveObserver(Observer o)
        {
            observers.Remove(o);
        }

        //通知观察者
        public void NotifyObserver()
        {
            foreach (var o in observers)
            {
                o.Update(Temperature, Humidity, Pressure);
            }
        }

        public void MeasurmentsChanged()
        {
            NotifyObserver();
        }

        //数据变化
        public void SetMeasurments(float temperature, float humidity, float pressure)
        {
            Temperature = temperature;
            Humidity = humidity;
            Pressure = pressure;
            MeasurmentsChanged();
        }
    }

    /// <summary>
    /// 订阅者
    /// </summary>
    public interface Observer
    {
        void Update(float temperature, float humidity, float pressure);
    }

    public class CurrentConditionDisply : Observer
    {
        private Subject weatherData;
        public CurrentConditionDisply(Subject weatherData)
        {
            this.weatherData = weatherData;
            weatherData.RegisterObserver(this);
        }
        public void Update(float temperature, float humidity, float pressure)
        {
            Console.WriteLine($"当前情况布告板:{temperature},{humidity},{pressure}");
        }
    }
    public class StaisticsDisply : Observer
    {
        private Subject weatherData;
        public StaisticsDisply(Subject weatherData)
        {
            this.weatherData = weatherData;
            weatherData.RegisterObserver(this);
        }
        public void Update(float temperature, float humidity, float pressure)
        {
            Console.WriteLine($"统计数据布告板:{temperature},{humidity},{pressure}");
        }
    }
    public class ForcastDisply : Observer
    {
        private Subject weatherData;
        public ForcastDisply(Subject weatherData)
        {
            this.weatherData = weatherData;
            weatherData.RegisterObserver(this);
        }
        public void Update(float temperature, float humidity, float pressure)
        {
            Console.WriteLine($"天气预报布告板:{temperature},{humidity},{pressure}");
        }
    }

测试结果:

Head First设计模式——观察者模式的更多相关文章

  1. 18. 星际争霸之php设计模式--观察者模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  2. linkin大话设计模式--观察者模式

    linkin大话设计模式--观察者模式 观察者模式定义了对象间的一对多依赖关系,让一个或者多个观察者观察一个对象主题.当主题对象的状态发生改变的时候,系统能通知所有的依赖于此对象的观察者对象,从而能自 ...

  3. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  4. js设计模式-观察者模式

    定义: 观察者模式又叫发布订阅模式,它定义了对象间的一种一对多的依赖关系.观察者模式让两个对象松耦合地联系在一起,虽然不太清楚彼此的细节,但这不影响他们之间的互相通信. 思路 定义一个对象,在对象中实 ...

  5. 【设计模式】Java设计模式 - 观察者模式

    [设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...

  6. [Head First设计模式]山西面馆中的设计模式——观察者模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 引言 不知不自觉又将设计模式融入生活了,吃个饭也不得安生,也发现生活中的很多场景,都可以用设计模式来模拟.原来设计模式就在 ...

  7. javascript 设计模式-----观察者模式

    观察者模式在设计模式中被重点提到,因为它应用的场景非常多,而且在模块化设计当中扮演着非常重要的角色.MVC模式中最底层的就是观察者模式,当下流行的javascript框架backbone就是很好地运用 ...

  8. c#设计模式-观察者模式

    Observer 与 Subject 互为耦合,但是这种耦合的双方都依赖于抽象,而不依赖于具体. 一.观察者模式 目的 我们都知道解决一个问题有N种解决方式,但在面向对象的设计中如何能做到“高内聚,低 ...

  9. JAVA 设计模式 观察者模式

    用途 观察者模式 (Observer) 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观 ...

  10. IOS设计模式-观察者模式

    前言:23种软件设计模式中的观察者模式,也是在软件开发中,挺常用的一种设计模式.而在苹果开发中,苹果Cocoa框架已经给我们实现了这个设 计模式,那就是通知和KVO(Key-Value Observi ...

随机推荐

  1. 完整剖析SpringAOP的自调用

    摘要 spring全家桶帮助java web开发者节省了很多开发量,提升了效率.但是因为屏蔽了很多细节,导致很多开发者只知其然,不知其所以然,本文就是分析下使用spring的一些注解,不能够自调用的问 ...

  2. Unity3D_08_XML文件创建,读取,修改,添加

    今天在工作之余学习了一下关于Unity中关于XML的部分. 在这里要注意添加两个命名空间,如下: 一.xml的解析 首先新建一个xml,可以命名为item.xml,拖进assets里面,内容如下: & ...

  3. Java web 修改默认web部署路径

    转载自:https://blog.csdn.net/lcczpp/article/details/79968070 在eclipse上面部署web项目后,它没有将你的项目文件放到tomcat 的目录下 ...

  4. java获取电脑mac物理地址

    import java.net.InetAddress;import java.net.NetworkInterface;import java.net.SocketException;import ...

  5. java必学技能

    一:系统架构师是一个最终确认和评估系统需求,给出开发规范,搭建系统实现的核心构架,并澄清技术细节.扫清主要难点的技术人员.主要着眼于系统的“技术实现”.因此他/她应该是特定的开发平台.语言.工具的大师 ...

  6. JS 防抖和节流

    防抖和节流 在处理高频事件,类似于window的resize或者scorll,或者input输入校验等操作时.如果直接执行事件处理器,会增大浏览器的负担,严重的直接卡死,用户体验非常不好. 面对这种情 ...

  7. 论文阅读 | DeepDrawing: A Deep Learning Approach to Graph Drawing

    作者:Yong Wang, Zhihua Jin, Qianwen Wang, Weiwei Cui, Tengfei Ma and Huamin Qu 本文发表于VIS2019, 来自于香港科技大学 ...

  8. 06 (OC)* iOS中UI类之间的继承关系

    iOS中UI类之间的继承关系 此图可以更好的让你去理解iOS中一些底层的关系.你能够了解以及理解UI类之间的继承关系,你会更加明白苹果有关于底层的东西,更有助于你的项目开发由它们的底层关系,就能更加容 ...

  9. HTML5实现首页动态视频背景

    话不多说,先看效果图: ​​​ 炫酷吗?你想实现这种动态视频作为背景的首页吗?来,一起来学习,本文将带你一起实现H5动态视频背景: 首先网上找一段清晰的视频下载下来,最好是MP4格式的: 下载好了之后 ...

  10. 对Servlet执行流程的初步认识

    这里我们以Post方式请求Serclet为例 1.找到 中的URL地址 Form表单的Post请求HelloServlet(Action="HelloServlet")发起时, A ...