简介

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

责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做任何处理),作为请求者可以不用知道到底是需要谁来处理的,这是责任链模式的核心。

责任链有一个缺点是,大家在开发的时候要注意,调试不是很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。

适用性
1.有多个的对象可以处理一个请求,具体哪个对象处理该请求在运行时刻自动确定。
2.你在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3.可处理一个请求的对象集合应被动态指定。

作用:请求会被链上的对象处理,但是客户端不知道请求会被哪些对象处理
通过把请求从一个对象传递到链条中下一个对象的方式,直到请求被处理完毕,以实现对象间的解耦。
JDK中体现:
(1)java.util.logging.Logger会将log委托给parent logger
(2)ClassLoader的委托模型

简易演示-1

中国古代对妇女制定了“三从四德”的道德规范,“三从”是指“未嫁从父、既嫁从夫、夫死从子”,也就是说一个女性,在没有结婚的时候要听从于父亲,结了婚后听从于丈夫,丈夫死了还要听儿子的。举个例子来说,一个女的要出去逛街,同样这样的一个请求,在她没有出嫁前她必须征得父亲的同意,出嫁之后必须获得丈夫的许可,那丈夫死了怎么办?一般都是男的比女的死的早,还要问问儿子是否允许自己出去逛街。父亲、丈夫、儿子只有两种选择:要不承担起责任来告诉她允许或不允许逛街,要不就让她请示下一个人,这是整个社会体系的约束,应用到我们项目中就是业务规则,那我们来看怎么把“三从”通过我们的程序来实现。
public class Test2 {
    public static void main(String[] args) {
        //定义三个请示对象
        Handler father = new Father();
        Handler husband = new Husband();
        Handler son = new Son();
        //设置请示顺序
        father.setNext(husband);
        husband.setNext(son);

        //随机挑选几个女性
        ArrayList<IWomen> arrayList = new ArrayList<IWomen>();
        for (int i = 0; i < 5; i++) {
            arrayList.add(new Women(new Random().nextInt(4), "我要出去逛街"));
        }

        //处理请示
        for (IWomen women : arrayList) {
            father.HandleMessage(women);
        }
    }
}

interface IWomen {
    /**获得个人状况*/
    public int getType();
    /**获得个人请示,你要干什么?出去逛街?约会?还是看电影*/
    public String getRequest();
}
class Women implements IWomen {
    /** 描述妇女的个人状况 1---未出嫁 2---出嫁 3---夫死 */
    private int type = 0;
    /**请示内容*/
    private String request = "";
    public Women(int _type, String _request) {
        this.type = _type;
        switch (this.type) {//为了显示好看点,我在这里做了点处理
        case 1:
            this.request = "女儿的请求是:" + _request;
            break;
        case 2:
            this.request = "妻子的请求是:" + _request;
            break;
        case 3:
            this.request = "母亲的请求是:" + _request;
            break;
        }
    }
    @Override
    public int getType() {
        return this.type;
    }
    @Override
    public String getRequest() {
        return this.request;
    }
}

abstract class Handler {
    /**能处理的状况*/
    private int type = 0;
    /**责任传递,下一个人责任人是谁*/
    private Handler nextHanlder;
    public Handler(int type) {
        this.type = type;
    }
    //一个女性(女儿,妻子或者是母亲)要求逛街,你要处理这个请求
    public final void HandleMessage(IWomen women) {
        if (women.getType() == this.type) response(women);//自己处理
        else if (nextHanlder != null) nextHanlder.HandleMessage(women); //有后续环节,才把请求往后递送
        else System.out.println("-----------没有人可以请示了,不做处理!---------\n");//已经没有后续处理人了,不用处理了
    }
    public void setNext(Handler _handler) {
        this.nextHanlder = _handler;
    }
    /**回应*/
    public abstract void response(IWomen women);
}
/**父亲类,父亲只处理女儿的请求*/
class Father extends Handler {
    public Father() {
        super(1);
    }
    @Override
    public void response(IWomen women) {
        System.out.println("--------女儿向父亲请示-------");
        System.out.println(women.getRequest());
        System.out.println("父亲的答复是:同意\n");
    }
}
/**丈夫类,丈夫只处理妻子的请求*/
class Husband extends Handler {
    public Husband() {
        super(2);
    }
    //丈夫请示的答复
    @Override
    public void response(IWomen women) {
        System.out.println("--------妻子向丈夫请示-------");
        System.out.println(women.getRequest());
        System.out.println("丈夫的答复是:同意\n");
    }
}
/**儿子类*/
class Son extends Handler {
    public Son() {
        super(3);
    }
    @Override
    public void response(IWomen women) {
        System.out.println("--------母亲向儿子请示-------");
        System.out.println(women.getRequest());
        System.out.println("儿子的答复是:同意\n");
    }
}

简易演示-2

/**请求 */
public interface IRequest {
    public void request();
}
/**加薪请求 */
class AddMoneyRequest implements IRequest {
    @Override
    public void request() {
        System.out.print("加薪请求-->");
    }
}
/**离职请求 */
class DimissionRequest implements IRequest {
    @Override
    public void request() {
        System.out.print("离职请求-->");
    }
}
/**请假请求 */
class LeaveRequest implements IRequest {
    @Override
    public void request() {
        System.out.print("请假请求-->");
    }
}

/**请求处理接口 */
public interface IRequestHandle {
    void handleRequest(IRequest request);
}
/**项目经理处理,审批AddMoneyRequest的请求 */
class PMRequestHandle implements IRequestHandle {
    private IRequestHandle nextHandle;
    public PMRequestHandle(IRequestHandle rh) {
        this.nextHandle = rh;
    }
    @Override
    public void handleRequest(IRequest request) {
        if (request instanceof AddMoneyRequest) System.out.println("项目经理审批完毕");
        else nextHandle.handleRequest(request);
    }
}
/**项目组长处理,审批LeaveRequest的请求*/
class TLRequestHandle implements IRequestHandle {
    private IRequestHandle nextHandle;
    public TLRequestHandle(IRequestHandle rh) {
        this.nextHandle = rh;
    }
    @Override
    public void handleRequest(IRequest request) {
        if (request instanceof LeaveRequest) System.out.println("项目组长审批完毕");
        else nextHandle.handleRequest(request);
    }
}
/**最后的审批者,人事处理,审批其他请求 */
class LastRequestHandle implements IRequestHandle {
    @Override
    public void handleRequest(IRequest request) {
        System.out.println("人事审批完毕");
    }
}

/**
 * 责任链模式。使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
 * 将这些对象连成一条链,并沿着这条链【传递】该请求,直到有一个对象处理它为止。
 */
public class Test {
    public static void main(String[] args) {
        IRequest request1 = new DimissionRequest();
        IRequest request2 = new AddMoneyRequest();
        IRequest request3 = new LeaveRequest();

        IRequestHandle handle = new TLRequestHandle(new PMRequestHandle(new LastRequestHandle()));
        request1.request();
        handle.handleRequest(request1);
        request2.request();
        handle.handleRequest(request2);
        request3.request();
        handle.handleRequest(request3);
        
        System.out.println("\n");
        IRequestHandle handle2 = new PMRequestHandle(new TLRequestHandle(new LastRequestHandle()));//顺序无影响
        handle2.handleRequest(request1);
        handle2.handleRequest(request2);
        handle2.handleRequest(request3);
    }
}

附件列表

Chain of Responsibility 责任链模式的更多相关文章

  1. 设计模式(13)--Chain of Responsibility(责任链模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一 ...

  2. 设计模式(一)Chain Of Responsibility责任链模式

    设计模式篇章,源于网课的学习,以及个人的整理 在我们接收用户提交的字符时,常常会使用到过滤,在学习责任链模式前,我们是这样做的 1.定义一个类 public class MsgProcesser { ...

  3. Chain of Responsibility 责任链模式 MD

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

  4. python 设计模式之 (Chain of Responsibility)责任链模式

    #写在前面 对于每一种设计模式,如果不理解它的原理和结构,是写不出例子来的.所以弄明白很重要. 等过完这段浑浑噩噩的日子,我要找个遍地开花的地方开怀大笑一场 #责任链模式定义 简书上一网友就把这个定义 ...

  5. 设计模式C++学习笔记之十七(Chain of Responsibility责任链模式)

      17.1.解释 概念:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. main(),客户 IWom ...

  6. Chain of Responsibility - 责任链模式

    定义 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合度. 案例 比方如今有一个图形界面,它包含一个应用Application类,一个主窗体Window,一个buttonButton ...

  7. 设计模式19:Chain Of Responsibility 职责链模式(行为型模式)

    Chain Of Responsibility 职责链模式(行为型模式) 请求的发送者与接受者 某些对象请求的接受者可能有多种多样,变化无常…… 动机(Motivation) 在软件构建过程中,一个请 ...

  8. Design Pattern Chain of Reponsibility 责任链模式

    本程序实现一个责任链模式查询人名的资料. 開始都是查询第一个人,问其是否有某人的资料,假设有就返回结果,假设没有第一个人就会询问第二个人,第二个人的行为和第一个人的行为一致的,然后一致传递下去,直到找 ...

  9. 设计模式学习笔记——Chain of Responsibility职责链模式

    重点在链.一条链,如果本节点处理不了,则传递给下一个节点处理. 关键是如何传给下一个节点? 主要是由本节点决定传给哪一个节点. public class Client { public static ...

随机推荐

  1. C#中静态方法和非静态方法的区别(二)

    一.引言 在C#中,静态和非静态的特征对于我们来说是再熟悉不过了,但是很少看到有一篇文章去好好地总结静态和非静态它们之间的不同,为了帮助大家更好地去理解静态和非静态特征, 所以将在这篇文章中帮大家全面 ...

  2. codebook法分割前景目标

    利用codebook法训练得到背景模型后,对背景差分得到的掩模图像去噪声并找到较大连通域.相对于平均背景法,它的分割效果更好些.当然,分割效果和背景模型训练的帧数有很大关系,适当调整一些参数会得到更好 ...

  3. fragment 学习

    fragment需要id是必须属性 <fragment        android:id="@+id/frg1"        android:name="com ...

  4. Kent Beck揭秘Facebook开发部署流程

    http://www.infoq.com/cn/news/2013/10/facebook-development-deployment Facebook是世界上最大的社交网站,有超过10亿用户每月至 ...

  5. opencv 2.46与visual studio 2012 配置方法

    一开学就搞实训,还是没学过的图像处理.痛苦啊!图像处理时一般使用Matlab中的图像工具箱,或者是C/C++和OpenCV结合使用.以前看过一些关于opencv的文章,没想到现在要用上了. 把搭建开发 ...

  6. WPF小程序:贪吃蛇

    原文地址:http://hankjin.blog.163.com/blog/static/337319372009535108234/ 一共两个文件:EasterEgg.xaml + EasterEg ...

  7. BZOJ 1296 粉刷匠

    Description windy有\(N\)条木板需要被粉刷.每条木板被分为\(M\)个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. ...

  8. [BZOJ 3626] [LNOI2014] LCA 【树链剖分 + 离线 + 差分询问】

    题目链接: BZOJ - 3626 题目分析 考虑这样的等价问题,如果我们把一个点 x 到 Root 的路径上每个点的权值赋为 1 ,其余点的权值为 0,那么从 LCA(x, y) 的 Depth 就 ...

  9. Unity3d 项目管理 版本管理

    Unity3d中项目管理     版本管理 如果在提交文件的时候发现提示有"先更新,再提交的"提示的时候,这是因为,A提交了一个版本文件,版本是13,那么你还在修改版本为12的文件 ...

  10. Delphi编程中资源文件的应用

    Delphi编程中资源文件的应用/转自 http://chamlly.spaces.live.com/blog/cns!548f73d8734d3acb!236.entry一.引子: 现在的Windo ...