`
youtl
  • 浏览: 12360 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

用学校为例聊聊监听器模式的演变,看丑小鸭怎么变成天鹅的

阅读更多

       先介绍下监听器模式。它的学名叫做观察者模式,因为观察者一般都取名为listener,所以越来越多的人称它为监听器模式。它的主要作用有2个,一是扩展,比如web容器的listener,就是在web.xml中配置的那种,因为web容器(比如tomcat)无法预料到开发者在启动、销毁或者其它一些事件中全部行为,所以就预留了一些listener接口;另一种作用是解耦,比如领域驱动设计(DDD)中,常将监听器和CQRS(读写分离)结合来处理业务逻辑。以提交订单为例,提交订单不仅要保存订单信息,还要修改库存,发货,短信通知等等。把他们都合在一个流程里,就会使流程臃肿,引入监听器模式,我们就能在提交订单的时候,发布一个订单事件,由各个listener自己去监听,发短信的listener监听到下单后就发短信,发货listener监听到下单后,就做发货动作。每个listener做的事情都很单一,耦合度很低。

     现在让我们来看看观察者模式是怎么演变得来的。比如有个类student,然后它有个方法叫goTo(dest),dest是目标。上课铃响了,我们想让学生去教室,直接调student.goTo(教室)就行了。然后发现只有学生去教室还不行,也得让老师去教室。所以上课的时候,也要调用teacher.goTo(教室)。接着,我们发现可以提取出People接口,因为是人,都可以去一个地方。



 

我们在上课类里,建了个peoples列表,存储了2个people的实例:student和teacher。在上课的时候,循环调用其中的goto方法。

List<People> peoples=new ArrayList();
static{
     peoples.add(new Student());
     peoples.add(new Teacher());
}
上课(){
       for(People p:peoples){
              p.goto(教室);
     }
}

 

     很快,我们会发现这种方式很麻烦。比如要做早操了,在早操类里也要有上述peoples的初始化。这里我们可以引入单例模式,把peoples抽出来,放到一个第三方对象里,实例代码如下:

 

class PeoplesHolder{
     private static PeoplesHolder holder=new holder();
     private List<People> peoples;
     public static PeoplesHolder getHolder(){
     }

     PeoplesHolder(){
           List<People> peoples=new ArrayList();
           peoples.add(new Student());
           peoples.add(new Teacher());
     }
     
     public void goTo(dest){
         for(People p:peoples){
             p.goto(dest);
         }
     }        
}
 现在,上课的时候,只要调用PeoplesHolder.getHolder().goTo(教室)。做操的时候,只要调用PeoplesHolder.getHolder().goTo(操场)就可以了。使用比之前简单许多了,代码也就优美许多了。
       但我们会很快的发现,这还是不够的。因为people除了走路之外,还有很多其他的活动,比如放学了,要去吃饭。逻辑与走路类似,我们会发现PeoplesHolder还需要另一个方法,PeoplesHolder.getHolder().eat()。接着,我们发现走路的peoples成员与吃饭不会完全一致,比如校长不需要去上课,但他也要去吃饭。没办法,我们只好再建一个PeoplesHolder2。也就是用PeoplesHolder2.getHolder().eat()来完成吃放的动作。
    接下来,我们发现问题大了。因为people除了走路跟吃饭外,还有很多其他可能的操作。造成的结果是PeoplesHolder的种类不断膨胀,所以也要像刚才抽取PeoplesHolder那样,再将goTO、eat之类的动作给抽象出来。联系到实际业务,我们发现,走路和吃饭都有先决条件的,比如上课铃声,开饭时间等。也就是我们要观察某个条件才行。所以people接口修改如下:
interface People{
       观察(条件)
}
 以上的观察、条件是中国人的说法,外国人更喜欢用listen。也就是看和听的区别,所以观察者模式也被称为监听器模式。而条件编程语言里经常称为事件,也就是event。
interface People{
       listen(event)
}
到现在,监听器模式总算成型了。根据开闭原则,我们将listen的操作独立出来,做成新的接口PeopleListener;另外把Holder类改名为Publisher。就演变成如下结构:
interface PeopleListener{
       listen(Event event)
}

class WalkListener implements PeopleListener{
     private People;
}
class EatListener implements PeopleListener{
    private People;
}

Class Event{
}

class EventPublisher{
     private static EventPublisher holder=new EventPublisher();
     private List<PeopleListener> listeners;
     public static EventPublisher getHolder(){
     }

     PeoplesHolder(){
           List<PeopleListener> listeners=new ArrayList<PeopleListener>();
          ....
     }
     
     public void publish(event){
         for(People p:peoples){
             p.listen(event);
         }
     }        
}
 
现在,无论吃饭、睡觉还是走路,都只要调用EventPublisher.getHolder().pubulish(event)就行,而event是不同的,每个操作都要有一种event。所有的listener都能监听到该事件,然后自己判断需不需要做出反应。比如WalkListener,它只有在event类型时走路的时候,它才做出反应。
    到此,监听器模式就成型了。所有的设计模式,都是从代码的提炼中得来的。它也不会是固定格式的,会随着应用而不断演变。PS:People是人类,似乎Person更合适点。
 
  • 大小: 8.3 KB
分享到:
评论

相关推荐

    Java设计模式之监听器模式实例详解

    监听器模式是Java设计模式中的一种行为型模式,主要用于监听某些事件的发生,并在事件发生时自动执行预定义的操作。在实际开发中,监听器模式可以用于多种场景,如UI事件处理、事件广播、异步通知等。 在监听器模式...

    监听器模式(生产消费模型)

    监听器模式是一种设计模式,属于行为模式类别,它在软件工程中被广泛应用于事件处理,尤其是在多线程和异步编程中。这个模式的核心思想是定义一个对象接口,用于监听和处理特定事件的发生,使得多个对象可以注册为...

    java监听器的实现和原理详解

    在使用监听器模式时,需要注意以下几点: 1. 事件源和事件监听器之间的耦合度应该尽量降低,以便提高系统的灵活性和可扩展性。 2. 事件监听器的实现应该遵循单一职责原则,避免将多个事件处理方法放在同一个事件...

    基于SpringBoot为基础做的Binlog,MQ数据适配,解析,校验,托管,异常捕获,为使用者提供监听器模式和责任链模式

    为了更好的 完善,提升,B/S架构系统的性能和实用性,系统...MQ数据适配,解析,校验,托管,异常捕获,为使用者提供两种方案,监听器模式和责任链模式并提供出 crud接口 使用者只需要按自己的需求同步到其它容器中即可

    配置Oracle监听器

    Oracle监听器是Oracle数据库系统的重要组成部分,它负责管理和控制数据库实例与客户端应用程序之间的网络通信。在Oracle数据库环境中,监听器是运行在服务器端的一个后台进程,它的主要职责是监听来自客户端的连接...

    设计模式入门——胡老师的监听器模式

    NULL 博文链接:https://coco-young.iteye.com/blog/1275485

    基于 RBAC与监听器机制设计作业管理软件

    ### 基于RBAC与监听器机制设计作业管理软件 #### 一、项目背景与目标 本项目旨在设计一款适用于教育场景中的作业管理系统,利用角色基础的访问控制(Role-Based Access Control,简称RBAC)及监听器机制来实现安全...

    java一个监听器的例子

    在实际应用中,监听器经常与其他设计模式结合使用,如观察者模式(Observer),提供更灵活的事件处理方式。通过熟练掌握Java监听器机制,开发者可以创建更加响应用户输入的、交互性强的应用程序。 在提供的压缩包...

    监听者模式练习(包括jdk api的实现和自定义实现)

    在Java中,JDK提供了内置的监听器接口和类来支持这种模式。本练习将深入探讨如何使用JDK API实现监听者模式以及自定义实现这一模式。 首先,我们要理解JDK API中的观察者模式实现。`java.util.Observable`类代表可...

    监听器.zip

    在Java编程领域,监听器(Listener)是一种关键的组件,主要用于事件驱动编程。在这个名为"监听器.zip"的压缩包中,包含了三个示例项目...同时,理解监听器的工作原理也能为理解和使用其他基于事件的框架打下坚实基础。

    java监听器练习

    Java中的监听器机制是基于观察者模式的设计模式之一,广泛应用于图形用户界面(GUI)应用程序中。 #### 二、监听器的基本组成部分 监听器通常包括以下几个部分: 1. **事件源(Event Source)**:触发事件的对象,如...

    监听器源代码.zip

    在IT领域,监听器(Listener)是软件设计模式中的一种,广泛应用于事件驱动编程中,尤其是在Java和Web开发中。监听器允许程序订阅特定的事件,以便在这些事件发生时执行相应的操作。在这个名为"监听器源代码.zip"的...

    oracle监听器深入讲解

    "Oracle 监听器深入讲解" Oracle 监听器是 Oracle 数据库的核心组件之一,负责管理 Oracle 数据库和客户端之间的通讯。...了解 Oracle 监听器的工作原理和配置可以帮助开发者更好地使用 Oracle 数据库。

    【动力节点】Javaweb开发视频教程之监听器

    教程名称: 【动力节点】Javaweb开发视频教程之监听器 动力节点推出的Java视频教程包含两大部分内容:第一部分为监听器相关设计模式的详解。其中包括观察者设计模式、监听器设计模式。第二部分为监听器用法。详细...

    智能更新监听器使用说明

    智能更新监听器是针对C/S(客户端/服务器)架构软件的一种自动化补丁管理和更新工具,旨在解决手动更新补丁的繁琐过程。该工具由浪潮ERP-PS开发,用于提升企业系统的维护效率。以下是关于智能更新监听器的详细说明:...

    Java监听器添加 四种监听器 内部 外部 内部匿名 自身

    ### Java监听器添加:四种监听器(内部、外部、内部匿名、自身) #### 一、引言 在Java中,监听器(Listener)是事件处理机制的重要组成部分,它主要用于响应用户或其他组件产生的事件。根据实现方式的不同,可以...

    jsf中监听器与转换器的使用

    通过实现`javax.faces.event.FacesListener`接口或使用预定义的监听器类,开发者可以注册监听器来响应这些事件。例如,`PhaseListener`允许你在JSF生命周期的不同阶段介入,进行额外的处理或验证。在你的项目中,...

    监听器访问计数过滤非法字符

    首先,我们来看监听器。在Java的Servlet规范中,监听器是一种特殊的Servlet组件,它能够监听特定的事件并作出响应。在"监听器访问计数"的场景下,我们通常会使用HttpSessionListener或者...

    Struts2的监听器的使用

    下面我们将深入探讨Struts2监听器的使用及其在实际开发中的作用。 首先,了解监听器在Web应用中的基本概念。监听器是Servlet容器(如Tomcat)中的特殊Java类,它们实现了特定的监听器接口,并在特定事件发生时被...

    关于过滤器和监听器的使用模板

    在Java Web开发中,过滤器(Filter)和监听器(Listener)是两个非常重要的组件,它们主要用于增强应用程序的功能和管理应用程序的状态。以下是关于这两个概念的详细说明。 **过滤器(Filter)** 过滤器是Servlet...

Global site tag (gtag.js) - Google Analytics