设计模式系列 - Chain of Responsibility模式

简介:

1、引入: 从击鼓传花谈起

  击鼓传花是一种热闹而又紧张的饮酒游戏。在酒宴上宾客依次坐定位置,由一人击鼓,击鼓的地方与传花的地方是分开的,以示公正。开始击鼓时,花束就开始依次传递,鼓声一落,如果花束在某人手中,则该人就得饮酒。
  假比说,贾母、贾赦、贾政、贾宝玉和贾环是五个参加击鼓传花游戏的传花者,他们组成一个环链。击鼓者将花传给贾母,开始传花游戏。花由贾母传给贾赦,由贾赦传给贾政,由贾政传给贾宝玉,又由贾宝玉传给贾环,由贾环传回给贾母,如此往复(见下图)。当鼓声停止时,手中有花的人就得执行酒令。
    
  图1、击鼓传花。
  击鼓传花便是责任链模式的应用。在责任链模式里,很多的对象由每一个对象对其下家的引用而联接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
  责任链可能是一条直线、一个环链甚至一个树结构的一部分。
2、责任链模式的结构

 GoF对职责链模式的定义为:为了避免请求的发送者和接收者之间的耦合关系,使多个接受对象都有机会处理请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。通俗一点说就是,当客户提交一个请求时,从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。提交请求的对象并不知道哪一个对象将会处理它。当然职责链中也可能没有可以处理该请求的对象,这种情况是允许发生的。

 责任链模式是一种对象的行为模式,它所涉及到的角色如下:
  第一、抽象处理者(Handler)角色、定义出一个处理请求的接口;如果需要,接口可以定义出一个方法,以返回对下家的引用。下图给出了一个示意性的类图:
    
  图2、抽象处理者角色。 
  在图中的积累关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
  第二、具体处理者(ConcreteHandler)角色、处理接到请求后,可以选择将请求处理掉,或者将请 求传给下家。下图给出了一个示意性的类图。
   
   图3、具体处理者角色。 
  上图中的示意性的具体处理者ConcreteHandler类只有handleRequest()一个方法。
  责任链模式的静态类结构可见下图:
   
  图4、责任链模式的类图定义。

3、代码实例

 


 
 
  1. public interface Handler { 
  2.     public void handleRequest(String request); 

 


 
 
  1. public class HighRiskHandler implements Handler{ 
  2.     private static String[] riskWords= {"李刚","蒜你狠","豆你玩"}; 
  3.      
  4.     private Handler nextHandler; 
  5.  
  6.     public HighRiskHandler(Handler handler){ 
  7.         this.nextHandler = handler; 
  8.     } 
  9.  
  10.     public void handleRequest(String request){ 
  11.         //process request 
  12.         for(String risk : riskWords){ 
  13.             request = request.replaceAll(risk, ""); 
  14.         } 
  15.         // next processor 
  16.         nextHandler.handleRequest(request); 
  17.          
  18.     } 

 


 
 
  1. import org.slf4j.Logger; 
  2. import org.slf4j.LoggerFactory; 
  3.  
  4. public class LoggingFilter implements Handler { 
  5.     private static Logger logger = LoggerFactory.getLogger(LoggingFilter.class); 
  6.  
  7.     private Handler nextHandler; 
  8.  
  9.     public LoggingFilter(Handler handler) { 
  10.         this.nextHandler = handler; 
  11.     } 
  12.  
  13.     @Override 
  14.     public void handleRequest(String request) { 
  15.         logger.info("before " + request); 
  16.         this.nextHandler.handleRequest(request); 
  17.         logger.info("after " + request); 
  18.     } 
  19.  

 

 

【注意】

1、与观察者模式的区别

观察者模式重点在于变化是通知各个观察者,各观察者观察到的信息是相同的;而责任链模式在于使用链条的方式处理发送的内容,链条的前一环节处理之后的内容传递到下一环节,前面处理的结果可能会对后面的处理有影响

2、与装饰者模式的区别

装饰者模式重点在于加上各种修饰;责任链模式重在各个链条的处理,在调用的前后加上各种处理,中间可能存在堆栈调用的问题, 存在A前->B前->B后->A后的堆栈调用的情况

 

 本文转自 tianya23 51CTO博客,原文链接:http://blog.51cto.com/tianya23/536838,如需转载请自行联系原作者

相关文章
|
15天前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
4月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
2月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
2月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
51 1
|
3月前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
35 3
|
4月前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
|
3月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
47 0
|
4月前
|
设计模式 Java
Java设计模式-工厂方法模式(4)
Java设计模式-工厂方法模式(4)