Chinaunix首页 | 论坛 | 博客
  • 博客访问: 276790
  • 博文数量: 83
  • 博客积分: 2393
  • 博客等级: 大尉
  • 技术积分: 640
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-24 15:14
文章分类

全部博文(83)

文章存档

2019年(21)

2011年(5)

2010年(2)

2009年(1)

2008年(9)

2007年(33)

2006年(12)

我的朋友

分类: Java

2019-08-24 23:17:57



责任链模式



顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
介绍
意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
何时使用:在处理消息的时候以过滤很多道。
如何解决:拦截的类都实现统一接口。
关键代码:Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。
应用实例: 1、红楼梦中的"击鼓传花"。 2、JS 中的事件冒泡。 3、JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。
优点: 1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。

缺点: 1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。 3、可能不容易观察运行时的特征,有碍于除错。
使用场景: 1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。

注意事项:在 JAVA WEB 中遇到很多应用。

以下转载自https://www.cnblogs.com/coshaho/p/6815490.html


责任链模式
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
生产一个产品,需要依次执行多个步骤,才能完成,那么是使用责任链模式则是极好的。
在性能告警模块开发过程中,创建一条告警规则需要执行阈值解析,中间表生成,流任务生成,规则入库,告警事件入库等诸多操作。如果把这些步骤糅合在一个类中,代码可读性及复杂度往往是灾难的,特别对于这么多步骤的事务性操作,更是力不从心。使用责任链模式,上述问题迎刃而解。
以告警规则创建为例子,简化流程如下
阈值解析 ---> 流任务生成 ---> 规则入库
回滚流程如下
1、 阈值解析失败:回滚阈值解析。
2、 流任务生产失败:回滚流任务生成,阈值解析。
3、 规则入库失败:回滚规则入库,流任务生成,阈值解析。
采用责任链模式编码,思路如下:
1、 编写阈值解析处理器,流任务生成处理器,规则入库处理器,每个处理器包含业务处理方法和回滚方法;
2、 一个处理器业务代码执行完成后主动调用下一个处理器业务方法;
3、 一个处理器业务代码执行失败主动调用本处理器回滚方法,本处理器回滚完成后主动调用上一个处理器回滚方法。

代码如下
1、 抽象处理器


点击(此处)折叠或打开

  1. package com.coshaho.learn.handler;

  2. /**
  3.  *
  4.  * AbstractRuleHandler.java Create on 2017年5月5日 下午11:20:15
  5.  *
  6.  * 类功能说明: 告警规则责任链处理节点抽象类
  7.  *
  8.  * Copyright: Copyright(c) 2013
  9.  * Company: COSHAHO
  10.  * @Version 1.0
  11.  * @Author coshaho
  12.  */
  13. public abstract class AbstractRuleHandler
  14. {
  15.     // 上一个处理器
  16.     private AbstractRuleHandler preHandler;
  17.     
  18.     // 下一个处理器
  19.     private AbstractRuleHandler nextHandler;
  20.     
  21.     /**
  22.      * 业务执行
  23.      *
  24.      * @author coshaho
  25.      * @param rule
  26.      */
  27.     public void doHandle(AlarmRule rule)
  28.     {
  29.         try
  30.         {
  31.             doHandleReal(rule);
  32.         }
  33.         catch(Exception e)
  34.         {
  35.             // 业务代码执行失败主动回滚
  36.             rollBack(rule);
  37.             return;

  38.         }
  39.         
  40.         // 业务代码执行成功主动调用下一个处理器处理
  41.         if(null != nextHandler)
  42.         {
  43.             nextHandler.doHandle(rule);
  44.         }
  45.     }
  46.     
  47.     /**
  48.      * 事务回滚
  49.      *
  50.      * @author coshaho
  51.      * @param rule
  52.      */
  53.     public void rollBack(AlarmRule rule)
  54.     {
  55.         rollBackReal(rule);
  56.         // 本处理器业务回滚完成,主动调用前一个处理器业务回滚
  57.         if(null != preHandler)
  58.         {
  59.             preHandler.rollBack(rule);
  60.         }
  61.     }
  62.     
  63.     /**
  64.      * 每个处理器特有的业务处理方法
  65.      *
  66.      * @author coshaho
  67.      * @param rule
  68.      * @throws Exception
  69.      */
  70.     public abstract void doHandleReal(AlarmRule rule) throws Exception;
  71.     
  72.     /**
  73.      * 每个处理器特有的业务回滚方法
  74.      *
  75.      * @author coshaho
  76.      * @param rule
  77.      */
  78.     public abstract void rollBackReal(AlarmRule rule);

  79.     private AbstractRuleHandler setPreHandler(AbstractRuleHandler preHandler)
  80.     {
  81.         this.preHandler = preHandler;
  82.         return preHandler;
  83.     }

  84.     public AbstractRuleHandler setNextHandler(AbstractRuleHandler nextHandler)
  85.     {
  86.         this.nextHandler = nextHandler;
  87.         nextHandler.setPreHandler(this);
  88.         return nextHandler;
  89.     }

  90. }

2、阈值解析处理器

点击(此处)折叠或打开

  1. package com.coshaho.learn.handler;

  2. import org.apache.commons.lang.StringUtils;

  3. /**
  4.  *
  5.  * ThresholdParseHandler.java Create on 2017年5月5日 下午11:41:20
  6.  *
  7.  * 类功能说明: 阈值解析
  8.  *
  9.  * Copyright: Copyright(c) 2013
  10.  * Company: COSHAHO
  11.  * @Version 1.0
  12.  * @Author coshaho
  13.  */
  14. public class ThresholdParseHandler extends AbstractRuleHandler
  15. {

  16.     @Override
  17.     public void doHandleReal(AlarmRule rule) throws Exception
  18.     {
  19.         if(StringUtils.isEmpty(rule.getThreshold()))
  20.         {
  21.             throw new Exception("Threshold is empty.");
  22.         }
  23.         System.out.println("Parse threshold success. Threshold is " + rule.getThreshold());
  24.     }

  25.     @Override
  26.     public void rollBackReal(AlarmRule rule)
  27.     {
  28.         System.out.println("Roll parse threshold. Threshold is " + rule.getThreshold());
  29.     }

  30. }
3、流任务生成处理器

点击(此处)折叠或打开

  1. package com.coshaho.learn.handler;

  2. /**
  3.  *
  4.  * StreamGenerateHandler.java Create on 2017年5月5日 下午11:41:43
  5.  *
  6.  * 类功能说明: 告警流规则生成
  7.  *
  8.  * Copyright: Copyright(c) 2013
  9.  * Company: COSHAHO
  10.  * @Version 1.0
  11.  * @Author coshaho
  12.  */
  13. public class StreamGenerateHandler extends AbstractRuleHandler
  14. {

  15.     @Override
  16.     public void doHandleReal(AlarmRule rule) throws Exception
  17.     {
  18.         System.out.println("Generate stream success.");
  19.     }

  20.     @Override
  21.     public void rollBackReal(AlarmRule rule)
  22.     {
  23.         System.out.println("Roll Generate stream.");
  24.     }

  25. }
4、规则入库处理器

点击(此处)折叠或打开

  1. package com.coshaho.learn.handler;

  2. import org.apache.commons.lang.StringUtils;

  3. /**
  4.  *
  5.  * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08
  6.  *
  7.  * 类功能说明: 告警规则持久化
  8.  *
  9.  * Copyright: Copyright(c) 2013
  10.  * Company: COSHAHO
  11.  * @Version 1.0
  12.  * @Author coshaho
  13.  */
  14. public class RulePesistHandler extends AbstractRuleHandler
  15. {

  16.     @Override
  17.     public void doHandleReal(AlarmRule rule) throws Exception {
  18.         if(StringUtils.isEmpty(rule.getName()))
  19.         {
  20.             throw new Exception("Rule name is empty.");
  21.         }
  22.         System.out.println("Persist rule success. Rule name is " + rule.getName());
  23.     }

  24.     @Override
  25.     public void rollBackReal(AlarmRule rule) {
  26.         System.out.println("Roll persist rule. Rule name is " + rule.getName());
  27.         
  28.     }

  29. }
5、规则入库处理器

点击(此处)折叠或打开

  1. package com.coshaho.learn.handler;

  2. import org.apache.commons.lang.StringUtils;

  3. /**
  4.  *
  5.  * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08
  6.  *
  7.  * 类功能说明: 告警规则持久化
  8.  *
  9.  * Copyright: Copyright(c) 2013
  10.  * Company: COSHAHO
  11.  * @Version 1.0
  12.  * @Author coshaho
  13.  */
  14. public class RulePesistHandler extends AbstractRuleHandler
  15. {

  16.     @Override
  17.     public void doHandleReal(AlarmRule rule) throws Exception {
  18.         if(StringUtils.isEmpty(rule.getName()))
  19.         {
  20.             throw new Exception("Rule name is empty.");
  21.         }
  22.         System.out.println("Persist rule success. Rule name is " + rule.getName());
  23.     }

  24.     @Override
  25.     public void rollBackReal(AlarmRule rule) {
  26.         System.out.println("Roll persist rule. Rule name is " + rule.getName());
  27.         
  28.     }

  29. }

6、告警规则

点击(此处)折叠或打开

  1. package com.coshaho.learn.handler;

  2. /**
  3.  *
  4.  * AlarmRule.java Create on 2017年5月5日 下午11:40:50
  5.  *
  6.  * 类功能说明: 告警规则
  7.  *
  8.  * Copyright: Copyright(c) 2013
  9.  * Company: COSHAHO
  10.  * @Version 1.0
  11.  * @Author coshaho
  12.  */
  13. public class AlarmRule
  14. {
  15.     private String name;
  16.     
  17.     private String type;
  18.     
  19.     private String threshold;
  20.     
  21.     public String getName() {
  22.         return name;
  23.     }
  24.     public void setName(String name) {
  25.         this.name = name;
  26.     }
  27.     public String getType() {
  28.         return type;
  29.     }
  30.     public void setType(String type) {
  31.         this.type = type;
  32.     }
  33.     public String getThreshold() {
  34.         return threshold;
  35.     }
  36.     public void setThreshold(String threshold) {
  37.         this.threshold = threshold;
  38.     }
  39. }
7、规则创建责任链

点击(此处)折叠或打开

  1. package com.coshaho.learn.handler;

  2. /**
  3.  *
  4.  * AlarmRuleCreator.java Create on 2017年5月5日 下午11:56:45
  5.  *
  6.  * 类功能说明: 告警规则创建
  7.  *
  8.  * Copyright: Copyright(c) 2013
  9.  * Company: COSHAHO
  10.  * @Version 1.0
  11.  * @Author coshaho
  12.  */
  13. public class AlarmRuleCreator
  14. {
  15.     private AbstractRuleHandler alarmRuleHandler;
  16.     public AlarmRuleCreator()
  17.     {
  18.         alarmRuleHandler = new ThresholdParseHandler();
  19.         alarmRuleHandler.setNextHandler(new StreamGenerateHandler())
  20.                 .setNextHandler(new RulePesistHandler());
  21.     }
  22.     
  23.     public void create(AlarmRule rule)
  24.     {
  25.         alarmRuleHandler.doHandle(rule);
  26.     }
  27.     public static void main(String[] args)
  28.     {
  29.         AlarmRule rule = new AlarmRule();
  30.         rule.setThreshold("cpuRate < 10");
  31.         rule.setName("Cpu Alarm");
  32.         
  33.         AlarmRuleCreator ruleCreator = new AlarmRuleCreator();
  34.         ruleCreator.create(rule);
  35.         System.out.println();
  36.         
  37.         rule.setName("");
  38.         ruleCreator.create(rule);
  39.     }

  40. }





阅读(844) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~