今天来说说程序员小猿和产品就关于需求发生的故事。前不久,小猿收到了产品的需求。

产品经理:小猿,为了迎合大众屌丝用户的口味,我们要放一张图,要露点的。

小猿:......露点?你大爷的,让身为正义与纯洁化身的我做这种需求,还露点。

产品经理:误会误会,是放一张暴露一点点的,尺寸不大。

小猿:尼玛~能说清楚些吗,需求模棱两可的。不干,我要上报boss。

产品经理也一阵无语,这豆丁的事还上报boss。话说这上报也得走程序是吧,技术经理就不干了,“凭什么要跳过我,得经过我才能到boss”。咦~这一层一层上报就涉及到这次的责任链模式。

一、责任链模式

定义

创建多个对象,使这些对象形成一条链,并沿着这条链传递请求,直到链上的某一个对象决定处理此请求。

特点

1)接收请求的对象连接成一条链,对象之间存在层级关系。

2)这些对象可处理请求,也可传递请求,直到有对象处理该请求。

UML

责任链模式涉及到的角色如下所示:

- 抽象处理者角色:定义了处理请求的接口或者抽象类,提供了处理请求的的方法和设置下一个处理者的方法。

- 具体处理者角色:实现或者继承抽象这角色,具体逻辑根据实际的架构来定,后面会提到。

二、实战

先来看抽象处理者角色代码:

public abstract class Handler {

private Handler nextHandler;

private int level;

public Handler(int level) {

this.level = level;

}

// 处理请求传递,注意final,子类不可重写

public final void handleMessage(Demand demand) {

if (level == demand.demandLevel()) {

this.report(demand);

} else {

if (this.nextHandler != null) {

System.out.println("事情太严重,需报告上一级");

this.nextHandler.handleMessage(demand);

} else {

System.out.println("我就是boss,没有上头");

}

}

}

public void setNextHandler(Handler handler) {

this.nextHandler = handler;

}

// 抽象方法,子类实现

public abstract void report(Demand demand);

}

在抽象处理者角色定义了处理请求的抽象方法,以及下一级传递的对象方法,重点在handleMessage处理请求传递的方法,下面会解释为什么要这样写,继续往下看。

下面是具体处理者角色,继承抽象处理者角色,在我们情景中有两个具体处理者,分别是技术经理和boss。

// 技术经理

public class TechnicalManager extends Handler {

public TechnicalManager() {

super(1);

}

@Override

public void report(Demand demand) {

System.out.println("需求:" + demand.detail());

System.out.println(getClass().getSimpleName() + ":小猿我挺你,这个需求不干");

}

}

// boss

public class Boss extends Handler {

public Boss() {

super(2);

}

@Override

public void report(Demand demand) {

System.out.println("需求:" + demand.detail());

System.out.println(getClass().getSimpleName() + ":你们打一架吧,打赢的做决定");

}

}

可以看到具体处理者的代码很简洁,重写了report方法,实现各自的业务逻辑,这都归功于父类中handleMessage这个方法。

两个角色都定义好了,来看客户端如何实现:

public class Client {

public static void main(String[] args) {

Demand demandA = new DemandA(); // 请求等级低

Demand demandB = new DemandB(); // 请求等级高

Boss boss = new Boss();

TechnicalManager technicalManager = new TechnicalManager();

technicalManager.setNextHandler(boss); // 设置下一级

technicalManager.handleMessage(demandA);

System.out.println("============================");

technicalManager.handleMessage(demandB);

}

}

可以看到在客户端中的重点是设置下一级的处理者,这样多个处理者对象就会形成一条链。运行客户端,结果如下:

需求:加一张露一点点的图

TechnicalManager:小猿我挺你,这个需求不干

============================

需求:加一张露一点点的图

TechnicalManager:事情太严重,需报告上一级

Boss:你们打一架吧,打赢的做决定

从结果可以看到,级别低的请求技术经理自己处理,级别高的传递给了下一级的Boss,这样就形成一条链,而这也是责任链的核心所在。注意,在请求的传递过程中,请求是不会发生变化的。需求不会从“加一张露一点点的图”变成了“加一张露点的图”,这等着boss请到办公室喝茶吧。

三、扩展

责任链+模板方法

回头看看上面的代码,抽象类中定义了几个方法,一个是final修饰的handleMessage,一个是抽象方法report,还有一个是setNextHandler。这刚好是模板方法模式中的三个基本方法,分别是具体方法(抽象类声明并实现,子类不实现)、抽象方法(抽象类声明,子类必须实现)、钩子方法(抽象类声明并实现,子类可扩展)。handleMessage方法加了final修饰,子类不可重写,而handleMessage正是把传递请求工作交给父类Handler,子类不需要处理传递的工作。而report则是抽象方法,子类必须重写该方法,子类处理请求的业务逻辑。setNextHandler是钩子方法,在这里我们并没有实现。

这样结合模板方法模式的好处在哪?首先加了handleMessage方法,把请求的传递判断从子类中剥离出来,让子类在report方法中专心处理请求的业务逻辑,做到了单一职责原则。再者是子类的实现变得简单了,不需要进行传递的判断,非常有利于快速扩展。

责任链模式VS观察者模式

观察者模式我在之前有些过,不了解的可以先看看。责任链模式和观察者模式存在一个共同点,就是传递责任链模式是一级一级的传递,形成一条链,链节点(处理者)之间是存在传递关系的。而观察者模式的被观察者向观察者们的传递,并不是具体观察者之间的传递,观察者之间是不存在关联的。拿小猿的经历来说,在责任链模式中是请求从技术经理到boss,有层级关系,而对于观察者模式是从被观察者小猿发出,作为观察者的技术经理和boss都会收到小猿的通知,是扩散式的,技术经理和boss并没有层级关系。这是责任链模式和观察者模式的区别,也是责任链模式的核心。

四、责任链模式的优缺点

优点

1)降低耦合度:客户端不需要知道请求由哪个处理者处理,而处理者也不需要知道处理者之间的传递关系,由系统灵活的组织和分配。

2)良好的扩展性:增加处理者的实现很简单,只需重写处理请求业务逻辑的方法。

缺点

1)请求会从链头发出,直到有处理者响应,在责任链比较长的时候会影响系统性能。

2)请求递归,调试排错比较麻烦。

总结

责任链模式在实际项目中可以用到的地方还是比较多的,比如会员等级系统,会员等级之间构成一条链,用户发起一个请求,系统只要把请求分发到责任链模式的入口,直到传递到与用户会员匹配的等级,这样各个会员等级的业务逻辑就会变成很清晰。这篇折腾了很久,主要是想把责任链的核心阐述清楚,让大家能够容易理解,也让我重新思考了责任链模式的核心。下一篇是“还没想好”,您的点赞和关注是我的动力哦,再会!

java实现责任链模式_我的Java设计模式-责任链模式相关推荐

  1. java bridge 模式_学习:java设计模式—Bridge模式

    一.引子 下面是吕振宇大牛的一个例子,个人觉得挺好的,有助于理解Bridge模式的设计目的: 设想要绘制一幅图画,蓝天.白云.绿树.小鸟,如果画面尺寸很大,那么用蜡笔绘制就会遇到点麻烦.毕竟细细的蜡笔 ...

  2. java 面试题合集_撩课-Java面试题合辑1-50题

    1.简述JDK.JRE.JVM? 一.JDK JDK(Java Development Kit) 是整个JAVA的核心, 包括了Java运行环境(Java Runtime Envirnment), 一 ...

  3. 深入java虚拟机 第四版_深入理解Java虚拟机-常用vm参数分析

    Java虚拟机深入理解系列全部文章更新中... https://blog.ouyangsihai.cn/shen-ru-li-jie-java-xu-ni-ji-java-nei-cun-qu-yu- ...

  4. java的应用程序开发_开发一个Java应用程序(1)

    开发一个Java应用程序(1) App Engine上的Java Web应用程序通过Java Servlet标准接口与应用程序服务器交互.一个应用程序由一个或多个类组成,这些类都扩展自一个servle ...

  5. java带参数的构造方法_看了Java的Class的源码,我自闭了

    作者丨chenweicool 来源:https://www.cnblogs.com/chentang/p/13170081.html 1.class这个类是什么 Class的本质也是一个类,只不过它是 ...

  6. java策略模式详解_Java经典设计模式之策略模式原理与用法详解

    本文实例讲述了Java经典设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式指:策略模式指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式 ...

  7. lgv50怎么进入fastboot模式_智能手机Fastboot功能!进入Fastboot模式设置

    原标题:智能手机Fastboot功能!进入Fastboot模式设置 智能手机Fastboot功能!进入Fastboot模式设置?Fastboot根据中文的翻译是手机快速启动的意思.在安卓手机中fast ...

  8. java中io是什么_深入理解Java中的IO

    深入理解Java中的IO 转载自:http://blog.csdn.net/qq_25184739/article/details/51205186 本文的目录视图如下: Java IO概要 a.Ja ...

  9. 有谁转行学java成功了的吗_转行学习java靠谱吗?

    转行学Java靠谱吗?靠不靠谱主要还是看你自己是否想要学好Java技术,是否想要从事这方面的岗位工作,如果你已经有了这个决心,那么自然而然什么都不会问题.无论我们学Java是兴趣还是想要通过学好Jav ...

最新文章

  1. watchOS 5 新特性:继续发力运动与健身
  2. 一文教你如何高效使用 IDEA !
  3. UA MATH563 概率论的数学基础1 概率空间3 概率测度
  4. 北大igem生物计算机,正在报名 | 2019国际基因工程机器大赛(iGEM)
  5. InChatter系统开源聊天模块前奏曲
  6. js设置奇偶行数样式
  7. Java VM –提防YoungGen空间
  8. python学习笔记--迭代器
  9. 2019最受欢迎数据库:MySQL居首PostgreSQL第二Oracle位列第八
  10. 设计模式—单例模式(思维导图)
  11. php 调用高拍仪,html页面通过ActiveX控件调用摄像头实现拍照上传demo代码下载
  12. 热门论坛排行top100--2010年07月11日[转]
  13. vue实现更换背景图片_Vue实现背景更换颜色操作
  14. KOL投放指南(六) :品牌五一借势营销大盘点!
  15. ## 纯干货|UI设计字体分类、使用标准及测量内容
  16. 【C++】用代码写一个气派的圣诞树发给身边的亲朋好友
  17. Ubuntu16.04下fctix无法切换中英文输入法
  18. JSON-handle 插件增加“去除转义”功能
  19. 常用数据结构和算法总结
  20. 用“找回你”,查找手机号的前身都被注册过些什么……

热门文章

  1. 求解带时间窗车辆路径问题的多目标模因算法
  2. 多网卡指定网卡发送数据
  3. VC++使用Soap ToolKit3.0调用WebService接口
  4. Flask-分开Models解决循环引用
  5. Windows7下安装LabelImg标注工具
  6. predicate java_java代码之美(13)--- Predicate详解
  7. unet 层_UNet解释及Python实现
  8. mysql里guest用户_MySQL用户权限分配
  9. 树莓派学习笔记——GPIO功能学习
  10. SVN提示:由于目标机器积极拒绝,无法连接 的解决方法