公司接到新任务,需要做一个气象监测应用。该应用将实现三个界面:当前气象状态,气象统计以及气象预报。应用从WeatherObject对象中获取所需数据:温度,湿度,气压。当然,为了可扩展性,该应用同时也要求提供api给其他开发者以便他们开发自己的气象面板。如下图

WeatherData中的方法,3个get方法将返回最新的测量数据,measurementsChanged在气象数据更新时被调用,该方法也是我们需要完成的。

现在我们开始来完成任务

第一次设计:先将三个参数由get方法获得,接着调用三个面板的update方法,并传入这三个参数

但在这个实现中,我们可以发现update可以被封装,且多个display违背了针对接口而不针对实现编程的原则

在这里,我们引入Observer模式,下图为总体设计

在这里,我们可以将Subject比喻为一家报社,Observer则是订阅报纸的人,人可以选择订阅或者取消订阅报纸,而报社则有义务随时将最新消息发送给订阅者。

我们首先定义了三个接口,分别是Subject(主题),Observer(观察者)和DisplayElement(显示)

具体看代码:

  1. public interface Subject {
  2. public void registerObserver(Observer o); //注册观察者
  3. public void removeObserve(Observer o); //删除观察者
  4. public void notifyObservers(); //更新观察者数据(即发送最新的报纸)
  5. }
  1. public interface Observer {
  2. public void update(float temp, float humidity, float pressure);
  3. }
  1. public interface DisplayElement {
  2. public void display();
  3. }

这样,我们就将update和display独立为接口了

接着,我们实现Subject(主题),或者说实现报社的功能,将订阅者作为list,新增删除就用list的方法,而通知就用for循环,将最新信息发送给所有订阅者,

  1. public class WeatherData implements Subject {
  2. private ArrayList observers;
  3. private float temperature;
  4. private float humidity;
  5. private float pressure;
  6.  
  7. public WeatherData() {
  8. // TODO Auto-generated constructor stub
  9. observers = new ArrayList();
  10. }
  11.  
  12. @Override
  13. public void registerObserver(Observer o) {
  14. // TODO Auto-generated method stub
  15. observers.add(o);
  16. }
  17.  
  18. @Override
  19. public void removeObserve(Observer o) {
  20. // TODO Auto-generated method stub
  21. int i = observers.indexOf(o);
  22. if(i >= 0) {
  23. observers.remove(i);
  24. }
  25. }
  26.  
  27. @Override
  28. public void notifyObservers() {
  29. // TODO Auto-generated method stub
  30. for(int i = 0; i < observers.size(); i ++) {
  31. Observer observer = (Observer)observers.get(i);
  32. observer.update(temperature, humidity, pressure);
  33. }
  34. }
  35.  
  36. public void measurementsChanged() {
  37. notifyObservers();
  38. }
  39.  
  40. public void setMeasurements(float temperature, float humidity, float pressure) {
  41. this.temperature = temperature;
  42. this.humidity = humidity;
  43. this.pressure = pressure;
  44. measurementsChanged();
  45. }
  46.  
  47. }

接着实现一名订阅者,订阅者实现update和display方法,并且在构造函数中注册成为一名观察者

  1. public class CurrentConditionsDisplay implements Observer, DisplayElement {
  2.  
  3. private float temperature;
  4. private float humidity;
  5. private Subject weatherData;
  6.  
  7. public CurrentConditionsDisplay(Subject weatherData) {
  8. // TODO Auto-generated constructor stub
  9. this.weatherData = weatherData;
  10. this.weatherData.registerObserver(this);
  11. }
  12.  
  13. @Override
  14. public void display() {
  15. // TODO Auto-generated method stub
  16. System.out.println("Current condition:" + temperature + "F degree and " + humidity + "% humidity");
  17. }
  18.  
  19. @Override
  20. public void update(float temp, float humidity, float pressure) {
  21. // TODO Auto-generated method stub
  22. this.temperature = temp;
  23. this.humidity = humidity;
  24. display();
  25. }
  26.  
  27. }

最后,在main方法中,我们建了(实例化)一个报社,一个订阅者。并将报社作为参数传给订阅者。随后,报社便不停更新数据,而订阅者也会不停接收最新的信息。

  1. public class WeatherStation {
  2.  
  3. public static void main(String[] args) {
  4. // TODO Auto-generated method stub
  5. WeatherData weatherData = new WeatherData();
  6. CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
  7. weatherData.setMeasurements(80, 65, 3.4F);
  8. weatherData.setMeasurements(82, 70, 3.5F);
  9. weatherData.setMeasurements(78, 90, 3.6F);
  10. }
  11.  
  12. }

JDK使用最多的模式之一--观察者模式的更多相关文章

  1. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(5):责任链模式、观察者模式

    一.责任链模式.观察者模式 1.责任链模式:当一个对象在一条链上被多个拦截器处理(烂机器也可以选择不拦截处理它)时,我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景.   2. ...

  2. 大型Java进阶专题(八)设计模式之适配器模式、装饰者模式和观察者模式

    前言 ​ 今天开始我们专题的第八课了.本章节将介绍:三个设计模式,适配器模式.装饰者模式和观察者模式.通过学习适配器模式,可以优雅的解决代码功能的兼容问题.另外有重构需求的人群一定需要掌握装饰者模式. ...

  3. Delphi的基于接口(IInterface)的多播监听器模式(观察者模式 )

    本文来自:http://www.cnblogs.com/hezihang/p/6083555.html Delphi采用接口方式设计模块,可以降低模块之间的耦合,便于扩展和维护.本文提供一个实现基于接 ...

  4. EventBus事件总线框架(发布者/订阅者模式,观察者模式)

    一. android应用内消息传递的方式: 1. handler方式-----------------不同线程间传递消息. 2. Interface接口回调方式-------任意两个对象. 3. In ...

  5. 反应器模式 vs 观察者模式

    反应器模式(Reactor pattern)与观察者模式(Observer pattern) 反应器模式 是一种为处理服务请求并发提交到一个或者多个服务处理程序的事件设计模式.当请求抵达后,服务处理程 ...

  6. javascript中的发布订阅模式与观察者模式

    这里了解一下JavaScript中的发布订阅模式和观察者模式,观察者模式是24种基础设计模式之一. 设计模式的背景 设计模式并非是软件开发的专业术语,实际上设计模式最早诞生于建筑学. 设计模式的定义是 ...

  7. 浅谈vue响应式原理及发布订阅模式和观察者模式

    一.Vue响应式原理 首先要了解几个概念: 数据响应式:数据模型仅仅是普通的Javascript对象,而我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率. 双向绑定:数据改变,视图 ...

  8. 十一个行为模式之观察者模式(Observer Pattern)

    定义: 定义对象之间一种一对多的关系,当被观察者状态变化时,可以自动地通知观察者并执行相关的业务操作.观察者模式又被称为发布-订阅模式等. 结构图: Subject:抽象主题类,定义了所有被观察类的通 ...

  9. Java设计模式补充:回调模式、事件监听器模式、观察者模式(转)

    一.回调函数 为什么首先会讲回调函数呢?因为这个是理解监听器.观察者模式的关键. 什么是回调函数 所谓的回调,用于回调的函数. 回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数. ...

随机推荐

  1. ES6的相关新属性

    ES6  引入了类这个概念. 1.class……extends es6中的class与es5 中的function差不多: class Student extends People , student ...

  2. POJ1459 Power Network —— 最大流

    题目链接:https://vjudge.net/problem/POJ-1459 Power Network Time Limit: 2000MS   Memory Limit: 32768K Tot ...

  3. 软件安全测试新武器 ——浅谈基于Dynamic Taint Propagation的测试技术

    软件安全测试是保证软件能够安全使用的最主要的手段,如何进行高效的安全测试成为业界关注的话题.多年的安全测试经验告诉我们,做好软件安全测试的必要条件是:一是充分了解软件安全漏洞,二是拥有高效的软件安全测 ...

  4. tuple built-in function

    tuple tips: 1.对于Python中的tuple类型来说,他与其它的序列类型来讲最大的不同就是tuple是不可变的. 2.当你需要创建一个只有一个元素的tuple时,需要在元祖分隔符里面加一 ...

  5. IOS中延时执行方式

    本文列举了四种延时执行某函数的方法及其一些区别.假如延时1秒时间执行下面的方法. - (void)delayMethod { NSLog(@"execute"); } 1.perf ...

  6. HDU4188:RealPhobia (连分数的运用之一)

    Bert is a programmer with a real fear of floating point arithmetic. Bert has quite successfully used ...

  7. WC2017游记

    Day0 到杭州之后出了点锅换了辆车,等了好久才开= =到宿舍发现路由器就在房门口,稳啊,过了一会儿就连不上了= =而且只有门口那个连不上,可以连上楼下的= =之后干了啥也忘了…… Day1 上午直接 ...

  8. MongoDb复制集实现故障转移,读写分离

    前言 数据库技术是信息系统的一个核心技术,发展很快,各种功能类型数据库层出不穷,之前工作中使用过关系型数据库(mysql.oracle等).面相对象数据库(db4o).key-value存储(Memc ...

  9. iOS多线程GCD的简单使用

    在iOS开发中,苹果提供了三种多线程技术,分别是: (1)NSThread (2)NSOperation (3)GCD 简单介绍一下GCD的使用. GCD全称 Grand Central Dispat ...

  10. Drools6:规则互斥

    在Drools中,有的时候会出现一种情况,一个事实Fact,满足了两个规则. 比如Fact的POJO是下面的 public class Message { public static final in ...