责任链模式大家应该都清楚,比如JS中的冒泡,Java中的拦截器、过滤器,都运用到了责任链模式。

可以看我之前的文章介绍责任链的:https://www.cnblogs.com/wuguanglin/p/ChainofResponsibilityPattern.html

我们在遇到一个请求,经过多个节点处理的时候就可以考虑使用责任链模式降低代码耦合度。

纯责任链模式

在es6 class语法下,我们可能会写出下面这样的代码:

  1. 'use strict';
  2.  
  3. class HandlerFactory {
  4. createHandler() {
  5. const aaa = new AaaHandler();
  6. const bbb = new BbbHandler();
  7. const ccc = new CccHandler();
  8. const ddd = new DddHandler();
  9. const eee = new EeeHandler();
  10. aaa.setNext(bbb);
  11. bbb.setNext(ccc);
  12. ccc.setNext(ddd);
  13. ddd.setNext(eee);
  14. return aaa;
  15. }
  16. }
  17.  
  18. class Handler {
  19. setNext(_handler) {
  20. this.nextHandler = _handler;
  21. }
  22. handleMsg(msg) {}
  23. }
  24. class AaaHandler extends Handler {
  25. handleMsg(msg) {
  26. if (msg < 0.2) {
  27. console.log('AaaHandler处理了:' + msg);
  28. } else {
  29. this.nextHandler.handleMsg(msg);
  30. }
  31. }
  32. }
  33.  
  34. class BbbHandler extends Handler {
  35. handleMsg(msg) {
  36. if (msg < 0.3) {
  37. console.log('BbbHandler处理了:' + msg);
  38. } else {
  39. this.nextHandler.handleMsg(msg);
  40. }
  41. }
  42. }
  43.  
  44. class CccHandler extends Handler {
  45. handleMsg(msg) {
  46. if (msg < 0.5) {
  47. console.log('CccHandler处理了:' + msg);
  48. } else {
  49. this.nextHandler.handleMsg(msg);
  50. }
  51. }
  52. }
  53.  
  54. class DddHandler extends Handler {
  55. handleMsg(msg) {
  56. if (msg < 0.6) {
  57. console.log('DddHandler处理了:' + msg);
  58. } else {
  59. this.nextHandler.handleMsg(msg);
  60. }
  61. }
  62. }
  63.  
  64. class EeeHandler extends Handler {
  65. handleMsg(msg) {
  66. if (msg < 0.8) {
  67. console.log('EeeHandler处理了:' + msg);
  68. } else {
  69. console.log('没有handler可以处理了:' + msg);
  70. }
  71. }
  72. }
  73.  
  74. const handlerFactory = new HandlerFactory();
  75. const handler = handlerFactory.createHandler();
  76. handler.handleMsg(Math.random());

代码的大概意思就是构建了一个msg处理链。但是我们可以看到这种实现方式还是觉得有点不太完美,不完美的地方在哪呢?

就是在于不断的setNext()设置下一个处理者,每个处理者的后继者都是由它自己维护的,也就是整个链条的关系是由所有的处理者共同维护的。所以这里可以优化,我们可以通过AOP(切面编程)的思想来把责任链抽象出来,解除链条与处理者的耦合关系。

非纯责任链模式

Talk is cheap,Show me the code

  1. 'use strict';
  2.  
  3. class HandlerChainFactory {
  4. createHandlerChain() {
  5. const handlers = [];
  6. handlers.push(new AaaHandler());
  7. handlers.push(new BbbHandler());
  8. handlers.push(new CccHandler());
  9. handlers.push(new DddHandler());
  10. handlers.push(new EeeHandler());
  11. return new HandlerChain(handlers);
  12. }
  13. }
  14.  
  15. class HandlerChain {
  16. constructor(handlers) {
  17. this.handlers = handlers;
  18. }
  19. handleMsg(msg) {
  20. if (this.handlers.length) {
  21. const handler = this.handlers.shift();
  22. handler.handleMsg(msg, this);
  23. } else {
  24. console.log('没有handler:' + msg);
  25. }
  26. }
  27. }
  28.  
  29. class AaaHandler {
  30. handleMsg(msg, chain) {
  31. if (msg < 0.2) {
  32. console.log('AaaHandler处理了:' + msg);
  33. } else {
  34. chain.handleMsg(msg);
  35. }
  36. }
  37. }
  38.  
  39. class BbbHandler {
  40. handleMsg(msg, chain) {
  41. if (msg < 0.3) {
  42. console.log('BbbHandler处理了:' + msg);
  43. } else {
  44. chain.handleMsg(msg);
  45. }
  46. }
  47. }
  48.  
  49. class CccHandler {
  50. handleMsg(msg, chain) {
  51. if (msg < 0.5) {
  52. console.log('CccHandler处理了:' + msg);
  53. } else {
  54. chain.handleMsg(msg);
  55. }
  56. }
  57. }
  58.  
  59. class DddHandler {
  60. handleMsg(msg, chain) {
  61. if (msg < 0.6) {
  62. console.log('DddHandler处理了:' + msg);
  63. } else {
  64. chain.handleMsg(msg);
  65. }
  66. }
  67. }
  68.  
  69. class EeeHandler {
  70. handleMsg(msg, chain) {
  71. if (msg < 0.8) {
  72. console.log('EeeHandler处理了:' + msg);
  73. } else {
  74. console.log('没有handler可以处理了:' + msg);
  75. }
  76. }
  77. }
  78.  
  79. const handlerChainFactory = new HandlerChainFactory();
  80. const handleChain = handlerChainFactory.createHandlerChain();
  81. handleChain.handleMsg(Math.random());

可以看到,改进后的责任链模式,代码更加清晰了,希望对大家有帮助。

es6 class中责任链模式与AOP结合的更多相关文章

  1. mina中责任链模式的实现

    一.mina的框架回顾 责任链模式在mina中有重要的作用,其中Filter机制就是基于责任链实现的. 从上图看到消息的接受从IoService层先经过Filter层过滤处理后最后交给IoHander ...

  2. Activiti工作流学习笔记(四)——工作流引擎中责任链模式的建立与应用原理

    原创/朱季谦 本文需要一定责任链模式的基础,主要分成三部分讲解: 一.简单理解责任链模式概念 二.Activiti工作流里责任链模式的建立 三.Activiti工作流里责任链模式的应用 一.简单理解责 ...

  3. C#设计模式-责任链模式

    在现实生活中,有很多请求并不是一个人说了就算的,例如面试时的工资,低于1万的薪水可能技术经理就可以决定了,但是1万~1万5的薪水可能技术经理就没这个权利批准,可能就需要请求技术总监的批准,所以在面试的 ...

  4. C#设计模式(21)——责任链模式

    一.引言 在现实生活中,有很多请求并不是一个人说了就算的,例如面试时的工资,低于1万的薪水可能技术经理就可以决定了,但是1万~1万5的薪水可能技术经理就没这个权利批准,可能就需要请求技术总监的批准,所 ...

  5. 设计模式学习之责任链模式(Chain of Responsibility,行为型模式)(22)

    参考:http://www.cnblogs.com/zhili/p/ChainOfResponsibity.html 一.引言 在现实生活中,有很多请求并不是一个人说了就算的,例如面试时的工资,低于1 ...

  6. Java设计模式13:责任链模式

    前言 来菜鸟这个大家庭10个月了,总得来说比较融入了环境,同时在忙碌的工作中也深感技术积累不够,在优秀的人身边工作必须更加花时间去提升自己的技术能力.技术视野,所以开一个系列文章,标题就轻松一点叫做最 ...

  7. 拦截器——原理(AOP、责任链模式、配置)

    1.Struts2拦截器概述: (1)Struts2框架封装中封装了很多功能,这些功能其实都是封装在Struts2的拦截器里面,Struts2里面有很多拦截器,每次不是这些拦截器都执行,每次只执行默认 ...

  8. [工作中的设计模式]责任链模式chain

    一.模式解析 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知 ...

  9. java设计模式之责任链模式以及在java中作用

    责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个 ...

随机推荐

  1. Spring boot +mybatis 连接mysql数据库,获取JDBC失败,服务器时区价值”Oйu±e×¼e±¼的识别或代表多个时区

    报出的错误 Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connec ...

  2. leetcode 之 Two Sum II - Input array is sorted c++

    class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { int ...

  3. win7 64位系统下安装autoitlibrary库遇到问题解决

    转载来自http://blog.sina.com.cn/s/blog_53f023270101skyq.html 今天需要在win7 64位系统下安装autoitlibrary库,起初安装好了robo ...

  4. H3C设备系列问题

    一.h3c交换器和交换机的Telnet或SSH登录用户名和密码忘记了,怎么办? 处理步骤: 1.使用Console线连接交换机或路由器的Console口,确保笔记本已连上设备,在设备启动过程中根据提示 ...

  5. 21.命名空间别名限定符::和global全局名称空间限定符

    命名空间别名限定符(::)用于查找标识符,它在指定的别名的命名空间中查找运算符,如下代码是在全局名称空间中查找System.Console.WriteLine("Hello World&qu ...

  6. node+webpack+vue-cli

     安装nodejs + 安装webpack + 安装vue-cli+安装脚手架模板+安装依赖+运行 1 安装nodejs 去官网安装node.js( http://www.runoob.com/nod ...

  7. 北京大学Cousera学习笔记--2-计算导论与C语言基础-第一讲.计算机的基本原理-图灵机

    有限状态读写头从一个初始状态开始,对存储器上的输入数据进行读或写操作,经过有限步操作之后停机,此时存储器上的输出数据就是计算结果 (1) 图灵机的构成: 1.一条存储带:双向无限延长:上有一个个的小方 ...

  8. NGUI之实现连连看小游戏

    一,部分游戏规则如下: 二,代码如下: 1. 游戏逻辑核心代码 using System.Collections.Generic; using UnityEngine; namespace Modul ...

  9. 18.11.20-C语言练习-根据输入统计字符类型

    一.题目: 二.C程序:(注意:中文部分是程序注释,如果编译器不支持中文,需要把中文删掉) #include <stdio.h> int main() { ; //保存字母数量 ; //保 ...

  10. 从网卡发送数据再谈TCP/IP协议—网络传输速度计算-网卡构造

    在<在深谈TCP/IP三步握手&四步挥手原理及衍生问题—长文解剖IP>里面提到 单个TCP包每次打包1448字节的数据进行发送(以太网Ethernet最大的数据帧是1518字节,以 ...