《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对象。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值