一、定义

职责链模式是一种对象的行为模式。在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。

1、为请求创建一个接收此次请求对象的链

2、类型:行为型

二、适用场景

一个请求的处理需要多个对象当中的一个或几个协作处理

三、有点

请求的发送者和接收者(请求的处理)解耦

责任链可以动态的组合

四、缺点

责任链太长或者处理时间过长,影像性能

责任链有可能过多

五、类图:

职责链模式的组成:
抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。
具体处理者(ConcreteHandle)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

六、实例:公司请病假,1天内,项目经理批准;2天内Senior PM批准; 大于两天,医院提供病例、假条
public abstract class LeaveBaseHandler
{
    protected LeaveBaseHandler successor;

public LeaveBaseHandler getSuccessor()
    {
        return successor;
    }

public void setSuccessor(final LeaveBaseHandler successor)
    {
        this.successor = successor;
    }

public abstract void requestLeave(int days);
}

public class OneDayLeaveConcreteHandler extends LeaveBaseHandler
{
    @Override
    public void requestLeave(final int days)
    {
        if (days <= 1)
        {
            System.out.println("approve one day leave");
        }
        else
        {
            super.successor.requestLeave(days);
        }

}

}

public class TwoDaysLeaveConcreteHandler extends LeaveBaseHandler
{
    @Override
    public void requestLeave(final int days)
    {
        if (days > 1 && days <= 2)
        {
            System.out.println("approve 2 days leave");
        }
        else
        {
            super.successor.requestLeave(days);
        }
    }
}

public class MoreThanTwoDaysConcreteHandler extends LeaveBaseHandler
{
    @Override
    public void requestLeave(final int days)
    {
        if (days > 2)
        {
            System.out.println("get the record for leave from hospital");
        }
    }
}

public class Client
{
    private static void requestLeave()
    {
        final LeaveBaseHandler oneDay = new OneDayLeaveConcreteHandler();
        final LeaveBaseHandler twoDays = new TwoDaysLeaveConcreteHandler();
        final LeaveBaseHandler moreThanTwoDays = new MoreThanTwoDaysConcreteHandler();
        oneDay.setSuccessor(twoDays);
        twoDays.setSuccessor(moreThanTwoDays);

oneDay.requestLeave(1);
        oneDay.requestLeave(2);
        oneDay.requestLeave(3);
    }

public static void main(final String[] args)
    {
        requestLeave();
    }
}

结果:
approve one day leave
approve 2 days leave
get the record for leave from hospital

如果职责链结构比较复杂,会产生很多的内存垃圾对象。

七、实例2

课程审核

1、创建批准者类

/**
* 批准者 2019/1/7.
*/
public abstract class Approver { //责任链的核心是包含一个自己。 protected可以让子类获取到它
protected Approver approver; //设置下一个批准者
public void setNextApprover(Approver approver){
this.approver = approver;
} //发布课程
public abstract void deploy(Course course);
}

  

2、创建ArticleApprover

public class ArticleApprover extends  Approver{
@Override
public void deploy(Course course) {
if(StringUtils.isNotBlank(course.getArticle())){
System.out.println(course.getName() + "含有Article,批准");
if(approver != null){
approver.deploy(course);
}
}else{
System.out.println(course.getName() + "无Article,不批准,流程结束");
return;
} }
}

 

3、创建VideoApprover  

public class VideoApprover extends  Approver{
@Override
public void deploy(Course course) {
if(StringUtils.isNotBlank(course.getVideo())){
System.out.println(course.getName() + "含有Video,批准");
if(approver != null){
approver.deploy(course);
}
}else{
System.out.println(course.getName() + "无Video,不批准,流程结束");
return;
} }
}

  

4、创建课程Course

public class Course {
private String name;
private String article;
private String video; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getArticle() {
return article;
} public void setArticle(String article) {
this.article = article;
} public String getVideo() {
return video;
} public void setVideo(String video) {
this.video = video;
} @Override
public String toString() {
return "Course{" +
"name='" + name + '\'' +
", article='" + article + '\'' +
", video='" + video + '\'' +
'}';
}
}

  

5、创建测试类

public class Test {
public static void main(String[] args) {
//审核员审核article
Approver articleApprover = new ArticleApprover();
//审核员审核video
Approver videoApprover = new VideoApprover(); Course course = new Course();
course.setName("设计模式");
course.setArticle("设计模式Article");
course.setVideo("设计模式Video"); articleApprover.setNextApprover(videoApprover); articleApprover.deploy(course);
}
}

  

6、输出结果

八、在源码中的应用

1、javax.servlet.Filter

Servlet中的过滤器

设计模式-责任链模式Chain of Responsibility)的更多相关文章

  1. C#设计模式-责任链模式(Chain of Responsibility Pattern)

    引子 一个事件需要经过多个对象处理是一个挺常见的场景,譬如采购审批流程,请假流程,软件开发中的异常处理流程,web请求处理流程等各种各样的流程,可以考虑使用责任链模式来实现.现在以请假流程为例,一般公 ...

  2. 23种设计模式--责任链模式-Chain of Responsibility Pattern

    一.责任链模式的介绍 责任链模式用简单点的话来说,将责任一步一步传下去,这就是责任,想到这个我们可以相当击鼓传花,这个是为了方便记忆,另外就是我们在项目中经常用到的审批流程等这一类的场景时我们就可以考 ...

  3. 乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern)

    原文:乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 责任链模式(Chain of R ...

  4. 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)

    责任链模式(Chain of Responsibility Pattern) 介绍为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求,直 ...

  5. 责任链模式-Chain of Responsibility(Java实现), 例2

    责任链模式-Chain of Responsibility 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. 咱们在 ...

  6. 责任链模式-Chain of Responsibility(Java实现), 例1

    责任链模式-Chain of Responsibility, 例1 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. ...

  7. 《JAVA设计模式》之责任链模式(Chain of Responsibility)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...

  8. 责任链模式/chain of responsibility/行为型模式

    职责链模式 chain of responsibility 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处 ...

  9. 设计模式之二十:责任链模式(Chain of Responsibility)

    感觉这个设计模式和组合模式一样是一种非常巧妙的设计模式,在须要使用它的地方假设不使用这样的设计模式代码会变的非常复杂,可是这样的设计模式的基本原理又是非常easy的. 责任链模式: 通过使多个对象都有 ...

随机推荐

  1. uwsgi理解

    uwsgi uWSGI 是一个 Web 服务器,它实现了 WSGI 协议.uwsgi.http 等协议.Nginx 中HttpUwsgiModule 的作用是与 uWSGI 服务器进行交换.WSGI ...

  2. [Jedis] ERR wrong number of arguments for 'mget'

    看别人写的代码是件比较痛苦的事情,更加痛苦的是别人的代码出错还要负责调试好. 关于如何迅速定位问题和调试代码,我的一点感受是:逐行认真查看错误信息,在这些信息中找自己熟悉的内容(包括文件名.方法名等) ...

  3. 配置JAVA 环境变量

    首先 下载好JDK后 打开环境变量配置 配置JAVA_HOME: C:\Program Files\Java\jdk1.8.0_144(也就是jdk下载后的文件夹)   之后配置PATH:这时用到%J ...

  4. 性能测试-3.Fiddler进行弱网测试

    fiddler模拟限速的原理(原文地址) 我们可以通过fiddler来模拟限速,因为fiddler本来就是个代理,它提供了客户端请求前和服务器响应前的回调接口,我们可以在这些接口里 面自定义一些逻辑. ...

  5. 微软Power BI 每月功能更新系列——4月Power BI 新功能学习

    本月Power BI Desktop的更新,除了常规的视觉和数据连接器改进之外,还有两个非常大的功能改进,交互式的报表.问答,用户直接在Desktop可以询问有关的数据问题,面对层出不穷的用户需求,这 ...

  6. 搭建使用create-react-native-app 搭建app开发环境

    文档地址 react-native expo 官网 expo 文档 两种创建react-natvie-app的方法 react-native init projectName create-react ...

  7. 数据文件resize扩容

    表空间不足 Alert日志报错 Mon Dec :: GMT+: Incremental checkpoint up to RBA[ox1af2d.3ddll.], current log tail ...

  8. verilog实现rgb2gray

    前言 项目算法需求,需要将RGB彩色图像转换为灰度图像,算法原理是很简单的,但是对于刚接触FPGA的宝宝来说,进行时序的设计和调试还是不那么容易的,为了省事儿,就按照上一篇中值滤波(http://ww ...

  9. Unity读取AssetBundle资源全教程(所有读取方式)

    读取/加载 AssetBundle 资源的多种方式 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Ch ...

  10. DES算法,JAVA,遇到的问题

    (1)使用Based64编码时出现的问题. java.lang.IllegalArgumentException 这中情况出现在解密时,主要原因是based64加密时用了sun的内部包sun.misc ...