/注:场景和例子引用github上的设计模式。传送门:https://github.com/iluwatar/java-design-patterns/tree/master/observer

场景:

一个天气预报系统,凡是订阅了改天气预报的,当天气发生改变的时候就把通知发送给所有订阅该天气预报的人。如兽人族(Orcs)和霍比特人(Hobitts)订阅了该天气预报系统,当天气从晴变成雨天的时候,兽人族和霍比特人就收到了天气变成雨天的通知。 如果还有其他订阅了该天气预报的如人族(Terran),只需要在WeatherObserver中加入该人族(Terran)订阅者,这样当天气发生改变的时候,人族也会收到天气通知。

意图:

定义对象间的一对多关系,当一个对象发生状态更改时,会自动通知并更新所有依赖者。

具体实现:

         订阅天气预报系统的即是观察者(如Orcs、Hobitts),把这些订阅天气预报的人抽象成接口(WeatherObserver),所有订阅该天气预报的人都得实现这个接口才行。另外在天气类(Weather)中也得开放一个接口让他们订阅,如使用List<Subscriber> observers 和写一个方法 addObserver(WeatherObserver obs)来让他们订阅,一旦天气发生变化就通知所有订阅该天气的方法 notifyAllObserver()。

talk is cheap,show me the code............................................................................................................................................................................................................................................................(分割线)

先定义天气类型(WeatherType.java),定义为枚举类型(sunny,rainny,windy,clod)

public enum WeatherType {SUNNY,WINDY,CLOD,RAINY;@Overridepublic String toString(){return this.name().toLowerCase();}
}

再将订阅者抽象成一个接口(WeatherObserver.java),所有订阅天气预报系统的必须实现这个接口。

public interface WeatherObserver {public void Upadate(WeatherType currentWeather);
}

天气类(Weather)负责定义数据结构来接收订阅者和通知更新订阅者天气变化。使用List<WeatherObserver>来接收订阅者,定义方法addObserver来接收新的订阅者和notifyAllObsever方法来更新订阅者天气状态。

import java.util.ArrayList;
import java.util.List;public class Weather {private WeatherType currentWeather;private List<WeatherObserver> observers;public Weather(){observers=new ArrayList<>();currentWeather=WeatherType.SUNNY;}public void addObservers(WeatherObserver observer){observers.add(observer);}public void removeObservers(WeatherObserver observer){observers.remove(observer);}public  void timePasses(){WeatherType[] enumValues=WeatherType.values();/* for(WeatherType type:enumValues){System.out.println(type);}*///改变天气,让天气的enum类型往后推一个currentWeather=enumValues[(currentWeather.ordinal() + 1) % enumValues.length];System.out.println("The weather change to  "+currentWeather);notifyAllObserver();}public void notifyAllObserver(){for(WeatherObserver obs: observers){obs.Upadate(currentWeather);}}
}

添加两个订阅天气预报的“人”,一个兽族(Orcs.java)一个霍比特人(Hobitts.java)。 如上面所说,要订阅该天气预报必须实现WeatherOberver接口。

public class Orcs implements WeatherObserver{@Overridepublic void Upadate(WeatherType currentWeather) {switch(currentWeather){case CLOD:System.out.println("The orcs are freezing cold");break;case SUNNY:System.out.println("The sun hurts the orcs' eyes.");break;case RAINY:System.out.println("The orcs are dripping wet.");break;case WINDY:System.out.println("The orc smell almost vanishes in the wind.");default:break;}        }public class Hobbits implements WeatherObserver{@Overridepublic void Upadate(WeatherType currentWeather) {switch(currentWeather){case CLOD:System.out.println("The Hobbits are freezing cold");break;case SUNNY:System.out.println("The sun hurts the Hobbits' eyes.");break;case RAINY:System.out.println("The Hobbits are dripping wet.");break;case WINDY:System.out.println("The Hobbits smell almost vanishes in the wind.");default:break;}       }
}

写一个主类来测试一下改功能(App.java)

public class APP {public static void main(String[] args){Weather weather=new Weather();weather.addObservers(new Orcs());weather.addObservers(new Hobbits());//weather.addObservers(new Terran());weather.timePasses();//weather.timePasses();
        }
}

输出:(即天气从Sunny变成Windy的时候,订阅该天气的Orcs和Hobitts都收到了天气改变的通知)

The weather change to  windy
The orc smell almost vanishes in the wind.
The Hobbits smell almost vanishes in the wind.

在以下任何情况下使用观察者模式:

  • 抽象有两个方面,一个依赖于另一个。将这些方面封装在单独的对象中可以让您独立地更改和重用它们
  • 当更改一个对象需要更改其他对象时,您不知道需要更改多少个对象
  • 当一个对象应该能够通知其他对象,而不需要假设这些对象是谁。换句话说,你不希望这些对象紧密结合

转载于:https://www.cnblogs.com/ahangBlogs/p/7988561.html

观察者模式/ java实现附代码 /相关推荐

  1. java中自造类是什么意思_Java建造者模式是什么?如何实现?(附代码)

    本篇文章给大家带来的内容是关于Java建造者模式是什么?如何实现?(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 建造者模式 一.什么是建筑者模式? 建造者模式(Build ...

  2. Java中集成极光推送实现给Android提送消息通知(附代码下载)

    场景 Android中集成极光推送实现推送消息通知与根据别名指定推送附示例代码下载: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details ...

  3. Java SE有几个代码_JavaSE常用类及方法的介绍(附代码)

    本篇文章给大家带来的内容是关于JavaSE常用类及方法的介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1.基本数据类型比较用:== 2.引用数据类型比较用:equal ...

  4. java 递归_采用递归算法求解迷宫问题(Java版) | 附代码+视频

    递归算法能够解决很多计算机科学问题,迷宫问题就是其中一个典型案例.本篇教程我们将采用递归算法求解迷宫问题,输出从入口到出口的所有迷宫路径. 01 用递归算法解决迷宫问题 迷宫问题在<数据结构教程 ...

  5. java乘法表_Java中四种9*9乘法表的实现方式(附代码)

    前言: 初学java,实现99乘法表是必学必会的内容. 需求 : 分别写出上下左右,对应四个角的乘法表. 思路: 可以先打印出*星星,形成一个直角三角形,然后再替换成乘法公式. 代码如下: publi ...

  6. java中对象类型转换_Java中的对象的类型转换介绍(附代码)

    本篇文章给大家带来的内容是关于Java中的对象的类型转换介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 向上转型:子类对象转为父类,父类可以是接口.公式:Father ...

  7. 知识库递归编程java和prolog代码;逻辑语言Prolog简介(附24555字PDF发“递归prolog简介”下载)

    知识库递归编程java和prolog代码:逻辑语言Prolog简介(附24555字PDF发"递归prolog简介"下载) 数据简化DataSimp 今天 数据简化DataSimp导 ...

  8. java 发邮件 新浪,发邮件时终于可以通过sina的smtp验证了(附代码)

    发邮件时终于可以通过sina的smtp验证了(附代码) 时间:2006/7/19 5:35:34 作者:佚名 人气:64 import javax.mail.*; import javax.mail. ...

  9. Java Web实现登录注册(超详细附代码)

    Java Web实现登录注册(超详细附代码) 文章目录 Java Web实现登录注册(超详细附代码) 1.前言 2.登录注册设计流程 3.注册的数据流程 4.登录的数据流程 5.部分代码的展示 5.1 ...

最新文章

  1. jquery 手型 鼠标穿过时_JS实现的鼠标跟随代码(卡通手型点击效果)
  2. java竞拍系统代码,网上拍卖系统的设计与实现(源代码及全套资料).doc
  3. error nr.1045 access denied for user 'root'@'localhost' (using passwd:no)
  4. list-style-type:decimal在IE中显示全是1的解析
  5. 正则表达式怎样匹配 不包含特定字符串的字符串
  6. Python爬虫淘宝商品详情页价格、类似数据
  7. 第五天 常用基本函数
  8. python就业方向-看完Python这五大就业方向的薪资待遇,你选择哪个?
  9. cogs 315. [POJ3255] 地砖RoadBlocks
  10. mp4文件如何转换为webm格式
  11. ios开发-教程选择
  12. 超强功能WebSSH安装,解决Web远程SSH终端
  13. 【本科毕业设计】基于单片机的智能家居防火防盗报警系统
  14. SQL(Oracle) 日期转换为英文年月格式
  15. 使用TIM3和TIM4,驱动外接LED和STM32上已焊接的LED,实现2个 LED呼吸灯的效果
  16. flex布局(flex容器,flex属性)
  17. 计算机专业当兵退役什么工作,当兵退伍后能做什么 能干什么工作
  18. 100以内奇数的和java_Java 求0-100奇数和
  19. 2021浙江大学计算机学院研究生招生计划,2021年浙江大学计算机学院考研分数线数据分析...
  20. 基于python的脑电地形图显示

热门文章

  1. linux内核参数优化
  2. 向窗体中拖放图片并显示
  3. IsNull和IsEmpty的区别
  4. Python中读取、显示和保存图片的方法
  5. Python技术栈与Spark交叉数据分析双向整合技术实战--大数据ML样本集案例实战
  6. Delphi 常用API 函数(好多都没见过)
  7. 关于Unity3D中鼠标移动指定物体的解决方案
  8. 演示:GLBP跟踪功能、权值、与不同的负载均衡方式
  9. oracle数据连接出现 login denied 问题
  10. 为什么基类的析构函数要声明成虚函数