当前位置: 首页 > news >正文

《java与模式》学习系列——观察者模式

 

一、 观察者(Observer)模式的结构

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

结构如下图所示:

二、 观察模式在java中的应用

java语言对观察者模式的支持

java语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成Java语言观观察者模式的支持。Observer接口只定义了一个方法,即update方法,相当于抽象观察者角色。Observable类相当于抽象主题角色。

AWT中的DEM机制

AWT 1.1 版本及以后的各版本,事件处理模型均为基于观察者模式的委派事件模型(Delegation Event ModelDEM)。在DEM模型里面,主题(Subject)角色负责发布事件,而观察者角色向特定的主题订阅它所感兴趣的事件。当一个具体主题产生一个事件时,它就会通知所有感兴趣的订阅者。在DEM中,发布者叫做事件源,而订阅者叫做事件监听器。

三、 观察者模式优缺点

优点:(1)观察者模式在主题和观察者之间建立一个抽象的耦合,实现了松耦合。(2)观察者模式支持广播通信。主题角色会向所有的登记过的观察者发出通知。

缺点:(1)如果一个主题有很多观察者的话,通知所有的观察者会花费很多的时间。(2)如果对观察者的通知是通过另外的线程进行异步投递的话,必须保证投递是以自恰的方式进行的。

四、 观察模式相关专题

1DEM结构

在常见的事件处理模型中,对象通常被划分为三种:事件对象,事件制造者对象(事件源对象),事件接收者对象。一般而言,事件对象本身封装了有关事件的信息,当事件制造者的内部状态发生变化时,会根据需要创建一个代表状态变化的事件对象,并将它传给所有登记过的事件接收者对象。

事件源对象:一个类要成为事件源并不需要实现任何接口或者继承任何类,但是一个事件源需要保持一个事件监听器的列表。调用addXXXListener()方法增加一个监听器,调用一个removeXXXListener()方法删除一个监听器。所有的AWT构件都是java.awt.Component的子类,它们都从Component类继承了各个addXXXListener()方法。事件对象:DEM中,每一种事件都有一个事件对象与之对应,而所有的AWT中的事件对象都是从Java.util.Object继承而来的,每一种具体的事件对象都有一些额外的功能,事件对象封装了事件的源对象与事件监听器对象所需要的事件信息。有一些事件类,比如PaintEvent,是不会被传递给监听器的,因此对java程序员来说并没有什么用处。Java应用程序设计师会接触到的是那些会被传递给监听器的事件类。如:ActionEventAdjustmentEventComponentEventContainerEventFocusEventItemEventKeyEventMouseEventTextEventWindowEvent

事件监听器对象

事件监听器对象是当事件发生时被调用的对象。一个对象要成为事件监听器对象,必须实现事件监听器接口,AWT库中所有的事件监听器接口都是java.util.EventListener接口的子接口。AWT中有些事件监听器接口声明了多于一个的方法,AWT为这些接口提供了相应的适配器类称为事件监听适配器类。适配器类为这些接口提供了空的实现,这样一个需要处理某个事件的应用类只需要继承相应的事件适配器类,并置换掉感兴趣的事件处理方法即可。这些事件监听适配器正是缺省适配器模式的应用。

语义事件与底层事件

AWT区分了底层事件和语义事件。一个语义事件表达了用户所做的事件,比如使用鼠标单击一个按键就是一个主义事件,一个底层事件则是组成各种语义事件的单纯事件。比如鼠标单击事件由一个鼠标键按下事件和一个鼠标键释放事件组成。AWT中最重要的四个语义事件类:ActionEvent(单击按键、选择菜单项、选择列表项、在文字框中输入文字等)AdjustmentEvent(调整滚动条)ItemEvent(用户在一组选择框中选择一个,或者在列表中选择一项)TextEvent(文字框的内容有变化)还有六个底层事件类:ComponentEventKeyEventMouseEventFocusEventWindowEventContainerEvent

2Swing定时器

java中提供了java.util.Timer定时器类和javax.swing.Timer定时器类。

util.Timer定时器与swing.Timer定时器区别

Util定时器是一个为一般用途设计的定时器,而Swing定时器是专为Swing库包准备的。Swing定时器在一个线程里面为任意多的操作定时,这个定时器往往用在变换文字框里的光标、定时显示和隐藏tooltips等用户界面上。

1)线程安全性

如同AWT一样,Swing不是线程安全的,它们均使用单一的线程处理所有来自操作系统的事件。

2)性能

Swing定时器类使用一个线程处理所有的定时器对象,因而不宜用来同时处理大量的定时器对象;而Util定时器则不然,它为每一个定时器对象提供一个独立的线程,因此如果所设计的系统要求大量的定时器对象的话,应使用Util定时器。同时由于Swing定时器类的所有定时器对象所用的线程与事件处理器使用的是同一个线程,因此适合于在Swing构件中使用。

3)使用上的区别

使用Swing定时器类时需要创建一个Action对象,以封装被定时的行为;而Util定时器则需要为每一个被定时的任务创建一个TimerTask对象。

 

相关文章:

  • angularjs服务-service
  • 《java与模式》学习系列——迭代子模式
  • Werkzeug工具包学习-官方例子Shortly分析
  • 《java与模式》学习系列——责任链模式
  • iOS中的交换空间(swap space)
  • 《java与模式》学习系列——命令模式
  • Windows10中无法打开这个应用的解决方案
  • sqlbulkcopy 使用DataTable作为数据源的数据类型问题--来自数据源的String类型的给定值不能转换为指定目标列的类型 uniqueidentifier...
  • 《java与模式》学习系列——状态模式
  • debian终端菱形乱码修复
  • 《java与模式》学习系列——访问者模式
  • 《java与模式》学习系列——解释器模式
  • C#调用windwos系统数据源配置
  • 《java与模式》学习系列——调停者模式
  • [hibernate]基本值类型映射之日期类型
  • php的引用
  • bearychat的java client
  • const let
  • DOM的那些事
  • hadoop集群管理系统搭建规划说明
  • JavaScript DOM 10 - 滚动
  • java中具有继承关系的类及其对象初始化顺序
  • js作用域和this的理解
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 程序员最讨厌的9句话,你可有补充?
  • 跨域
  • 使用common-codec进行md5加密
  • 探索 JS 中的模块化
  • 新手搭建网站的主要流程
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • Java数据解析之JSON
  • Java性能优化之JVM GC(垃圾回收机制)
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • !!Dom4j 学习笔记
  • (二)hibernate配置管理
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (转)甲方乙方——赵民谈找工作
  • .CSS-hover 的解释
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET HttpWebRequest、WebClient、HttpClient
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET 设计一套高性能的弱事件机制
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .net专家(高海东的专栏)
  • @Autowired注解的实现原理
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • [ 蓝桥杯Web真题 ]-Markdown 文档解析
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [Android]RecyclerView添加HeaderView出现宽度问题
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [C语言]——内存函数
  • [HeadFrist-HTMLCSS学习笔记][第一章Web语言:开始了解HTML]