简介

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

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

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

适用性
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. python unicode&str 转化

    从数据库中取出的值是Unicode编码的 需要转化为str才能正常使用 参考: http://www.mamicode.com/info-detail-308445.html

  2. spring mvc ModelAndView 404的原因

    在使用ModelAndView时不要导入 import org.springframework.web.portlet.ModelAndView; 而要导入以下这个包 import org.sprin ...

  3. Ruby自学笔记(一)— 基本概况

    之前一直想要多看看RESTful Service相关的东西,找到一本相关的书,但是里面的代码都是用Ruby写的,虽然知道编程语言都是类似的,但是看到一些陌生的语法,还是有些摸不着头脑,所以最近终于下定 ...

  4. 用C++进行函数式编程

    http://www.programmer.com.cn/12717/   文 / John Carmack 译 / 王江平 <Quake>作者Carmack认为追求函数式的程序设计有着实 ...

  5. 应用Oracle(解锁内置用户)

    解锁Oracle内置用户scott,密码默认为tiger. 系统管理员身份登录 cmd中, sqlplus / as sysdba 解除锁定 alter user scott account unlo ...

  6. 转 一些shell经验

    http://www.cnblogs.com/xublogs/archive/2010/03/16/2292254.html http://www.cnblogs.com/stephen-liu74/ ...

  7. 【Java】Hibernate4实战 之 第一部分Hibernate入门

    Hibernate是什么:ORMapping的原理 Hibernate是轻量级的ORMapping框架. ORMapping基本规则: 类和表映射. 实例和数据库表中的一条数据映射. 实例的属性和数据 ...

  8. Java中final、finally和finalize的区别(转)

    http://www.cnblogs.com/bluestorm/archive/2012/04/22/2464746.html final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖, ...

  9. SKYLINE

    uvalive4108:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&pag ...

  10. 【HDOJ】2364 Escape

    bfs.题目做的不细心,好多小错误.尤其注意起始点就是边界的情况.wa了八次. #include <iostream> #include <cstdio> #include & ...