观察者模式,是一对多的关系,一个主题对应多个观察者,当这个主题发生变化的时候,所有观察着这个主题的观察者都会接收到通知来获悉主题的变化。

在现实中我们也会遇到许许多多应用观察者模式的行为,比如电视的节目频道里有时候会有暴雨天气的标志,这个标志是会随着天气的变化来显示,而我们显示的也是最新的天气标志,在这里电视频道就相当于是一个主题,而我们的电视机就是这个主题观察者,所以当这个天气标志有变化时电视上的画面也随着变化。这就是使用的观察者模式,下面就让我们用代码实现观察者模式。

首先我们需要定义主题的接口,这里面有三个方法,registerObserver、removeObserver和notifyObserver,分别是用来添加观察者、去除观察者和通知所有观察者。其中dataChange方法是只要当数据有变化就会被调用,我们需要在这个方法里调用notifyObserver去通知所有的观察者数据变化的内容,这里我们使用setSimulateDataChange方法来模拟数据的变化。

public interface Subject {

void registerObserver(Observer observer);

void removeObserver(Observer observer);

void notifyObserver();

}

然后我们创建一个具体的主题类来实现这个主题接口,假设这个类是获取电视频道的信息。在这个类里面我们需要创建一个集合用来存取观察这个主题的所有观察者,接口中的registerObserver和removeObserver方法实际就是对集合的增删操作,而notifyObserver方法其实就是遍历集合通知所有的对象。

public class TelevisionData implements Subject {

private String showName;

private String showType;

private ArrayList list;

public TelevisionData(){

list = new ArrayList();

}

@Override

public void registerObserver(Observer observer) {

list.add(observer);

}

@Override

public void removeObserver(Observer observer) {

int index = list.indexOf(observer);

if (index>=0){

list.remove(index);

}

}

@Override

public void notifyObserver() {

ListIterator listIterator = list.listIterator();

while (listIterator.hasNext()){

Observer observer = (Observer)listIterator.next();

observer.update(showName,showType);

}

}

public void dataChange(){

notifyObserver();

}

//此方法用于模拟控制数据的更新,数据更新后会调用dataChange方法

public void setSimulateDataChange(String showName,String showType){

this.showName = showName;

this.showType= showType;

dataChange();

}

}

主题部分的代码写好了,接着我们需要写观察者的代码,电视节目都播放在电视上,那我们把创建的电视类抽取出一个show方法放在Display接口中。

public interface Display {

void show();

}

另外观察者还有一个共性,就是要接收更新到的数据进行更新,所以我们再抽取出一个update方法放到Obeserver接口中。

public interface Observer {

void update(String showName,String showNum);

}

最后我们创建观察者的类来实现这两个接口,在这个类中showName和showType字段是用来接收主题的数据的,而subject则是要关注的主题类型引用,通过这个引用我们就可以调用registerObserver和removeObserver来控制观察者是否还要观察这个主题。当主题更新时则会调用update方法,观察者获取到更新的数据就再调用show方法显示出来。

public class John implements Observer,Display {

private Subject subject;

private String showName;

private String showType;

public John(Subject subject){

this.subject = subject;

}

@Override

public void show() {

System.out.println("john收看的当前天气类型-" + showType);

System.out.println("john收看的当前天气级别-" + showName);

}

@Override

public void update(String showName,String showType) {

this.showName = showName;

this.showType = showType;

show();

}

public void registerObserver(){

this.subject.registerObserver(this);

}

public void removeObserver(){

this.subject.removeObserver(this);

}

}

public class Jack implements Observer,Display {

private Subject subject;

private String showName;

private String showType;

public Jack(Subject subject){

this.subject = subject;

}

@Override

public void show() {

System.out.println("jack收看的当前天气类型-" + showType);

System.out.println("jack收看的当前天气级别-" + showName);

}

@Override

public void update(String showName,String showType) {

this.showName = showName;

this.showType = showType;

show();

}

public void registerObserver(){

this.subject.registerObserver(this);

}

public void removeObserver(){

this.subject.removeObserver(this);

}

}

下面我们来测试一下

//创建一个主题

televisionData = new TelevisionData();

//添加观察者

John john = new John(televisionData);

john.registerObserver();

Jack jack = new Jack(televisionData);

jack.registerObserver();

//模拟数据更新

changeData("大风", "5级");

changeData("暴雨", "红色");

public static void changeData(String showName, String showType) {

televisionData.setSimulateDataChange(showName,showType);

}

结果:

john收看的当前天气类型-红色

john收看的当前天气级别-暴雨

jack收看的当前天气类型-红色

jack收看的当前天气级别-暴雨

john收看的当前天气类型-5级

john收看的当前天气级别-大风

jack收看的当前天气类型-5级

jack收看的当前天气级别-大风

我们再试着去掉一个观察者看它还会不会收到更新,结果是不会收到更新了

changeData("暴雨", "红色");

john.removeObserver();

changeData("大风", "5级");

结果:

john收看的当前天气类型-红色

john收看的当前天气级别-暴雨

jack收看的当前天气类型-红色

jack收看的当前天气级别-暴雨

jack收看的当前天气类型-5级

jack收看的当前天气级别-大风

总结:

观察者模式的大致原理其实就是观察者持有主题的引用来控制主题内部的集合对自己增删从而控制是否关注这个主题,而主题则通过对集合中的对象的操作,把数据的更新通知给所有的观察者。

java观察者模式_Java设计模式之观察者模式详解相关推荐

  1. java connection 单例_Java设计模式之单例模式详解

    Java设计模式之单例模式详解 什么是设计模式 设计模式是在大量的实践中总结和理论之后优选的代码结构,编程风格,以及解决问题的思考方式.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可 ...

  2. java单例设计模式_Java设计模式之单例模式详解

    在Java开发过程中,很多场景下都会碰到或要用到单例模式,在设计模式里也是经常作为指导学习的热门模式之一,相信每位开发同事都用到过.我们总是沿着前辈的足迹去做设定好的思路,往往没去探究为何这么做,所以 ...

  3. java远程_java实现电脑远程控制详解,附完整源代码

    Java JDK1.4 的Robot对象,该对象可以完成屏幕图像截取操作,控制鼠标,键盘,如此便可以轻而易举地实现远程服务器的控制.本文向大家介绍如何用Java Robot对象实现远程服务器的控制,并 ...

  4. filter java 是单例的吗_JAVA 设计模式之 单例模式详解

    单例模式:(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.单例模式是创建型模式.单例模式在现实生活中应用也非常广泛. 在 J2EE 标准中,S ...

  5. java设计模式观察者模式_Java设计模式(9)——观察者模式

    一.观察者模式定义 Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态. Observer模式提供给关联对象一种同步通信的手段,使某个 ...

  6. 设计模式java装饰模式范例_Java设计模式之装饰模式详解

    装饰者模式是动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 假设我们有一个需求,是给一家饮料店做一个计算各种饮料价格的功能.听起来很简单,我们创建一个抽象父类Bever ...

  7. predicate java 作用_Java函数式编程接口详解之Predicate

    一.初识 Predicate是Java提供的重要的函数编程接口之一,作用主要是用于逻辑判断. 首先看看源码: @FunctionalInterface public interface Predica ...

  8. java 事务_Java中事务总结详解(精华)

    1.什么是JAVA事务? 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (is ...

  9. java 聚合_Java 8 聚合操作详解

    Oracle在2014年3月19日如期发布了Java 8.Java 8版本被认为是具有里程碑意义的一个版本,Oracle在该版本中添加了许多新特性,包括Lambda表达式.方法引用.加强了安全等等. ...

最新文章

  1. add_compile_options和CMAKE_CXX_FLAGS的区别
  2. 如何在vue中使用element-ui
  3. 虾扯蛋之函数防抖和节流
  4. C语言(CED)查找最接近的元素(分治法/二分查找):在一个非降序列中,查找与给定值最接近的元素。(递归实现)
  5. leetcode —— 面试题36. 二叉搜索树与双向链表
  6. mysql不带加密模式jar包_Spring boot jar包加密(防止放在客户端反编译)
  7. 印花固浆在水性印花中的作用
  8. 深度学习——CNN、RNN、DNN汇总
  9. linux adb工具 终极总结
  10. 嵌入式DM(data matrix)码检测
  11. Mac Navicat连接MySQL8.0.11出错:2003 - Can't connect to MySQL server on ……(61 Connection refused)
  12. 202203 word中的表格 实现 外框线粗 内部线细
  13. 电子邮件链接格式html主题,HTML的电子邮件链接标签mailto用法详解
  14. 教你在M1芯片的imac一体机上安装PS2021 附教程和方法适用于所有Mac
  15. ae2018怎么打开2019_ae2018中英文切换的方法
  16. 990php,音频牛绝配 DIY音频专用分立运放OP990初测
  17. MobaXterm Professional v11.1 Build 3860 注册版-全功能SSH/X远程客户端-Xmanager最佳替代品
  18. 计算机研究与发展 杂志,计算机研究与发展杂志
  19. 千兆网络PHY芯片 RTL8211E的实践应用(自我总结篇)
  20. uva 11419 SAM I AM (最小覆盖 König定理)

热门文章

  1. mysql 字段加减_MySQL中你必须了解的函数
  2. Error:CPACK_PACKAGE_VERSION does not match version provided by version.hpp header!
  3. srand((unsigned)time(NULL))详解
  4. 百度搜索引擎广告SEM调用架构示意图
  5. [NOI2005]维护数列
  6. django-后台sms管理系统的css框架
  7. promise实现多个请求并行串行执行
  8. 【2018-01-22】HTML-表单及表单元素
  9. AngularJs--过滤器(filter)
  10. iOS开发技巧(系列十八:扩展UIColor,支持十六进制颜色设置)