文章目录

  • 前言
  • 一、认识观察者模式
  • 二、实现观察者模式
    • 实现过程
    • 实际应用情况描述
  • 总结
  • 参考资料

前言

本篇博客是关于观察者模式的实现,若文章中出现相关问题,请指出!

对应代码地址:Gitee(demo-exer/ java-Lear23designpatterns)、Github(java-demo/ java-Lear23designpatterns)

所有博客文件目录索引:博客目录索引(持续更新)

一、认识观察者模式

观察者模式定义:属于对象行为模式,当多个对象之间存在一对多的依赖关系,即一个对象的状态发生改变时,所以依赖它的对象都会得到通知并被自动更新。这种模式有时又被称为发布-订阅模式、模型-视图模式。

结构

  1. 抽象主题角色(Subject):即抽象类,提供了添加、移除观察者的方法,以及一个通知所有观察者的抽象方法。
  2. 具体主题角色(Concrete Subject):也称为具体目标类,实现抽象目标中的通知方法,一旦该类内部发生了什么改变时,通知所有注册过的观察者对象。
  3. 抽象观察者(Observer):是一个抽象类或接口,包含了一个更新自己的抽象方法,当接到具体主题的更改时被调用。
  4. 具体观察者(Concrete Observer):实现抽象观察者中的更新方法,一旦目标角色发出更新通知时会调用该更新方法来更新自身的状态。

优缺点

  • 优点:降低了目标与观察者之间的耦合关系,符合依赖倒置原则开闭原则。目标与观察者之间建立了一套触发机制。
  • 缺点:目标与观察者之间依赖关系并没有完全解除,可能出现循环引用。并且若是当在主题角色中的观察者过多时,通知发布会花费很多时间,影响程序的效率。

实际应用场景

  1. JDK中的java.util.Observable
  2. Spring中的org.springframework.context.ApplicationListener

二、实现观察者模式

实现过程

demo见xyz.changlu.observer包下代码:

抽象观察者(接口):Observer

public interface Observer {void response();
}

抽象主题类:Subject

public abstract class Subject {protected List<Observer> observers = new ArrayList<>();//添加观察者到集合中public void addObserver(Observer observer){observers.add(observer);}//移除指定观察者public void removeObserver(Observer observer){observers.remove(observer);}//具体通知方法让实现类去实现public abstract void notifyAllObserver();
}

具体观察者:Task1Task2

//具体观察者1号
public class Task1 implements Observer {@Overridepublic void response() {System.out.println("Task1收到通知,正在执行任务2.....");}
}//具体观察者2号
public class Task2 implements Observer {@Overridepublic void response() {System.out.println("Task2收到通知,正在执行任务2.....");}
}

具体主题者:ConcreteSubject

public class ConcreteSubject extends Subject {@Overridepublic void notifyAllObserver() {System.out.println("收到通知");//开始通知到所有的观察者for (Observer observer : observers) {observer.response();}}
}

测试程序:测试类Customer

public class Customer {public static void main(String[] args) {//创建两个任务Task1 task1 = new Task1();Task2 task2 = new Task2();//创建主题角色,并添加两个观察者(及任务)ConcreteSubject subject = new ConcreteSubject();subject.addObserver(task1);subject.addObserver(task2);//进行更新通知subject.notifyAllObserver();}
}

  • 首先将多个任务(即观察者)添加到主题类中(存放在一个list集合里),一旦ConcreteSubject主题类进行了更新操作,即可调用其实现Subject抽象类的实现方法notifyAllObserver()来通知观察者集合中的各个观察者执行任务。

说明:解决的是当一个对象进行更新或其他操作时对应要去更改执行或通知多个任务时,我们即可以使用观察者模式。


实际应用情况描述

问题描述

若是主题进行了更新,并且该更新涉及到了需要个部分,此时你会怎么呢?若是没有了解过观察者模式的也许会这样:

class Weather{//执行更新操作public void update(){dao.update();//本方法核心的更新操作//通知的操作Task task = new Task();Task2 task2 = new Task2();task.doThing1();task2.doThing2();}
}class Task{void doThing1(){...}
}class Task2{void doThing2(){....}
}

你可能会在update()操作中去new多个对象并且逐一执行,若是某一天要少通知一个单位的话还需要去手动删除…

解决对策

创建一个抽象类,其包含了一个集合专门用来存放多个观察者对象,并包含添加、移除操作:

//抽象主题
public abstract class Subject {protected List<Observer> observers = new ArrayList<>();//添加观察者到集合中public void addObserver(Observer observer){observers.add(observer);}//移除指定观察者public void removeObserver(Observer observer){observers.remove(observer);}public abstract void notifyAllObserver();
}

再创建一个抽象观察者接口,其带有一个通知方法:

public interface Observer {void response();
}

万事具备了,我们开始改造原来的两个类

class Weather extends Subject{//执行更新操作public void update(){dao.update();//本方法核心的更新操作//调用通知操作即可!!!notifyAllObserver();}//实现一个通知方法@Overridepublic void notifyAllObserver() {//通知所有的观察者开始执行其自己的操作for (Observer observer : observers) {observer.response();}}
}//两个任务分别实现了观察者接口
class Task implements Observer{void doThing1(){...}@Overridepublic void response() {doThing1();//不仅仅可以添加该方法,还可以添加其他方法}
}class Task2{void doThing2(){....}@Overridepublic void response() {doThing2();//不仅仅可以添加该方法,还可以添加其他方法}
}

测试使用时:

public class Customer {public static void main(String[] args) {Weather weather = new Weather();//添加指定的任务weather.addObserver(new Task());weather.addObserver(new Task2());//执行其中的更新操作weather.update();//此时调用更新操作时,自动会执行集合中的所有观察者操作}
}

感悟:在对观察者模式进行思考时,将模式应用到实际案例中去,去通过使用设计模式来去解决整个项目的架构问题,提高方法解耦!!!


总结

1、对于观察者模式,在出现一对多的关系操作时可以进行使用来实现方法解耦,一般应当是当要执行更新或其他操作影响到很多个对象时,为了方便管理通知可以使用到该模式。

2、优点是符合开闭原则、依赖倒置原则,对于目标与观察者之间建立了连接。缺点是依赖关系没有完全解除,若是观察者过多通知发布会耗费很多时间,影响程序的效率。


参考资料

视频:2020年最详细的23种Java设计模式完整视频教程全集 观察者模式

[1]. 观察者模式(Observer模式)详解

[2]. 设计模式之观察者模式 包含一个天气的例子

我是长路,感谢你的耐心阅读。如有问题请指出,我会积极采纳!
欢迎关注我的公众号【长路Java】,分享Java学习文章及相关资料
Q群:851968786 我们可以一起探讨学习
注明:转载可,需要附带上文章链接

设计模式之观察者模式(Java实现)相关推荐

  1. Java 设计模式之观察者模式

    一.了解观察者模式 1.1 什么是观察者模式 观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新. 典型的问题比如报社,只要你是他们的订户,他们 ...

  2. java 观察者模式_图解Java设计模式之观察者模式

    图解Java设计模式之观察者模式 天气预报项目需求 天气预报设计方案 1 - 普通方案 观察者模式(Observer)原理 观察者模式解决天气预报需求 观察者模式在JDK应用的源码分析 天气预报项目需 ...

  3. java观察者模式本质_6.[研磨设计模式笔记]观察者模式

    1.定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新. 2.解决问题 --订阅报纸 看起来订阅者是直接根有据打交道,但实际上,订阅者的订阅数据 ...

  4. java设计模式观察者模式吗_Java设计模式之观察者模式原理与用法详解

    Java设计模式之观察者模式原理与用法详解 本文实例讲述了Java设计模式之观察者模式原理与用法.分享给大家供大家参考,具体如下: 什么是观察者模式 可以这么理解: 观察者模式定义了一种一对多的依赖关 ...

  5. Java设计模式系列--观察者模式(使用)

    原文网址:Java设计模式系列--观察者模式(使用)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文用示例介绍观察者模式的用法. 观察者模式的含义 以微信公众号为例.我们关注了某个微信公众号后能收 ...

  6. Java设计模式之观察者模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  7. 折腾Java设计模式之观察者模式

    观察者模式 Define a one-to-many dependency between objects where a state change in one object results in ...

  8. JAVA架构之路(设计模式之观察者模式)

    设计模式之观察者模式 定义:对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新 核心原理: 1.被观察者中维护一个观察者对象列表 2.观察者可新增可可移 ...

  9. 设计模式:观察者模式--Observer

    一.什么是观察者模式 1.生活中的观察者模式 1.警察抓小偷 在现实生活中,警察抓小偷是一个典型的观察者模式「这以一个惯犯在街道逛街然后被抓为例子」,这里小偷就是被观察者,各个干警就是观察者,干警时时 ...

  10. 学习《图说设计模式》观察者模式

    图说设计模式之观察者模式 1. 模式动机 建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应.在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一 ...

最新文章

  1. Qt运行时中文乱码的解决办法
  2. python有哪些软件包用来考察变量之间的相关性_Python计算数据相关系数(person、Kendall、spearman)...
  3. 新挑战、新架构下的数据保护新需求
  4. leetcode337. 打家劫舍 III
  5. 数据结构实验之图论七:驴友计划
  6. 实战:kafka实现日志收集系统
  7. 修改服务器时间需要重启吗,云服务器需要定期重启吗
  8. Zookeeper集群部署及报错分析
  9. iconfont-矢量图标字体的运用
  10. 第一次JAVA课,第一次课堂考,课后感受
  11. Spark Streaming揭秘 Day6 关于SparkStreaming Job的一些思考
  12. 如何实现全选checkbox效果
  13. webpack遇见的坑:Please install 'webpack-cli' in addition to webpack itself to use the CLI.
  14. 使用Jquery对数组进行迭代、排序、去重! 美男子加油!!!
  15. PHP微信公众开发笔记(一)
  16. 安卓手游辅助分析与开发!五步搞定Android开发环境部署,深度好文
  17. Gan 和 StyleGAN 架构
  18. 基于MFC的U盘检测
  19. 天猫order前后台
  20. hive创建hbase外部表

热门文章

  1. 微信小程序获取点击事件的值
  2. 网络七层模型及各层协议
  3. 海森矩阵(Hessian)
  4. 慕课翁凯习题集答案01厘米转换为英尺,英寸问题
  5. python绘图技巧(高清图)
  6. 分区助手迁移系统,更改系统盘盘符
  7. M-TOUCH移动端社区论坛类型的网站源码
  8. Drozer的安装和使用教程(入门)
  9. 西门子PLC S7-1200程序实例,博图版本V15,仅供电气编程者学习借鉴
  10. lvds接口屏线安装图解_lvds液晶屏幕接口详解