文章目录
切勿抄袭,违者后果自负,饶元老师很严格的😄
面向对象事件处理机制分析
一、 题目描述
一般的,面向对象分析与设计存在三种基本事件处理的机制,除了普通的方法调用以外, 也常常使用到回调函数,而 J2EE 中还提供了一种基于监听方式的事件处理机制,请查阅资料,对 Action 与 ActionListener 的机制进行分析,完成一个分析示例。
同时,请将这三种方法或其他更多的事件处理方法在代码实现过程中的优劣进行比较和分析,并形成详细的分析总报告。
二、 Action 与 ActionListener 的机制分析
1) 观察者模式(Observer 模式)
观察者模式是指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,它是一种对象行为型模式。
观察者模式的主要角色如下。
1️⃣ 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
2️⃣ 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
3️⃣ 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
4️⃣ 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
2) J2EE 中基于监听方式的事件处理机制
J2EE 中提供的基于监听方式的事件处理机制就是观察者模式在 Java 中的重要应用,其中涉及到以下四个重要的概念。
1️⃣ 事件源**(Event** Source):操作发生的场所,通常指某个组件,例如按钮、窗口等;
2️⃣ 事件**(Event)**:在事件源上发生的操作可以叫做事件,基于监听方式的事件处理机制会把事件都封装到一个 Event 对象中,如果需要知道该事件的详细信息,就可以通过 Event 对象来获取。
3️⃣事件监听器**(Event** Listener):当在某个事件源上发生了某个事件,事件监听器就可以对这个事件进行处理。
4️⃣ 注册监听:把某个事件监听器(A)通过某个事件(B)绑定到某个事件源©上,当在事件源C 上发生了事件B 之后,那么事件监听器 A 的代码就会自动执行。
其中监听器接口就是 Observer 模式中的抽象观察者角色,监听接口的实现类就是Observer 模式中的具体观察者角色,而事件源则是抽象目标类,事件源产生的具体事件则是具体目标类,以上的关系都是一一对应的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在此事件处理机制中,事件处理的流程为,首先将事件监听器通过事件注册到事件源上, 然后外部动作在事件源上执行了某个事件,事件处理机制则会根据动作的详细信息封装成事件对象,然后会自动执行事件监听器中的代码,并传递事件对象。图解如下:
3) Action 与 ActionListener 机制分析
Java GUI 中可以添加 ActionListener 进行 Action 事件监听,而 ActionListener 接收到的Action 事件是 ActionEvent。
使用 ActionListener 的步骤如下:
1️⃣ 创建事件源组件对象;
2️⃣ 自定义类,实现 ActionListener 接口,重写方法;
3️⃣ 创建事件监听器对象(自定义类对象)
4️⃣ 调用事件源组件对象的addActionListener 方法完成注册监听
为了说明其机制,下面进行举例说明:完成下图效果,点击确定按钮,在单行文本域内显示 “action”。
首先需要创建事件源组件 Button,然后将监听器 ActionListener 中的方法用具体的类MyListener 加以实现,之后将事件监听器利用 addActionListener 方法注册到事件源 Button 上,监听器中的 actionPerformed 方法会监听事件 ActionEvent。当我们按下 Button 时,会触发监听机制,从而执行 ActionListener 中的 actionPerformed 方法,从而显示”action”。
具体代码如下:这里使用了内部类
为了简化代码,我们也可以使用匿名类来加以实现:
三、 三种基本事件处理机制的比较分析
对于面向对象分析与设计,由三种基本的事件处理机制:普通的方法调用、回调方法、以及基于监听的事件处理机制。监听事件处理上文已经分析过,不再进行阐述,对普通的方法调用和回调方法的说明如下。
1) 普通的方法调用
普通的方法调用通常指的是同步调用,即类 One 的方法 o()调用类 Two 的方法 t(),一直等待 t()方法执行完毕, o()方法继续往下走。这种调用方法实现简单,但是只适用于方法 t() 执行时间不长的情况, 因为 t()方法执行时间一长或者直接阻塞的话, o()方法的余下代码是无法执行下去的, 这样会造成整个线程的阻塞。
2) 方法回调
回调是一种双向的调用模式,也就是说,被调用的接口被调用时也会调用对方的接口。就像下图的类 One 中的 o()方法会调用类 Two 中的 t()方法,同时 t()反过来也会调用类 One 中的callback()方法。这是将功能定义与功能分开的一种手段,一种解耦合的设计思想;在 Java 中回调是通过接口来实现的, 作为一种系统架构,必须要有自己的运行环境,且需要为用户提供实现接口;实现依赖于客户,这样就可以 达到接口统一,实现不同,系统通过在不同的状态下"回调"我们的实现类,从而达到接口和实现的分离。
举例说明回调方法:我约你去自习,但是你要先洗澡,等你洗完澡再跟我一起去自习。代码如下:
先要定义回调接口:
然后是 Me 类的实现
最后是 You 类的实现
由上例可知,Me 调用了 You 中的 wash 方法,然后 You 中也调用了 Me 中的 learn 方法,代码实现结果如下:
3) 三种方法的比较分析
基于监听的事件处理机制,会为事件源(组件)添加一个监听器,然后当用户触发了事件后交给监听器去处理,根据不同的事件执行不同的操作。对于基于回调的事件处理模型来说,事件源与事件监听器是统一的,不需要单独的监听器,当激发某个事件时,是事件所在的方法将会负责处理该事件。
一般来说,基于回调的事件处理可用于处理一些具有通用性的事件,基于回调的事件处理代码显得比较简洁.但由于某些特定的事件,无法使用基于回调的事件处理,只能使用基于监听的事件处理。而普通方法的调用的适用范围更窄,当事件的处理机制较为复制时便难以再使用了。
综合以上的代码与分析,可以得到以下的分析结果。
表格 1 事件处理方法比较
特点 | 普通的方法调用 | 方法回调 | 基于监听的事件处理 |
---|---|---|---|
实现难度 | 简单 | 较难 | 难 |
线程阻塞 | 是 | 可异步处理 | 可异步处理 |
适用范围 | 窄 | 较宽 | 宽 |
使用频率 | 高 | 较高 | 较高 |
需要监听器 | 否 | 否 | 是 |
四、 参考资料
[1] 欧阳宏基, 杨卫忠, 赵蔷. 观察者模式在 Java 事件处理中的应用研究[J]. 微处理机,2013,34(04):77-79.
[2] iaanming.一个经典例子让你彻彻底底理解 java 回调机制[ER/OL].
[3]带妳心菲.Java 调用与回调总结(2) [ER/OL].