监听器模式

监听器模式其实是观察者模式中的一种,两者都有关于回调的设计。

与观察者模式不同的是,观察者模式中存在的角色为观察者(Observer)被观察者(Observable)

而监听器模式中存在三种角色

  • 事件源(EventSource)
  • 事件对象(EventObject)
  • 事件监听器(EventListener)

简单的概述就是: 事件源经过事件的封装传给监听器,当事件源触发事件后,监听器接收到事件对象可以回调事件的方法

下面这张图可以很详细解释他们之间的关系

简单的实例

UML

@startuml
class EventSource{
- listeners: Vector<EventListener>
+ void addListener(EventListener listener)
+ void removeListener(EventListener listener)
+ void notifyListenerEvents(EventObject eventObject)
} class EventObject{
+ getSource(): Object
+ void:say() } interface EventListener{
+ void handleEvent(EventObject eventObject)
} class ConcreteEvetListenerA{
+ void handleEvent(EventObject eventObject)
}
class ConcreteEvetListenerB{
+ void handleEvent(EventObject eventObject)
} EventListener <-- ConcreteEvetListenerA
EventListener <-- ConcreteEvetListenerB EventObject --o EventListener EventSource -- EventObject
@enduml

事件源

public class DemoEventSource {

    /** 监听器列表 */
public Vector<DemoEventListener> listeners = new Vector<>(); /**
* 注册监听器
* @param listener EventListener
*/
public void addListener(DemoEventListener listener) {
listeners.add(listener);
} /**
* 撤销监听器
* @param listener EventListener
*/
public void removeListener(DemoEventListener listener) {
listeners.remove(listener);
} /**
* 通知所有监听器,包裹事件源成为事件
* @param eventObject EventObject
*/
public void notifyListenerEvents(EventObject eventObject){
listeners.forEach(listener ->{
listener.handleEvent(eventObject);
});
}
}

事件对象

public class DemoEventObject extends EventObject {

    /**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @throws IllegalArgumentException if source is null.
*/
public DemoEventObject(Object source) {
super(source);
} /**
* 事件的回调或者业务逻辑
*/
public void say() {
System.out.println("this is " + this + " to say");
}
}

事件监听器

public interface DemoEventListener extends EventListener {

    /**
* 处理事件
* @param eventObject EventObject
*/
void handleEvent(EventObject eventObject);
} public class ConcreteEventListenerA implements DemoEventListener { @Override
public void handleEvent(EventObject eventObject) {
System.out.println("ConcreteEventListenerA accept eventObject , eventSource is : " + eventObject.getSource());
if (eventObject instanceof DemoEventObject) {
// 执行事件的回调函数/具体业务逻辑
((DemoEventObject) eventObject).say();
}
}
} public class ConcreteEventListenerB implements DemoEventListener { @Override
public void handleEvent(EventObject eventObject) {
System.out.println("ConcreteEventListenerB accept eventObject , eventSource is : " + eventObject.getSource()); if (eventObject instanceof DemoEventObject) {
// 执行事件的回调函数/具体业务逻辑
((DemoEventObject) eventObject).say();
} }
}

客户端

public class Client {
public static void main(String[] args) { // 初始化监听器
DemoEventListener demoEventListenerA = new ConcreteEventListenerA();
DemoEventListener demoEventListenerB = new ConcreteEventListenerB(); // 事件源A
DemoEventSource demoEventSource1 = new DemoEventSource();
demoEventSource1.addListener(demoEventListenerA);
demoEventSource1.addListener(demoEventListenerB);
demoEventSource1.notifyListenerEvents(new DemoEventObject(demoEventSource1)); // 事件源B
DemoEventSource demoEventSource2 = new DemoEventSource();
demoEventSource2.addListener(demoEventListenerB);
demoEventSource2.notifyListenerEvents(new DemoEventObject(demoEventSource2));
}
}

【Design Patterns】监听器模式的更多相关文章

  1. Java基础学习总结(37)——Java23中设计模式(Design Patterns)详解

    设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  2. Design Patterns in Android

    对日常在 Android 中实用设计模式进行一下梳理和总结,文中参考了一些网站和大佬的博客,如 MichaelX(xiong_it) .菜鸟教程.四月葡萄.IAM四十二等,在这里注明下~另外强烈推荐图 ...

  3. Design Patterns Simplified - Part 3 (Simple Factory)【设计模式简述--第三部分(简单工厂)】

    原文链接:http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part3-factory/ Design ...

  4. [Design Patterns] 4. Creation Pattern

    设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结,使用设计模式的目的是提高代码的可重用性,让代码更容易被他人理解,并保证代码可靠性.它是代码编制真正实现工程化. 四个关键元素 ...

  5. [Design Patterns] 3. Software Pattern Overview

    When you're on the way which is unknown and dangerous, just follow your mind and steer the boat. 软件模 ...

  6. 设计模式(Design Patterns)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  7. Design Patterns in Smalltalk MVC 在Smalltalk的MVC设计模式

    Design Patterns in Smalltalk    MVC在Smalltalk的MVC设计模式 The Model/View/Controller (MVC) triad ofclasse ...

  8. 设计模式(Design Patterns)Java版

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  9. java Design Patterns

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

随机推荐

  1. JavaScript中的eval()函数详解

    和其他很多解释性语言一样,JavaScript同样可以解释运行由JavaScript源代码组成的字符串,并产生一个值.JavaScript通过全局函数eval()来完成这个工作     eval(“1 ...

  2. c# Linq Where 抛出异常 导致 程序崩溃

    Collection was modified; enumeration operation may not execute" 这次项目中遇到一个问题, 就是C#程序随机崩溃, 抛出上面的异 ...

  3. 如何分析一个QT类

    作者:gnuhpc  出处:http://www.cnblogs.com/gnuhpc/ 我们以QLineEdit这个类为例来看看如何学习分析一个QT类. 1.Public Types: 这是一个在这 ...

  4. JS加DOM理解

    1. ***变量 2. ***数据类型 一. ***变量:内存中存储*一个*数据的存储空间,再起一个名字 何时使用:程序中反复使用的数据,都要先保存在变量中,再参与运算 如何使用:声明   赋值    ...

  5. #if _MSC_VER > 1000 #pragma once #endif

    #if _MSC_VER > 1000 #pragma once #endif 解释: 这是微软的预编译控制. 在_MSC_VER较小时,它对一些东西的支持与新版不同 _MSC_VER分解如下: ...

  6. Polygon

    用当前的笔绘制一个由两个或多个点(顶点)连接的多边形. BOOL Polygon( LPPOINT lpPoints, int nCount ); lpPoints 指向一个指定多边形顶点的点.数组中 ...

  7. POJ-3617

    Best Cow Line Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25616   Accepted: 6984 De ...

  8. 选择Netty的理由

    摘自:http://blog.csdn.net/u010154380/article/details/64443762 <Netty 权威指南>—— 选择Netty的理由 声明:本文是&l ...

  9. 34.Docker安装Mysql参数及环境变量使用

    容器安装好后,通过exec进去到容器的内部, 容器安装的时候两种容器配置参数 直接在镜像的后面加配置 第二种方式 把这段代码拷贝过来.参数我们可以写在镜像的后面 我们把参数写在镜像的后面 然后我们需要 ...

  10. Fitnesse框架简单介绍

    1.Fitnesse是什么? 官方的说明:FitNesse is a wiki server. It's also a test execution engine. Fitnesse是一个wiki s ...