/注:场景和例子引用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; @Override
public 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{

    @Override
public 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{ @Override
public 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.

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

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

观察者模式/ java实现附代码 /的更多相关文章

  1. 单例模式/ java实现附代码 /

    注: 场景和例子出自github的设计模式.传送门:https://github.com/iluwatar/java-design-patterns/tree/master/singleton 意图: ...

  2. 正则表达式学习笔记(附:Java版示例代码)

    具体学习推荐:正则表达式30分钟入门教程 .         除换行符以外的任意字符\w      word,正常字符,可以当做变量名的,字母.数字.下划线.汉字\s        space,空白符 ...

  3. SpringCloud-创建服务消费者-Feign方式(附代码下载)

    场景 SpringCloud-服务注册与实现-Eureka创建服务注册中心(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  4. JPA中实现双向多对多的关联关系(附代码下载)

    场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 ...

  5. Dubbo与SpringBoot整合流程(从实例入手,附代码下载)

    场景 Dubbo环境搭建-管理控制台dubbo-admin实现服务监控: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10362 ...

  6. 07.深入浅出 Spring Boot - 数据访问之Mybatis(附代码下载)

    MyBatis 在Spring Boot应用非常广,非常强大的一个半自动的ORM框架. 代码下载:https://github.com/Jackson0714/study-spring-boot.gi ...

  7. 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

    一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...

  8. 分享5种风格的 jQuery 分页效果【附代码】

    jPaginate 是一款非常精致的分页插件,提供了五种不同风格的分页效果,支持鼠标悬停翻页,快速分页功能.这款插件还提供了丰富的配置选项,你可以根据需要进行设置. 效果演示      源码下载 各个 ...

  9. java俄罗斯方块游戏代码

    java俄罗斯方块游戏代码: package com; import java.awt.Color; import java.awt.Graphics; import java.awt.event.K ...

随机推荐

  1. Python 元组 index() 方法

    描述 Python 元组 index() 方法用于从元祖中找出某个对象第一个匹配项的索引位置,如果这个对象不在元祖中会报一个异常. 语法 index() 方法语法: T.index(obj[,star ...

  2. Spring Boot(一):初步认识

    简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置 ...

  3. REST技术第三步 @BeanParam的使用

    我简介下rest中@BeanParam的使用 我们来做一个计算加法的服务. 提供两个參数a和b,计算出a+b. 參数都在URL里 就是类似这样的效果. 这次用上@BeanParam 首先写个POJO来 ...

  4. NGUI下拉菜单学习UIPopupList

    NGUI下拉栏主要注意2点 1.弹出文字收回去,需要更新主显文字信息,要绑定调用 2.有时候发现弹出来的面板差别很大 看了下代码 会根据父节点取相对位置. 这样位置就可以了,很奇怪的做法..

  5. 【Android】第21章 2D图形和动画

    分类:C#.Android.VS2015: 创建日期:2016-03-19 一.简介 Android系统定义了一系列独立的图形处理类,其中,2D图形处理类分别位于以下命名空间: Android.Gra ...

  6. 【Android】11.2 通过重写对应的方法保存和恢复实例的状态

    分类:C#.Android.VS2015: 创建日期:2016-02-21 一.简介 通过重写(也叫回调)对应的方法来管理Activity的生命周期,比如用户旋转屏幕时应用程序要能自动保存和恢复实例的 ...

  7. [Linux] Ubuntu修改时区

    sudo apt-get install sysv-rc-confsudo dpkg-reconfigure tzdata

  8. haproxy 配置mysql的代理

    应用场境,是如果mysql服务器没有外网的,需要一个有外网的代理服务器做代理,这时就可以用haproxy做个四层的代理: listen mysql bind mode tcp balance roun ...

  9. Maven 在eclipse中如何配置

    大部分码农们都很熟悉Eclipse,用eclipse开发项目,Maven是解决依赖库的一个非常好用的java工具,可以与Eclipse集成,方便地管理web,java项目等等:但是很多初学者都不知道怎 ...

  10. js实现新闻条目滚动效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...