这个责任链模式,其实在之前写的定时任务中也用到过。其实,责任链模式跟工作流很相似,一个工作分为很多任务,当启动这个工作时,这些任务按照设定的顺序,一个接着一个的执行。web中的过滤器其实也用到了这种设计模式。
接下来,一起看看责任链模式。

一、基本概念

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

二、结构

抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家

三、代码实现

首先,创建一个抽象处理者角色类:

package org.wuqiong.designpattern.chainofResponsibility;
/**
 * ClassName:Handler <br/>
 * Function: 抽象处理者角色类. <br/>
 * Date:     2016年1月29日 下午3:08:40 <br/>
 * @author   qiyongkang
 * @version  
 * @since    JDK 1.6
 * @see      
 */
public abstract class Handler {

    /**
     * 持有下一个处理请求的对象
     */
    protected Handler successor = null;

    /**
     * 取值方法
     */
    public Handler getSuccessor() {
        return successor;
    }

    /**
     * 设置下一个处理请求的对象
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    /**
     * 处理聚餐费用的申请
     * @param user    申请人
     * @param fee    申请的钱数
     * @return        成功或失败的具体通知
     */
    public abstract String handleFeeRequest(String user , double fee);
}

然后,再准备三个具体的处理角色类:
项目经理

package org.wuqiong.designpattern.chainofResponsibility;

/**
 * ClassName:ProjectManager <br/>
 * Function: 具体处理者角色-项目经理. <br/>
 * Date: 2016年1月29日 下午3:11:30 <br/>
 * 
 * @author qiyongkang
 * @version
 * @since JDK 1.6
 * @see
 */
public class ProjectManager extends Handler {

    @Override
    public String handleFeeRequest(String user, double fee) {
        String str = "";
        // 项目经理权限比较小,只能在500以内
        if (fee < 500) {
            // 为了测试,简单点,只同意张三的请求
            if ("张三".equals(user)) {
                str = "成功:项目经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            } else {
                // 其他人一律不同意
                str = "失败:项目经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            }
        } else {
            // 超过500,继续传递给级别更高的人处理
            if (getSuccessor() != null) {
                return getSuccessor().handleFeeRequest(user, fee);
            }
        }
        return str;
    }

}

部分经理

package org.wuqiong.designpattern.chainofResponsibility;

/**
 * ClassName:DeptManager <br/>
 * Function: 具体处理者角色-部门经理 <br/>
 * Date: 2016年1月29日 下午3:14:41 <br/>
 * 
 * @author qiyongkang
 * @version
 * @since JDK 1.6
 * @see
 */
public class DeptManager extends Handler {

    @Override
    public String handleFeeRequest(String user, double fee) {
        String str = "";
        // 部门经理的权限只能在1000以内
        if (fee < 1000) {
            // 为了测试,简单点,只同意张三的请求
            if ("张三".equals(user)) {
                str = "成功:部门经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            } else {
                // 其他人一律不同意
                str = "失败:部门经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            }
        } else {
            // 超过1000,继续传递给级别更高的人处理
            if (getSuccessor() != null) {
                return getSuccessor().handleFeeRequest(user, fee);
            }
        }
        return str;
    }

}

总经理

package org.wuqiong.designpattern.chainofResponsibility;

/**
 * ClassName:GeneralManager <br/>
 * Function: 具体处理者角色-总经理. <br/>
 * Date: 2016年1月29日 下午3:16:02 <br/>
 * 
 * @author qiyongkang
 * @version
 * @since JDK 1.6
 * @see
 */
public class GeneralManager extends Handler {

    @Override
    public String handleFeeRequest(String user, double fee) {
        String str = "";
        // 总经理的权限很大,只要请求到了这里,他都可以处理
        if (fee >= 1000) {
            // 为了测试,简单点,只同意张三的请求
            if ("张三".equals(user)) {
                str = "成功:总经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            } else {
                // 其他人一律不同意
                str = "失败:总经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            }
        } else {
            // 如果还有后继的处理对象,继续传递
            if (getSuccessor() != null) {
                return getSuccessor().handleFeeRequest(user, fee);
            }
        }
        return str;
    }

}

最后,再准备一个客户端,把这些具体的处理者给链起来:

package org.wuqiong.designpattern.chainofResponsibility;

/**
 * ClassName:Client <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2016年1月29日 下午3:17:48 <br/>
 * 
 * @author qiyongkang
 * @version
 * @since JDK 1.6
 * @see
 */
public class Client {
    public static void main(String[] args) {
        // 先要组装责任链
        Handler h1 = new GeneralManager();
        Handler h2 = new DeptManager();
        Handler h3 = new ProjectManager();
        h3.setSuccessor(h2);
        h2.setSuccessor(h1);

        // 开始测试
        String test1 = h3.handleFeeRequest("张三", 300);
        System.out.println("test1 = " + test1);
        String test2 = h3.handleFeeRequest("李四", 300);
        System.out.println("test2 = " + test2);
        System.out.println("---------------------------------------");

        String test3 = h3.handleFeeRequest("张三", 700);
        System.out.println("test3 = " + test3);
        String test4 = h3.handleFeeRequest("李四", 700);
        System.out.println("test4 = " + test4);
        System.out.println("---------------------------------------");

        String test5 = h3.handleFeeRequest("张三", 1500);
        System.out.println("test5 = " + test5);
        String test6 = h3.handleFeeRequest("李四", 1500);
        System.out.println("test6 = " + test6);
    }
}

其实,责任链这种设计模式还是挺不错,可以把一个复杂的任务,分解成若干个小任务,一个接着一个的执行,让程序业务逻辑变得更清晰。
那么,责任链就提到这儿啦,一定要记得它的代码写法!