专栏首页Open软件开发小组Java设计模式精讲(一):责任链模式

Java设计模式精讲(一):责任链模式

前言

这篇分享作为一个系列分享的第一篇,主要和大家一起学习一下java设计模式方面的基础,我们现在的安卓开发主要还是基于java语言,所以掌握java本身的基础也是非常重要的。

在j2ee、web和安卓其他一些java程序开发领域,设计模式被普遍使用,设置模式本身功能并不是体现在优化程序性能,选择一个合适设置模式来构建程序,能让我们的程序整体的设计更加合理,思路更加清晰,在后期面对复杂需求变化能够从容应对,在很大程度上减少代码逻辑性的错误。 这个系列会在后面逐渐分享出来,和大家一起学习进步,暂定包括责任链模式、享元模式、外观模式、适配器模式、命令模式、中介者模式、观察者模式、状态模式、模版方法模式、访问者模式。后续有机会也会增加其他的。

什么是责任链模式

什么是责任链模式?打个比方类似击鼓传花,花束在每个人手里开始传递,鼓声一落,谁拿到花,谁就要背锅。正式的解释是,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

场景

纯的责任链事例。李四生病了,去大医院看医生,他自己认为是去外科就行,结果去了后外科医生告诉他这个他医不了,让他去耳鼻科看看。于是李四又到了耳鼻科,耳鼻科医生看了下,发现李四的病情严重了,就告诉他这个他搞不定,让他去急症科。于是李四又到了急症科,最后急症科医好了李四的病。

AbstractSickHandler:

public abstract class AbstractSickHandler {
private AbstractSickHandler successor;
public void setSuccessor(AbstractSickHandler successor) {
   this.successor = successor;
}
protected abstract boolean isMyResponsibility(String illCase);
public void handleSick(String personName,String illCase) {
   if (isMyResponsibility(illCase)) {
       doMyJob(personName,illCase);
   } else {
       if (!ParamUtils.isNull(successor)) {
           successor.handleSick(personName,illCase);
       } else {
           LogUtil.printWithSystemErr("完蛋了,没救了");
       }
   }
}
protected abstract void doMyJob(String personName,String illCase);
}

EmergencySickHandler:

public class EmergencySickHandler extends AbstractSickHandler {@Override
protected boolean isMyResponsibility(String illCase) {
   if(illCase.equals("耳鼻喉科")){
       return true;
   }   LogUtil.printWithSystemOut("耳鼻喉科医生:不是我的责任");
   return false;
}@Override
protected void doMyJob(String personName, String illCase) {
   LogUtil.printWithSystemErr("耳鼻喉科医生:"+personName+", 你这病我能医好,给你开了两服药,按时吃就好了");
}

}

GeneralSurgerySickHandler

public class GeneralSurgerySickHandler extends AbstractSickHandler {@Override
protected boolean isMyResponsibility(String illCase) {
   if(illCase.equals("普通外科")){
       return true;
   }   LogUtil.printWithSystemOut("普通外科:不是我的责任");
   return false;
}@Override
protected void doMyJob(String personName, String illCase) {
   LogUtil.printWithSystemErr("普通外科医生:"+personName+", 你这病我能医好,给你开了两服药,按时吃就好了");
}
}

OtolaryngologySickHandler

public class OtolaryngologySickHandler extends AbstractSickHandler {@Override
protected boolean isMyResponsibility(String illCase) {
   if(illCase.equals("急诊科")){
       return true;
   }   LogUtil.printWithSystemOut("急诊科医生:不是我的责任");
   return false;
}@Override
protected void doMyJob(String personName, String illCase) {
   LogUtil.printWithSystemErr("急诊科医生:"+personName+", 你这病我能医好,给你开了两服药,按时吃就好了");
}
}public class SimplePatternRun implements IPatternRun{
@Override
public void run() {
   String personName = "李四";
   String illCase = "普通外科";   EmergencySickHandler emergencySickHandler = new  EmergencySickHandler();
   GeneralSurgerySickHandler generalSurgerySickHandler = new  GeneralSurgerySickHandler();
   OtolaryngologySickHandler otolaryngologySickHandler = new  OtolaryngologySickHandler();
   emergencySickHandler.setSuccessor(generalSurgerySickHandler);
   generalSurgerySickHandler.setSuccessor(otolaryngologySickHandler);   emergencySickHandler.handleSick(personName, illCase);
}
}

模式优缺点

1) 降低耦合度

该模式使得一个对象无需知道是其他哪一个对象处理其请求。对象仅需知道该请求会被“正确”地处理。接收者和发送者都没有对方的明确的信息,且链中的对象不需知道链的结构。结果是,职责链可简化对象的相互连接。它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。

2) 增强了给对象指派职责(Responsibilibty) 的灵活性

当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责。你可以将这种机制与静态的特例化处理对象的继承机制结合起来使用。

3) 不保证被接受

既然一个请求没有明确的接收者,那么就不能保证它一定会被处理 —该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。

模式适用性

A、有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。

B、你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

C、可处理一个请求的对象集合应被动态指定。

本文分享自微信公众号 - Open软件开发小组(open_dev),作者:俊爷

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-07-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • AndroidLintWatchDog Custom-Lint 自定义Lint检查的实现

    Android自定义Lint检查有效提升代码质量、避免人工的低级失误、规范代码,属于程序自动化的内容,这部分内容涉及的资料较少,但是实际意义重大...

    open
  • Android后台发送邮件进行日志反馈

    最近在和解决用户反馈的问题,但是出现了不方便的事情.就是获取用户操作日志的问题.想来想去还是用比较隐晦的方法---发送邮件.(需要告知用户,不然会当成流氓的!)

    open
  • [Android技术专题]每个开发者都应该懂一点单元测试

    笔者在项目中实际有写过单元测试的代码,也用过一些单元测试的框架,但对单元测试的理解都很浅显,直到有一次在InfoQ编辑徐川主导的微信群里面看了蘑...

    open
  • 设计模式之备忘录模式

    备忘录模式(Momento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保...

    Dylan Liu
  • 解析JSON数组正常,却在获取数组元素时抛出了类型转换异常

    下面这段代码会抛出类型转换异常(ClassCastException),JVM给出的解释是:不能将Double类型对象转换String类型 (java.lang...

    wujiuye
  • Android 二次封装网络加载框架

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/de...

    用户2965908
  • Spring中的SpEL表达式概述

    <bean id="numberGuess" class="org.spring.samples.NumberGuess"> <property name="...

    cwl_java
  • 图像去模糊算法 循序渐进 附完整代码

    这样看,虽然知道是在做一个点面计算的操作,但是要具体描述卷积的用途或者原理,是有点困难的。

    cpuimage
  • 工作--如何封装第三方服务?

    业务开发中经常会对接某某第三方服务,因此会经常写一些SDK供服务使用,一种比较好的做法就是使用命令模式封装第三方服务,命令模式对于调用方来说简洁明了,也正是封装...

    屈定
  • Builder模式

    (1)相同的方法,不同的执行顺序,产生不同的事件结果时。 (2)多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。 (3)产品类...

    提莫队长

扫码关注云+社区

领取腾讯云代金券