为了账号安全,请及时绑定邮箱和手机立即绑定

java设计模式-职责链模式

标签:
Java 设计

职责链模式——使多个对象都有可能处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递请求,知道有一个对象处理它为止。
图片描述
抽象处理者角色(Handler):
定义一个处理请求的接口,定义一个方法以设定和返回对下一个处理角色的引用。
具体处理者角色(ConcreteHandler):
具体处理者接收到请求时,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有下家,如必要具体处理者可以访问下家。

代码结构:
抽象处理者角色——

package com.hy.chain;

public abstract class Handler {  

    /** 
     * 持有后继的责任对象 
     */  
    protected Handler successor;  
    /** 
     * 示意处理请求的方法,虽然这个示意方法是没有传入参数的 
     * 但实际是可以传入参数的,根据具体需要来选择是否传递参数 
     */  
    public abstract void handleRequest();  
    /** 
     * 取值方法 
     */  
    public Handler getSuccessor() {  
        return successor;  
    }  
    /** 
     * 赋值方法,设置后继的责任对象 
     */  
    public void setSuccessor(Handler successor) {  
        this.successor = successor;  
    }  

}  

具体的处理者角色———

package com.hy.chain;

public class ConcreteHandler1 extends Handler {  
    /** 
     * 处理方法,调用此方法处理请求 
     */  
    @Override  
    public void handleRequest() {  
        /** 
         * 判断是否有后继的责任对象 
         * 如果有,就转发请求给后继的责任对象 
         * 如果没有,则处理请求 
         */  
        if(getSuccessor() != null)  
        {              
            System.out.println("1放过请求");  
            getSuccessor().handleRequest();              
        }else  
        {              
            System.out.println("1处理请求");  
        }  
    }  

}
package com.hy.chain;

public class ConcreteHandler2 extends Handler {  
    /** 
     * 处理方法,调用此方法处理请求 
     */  
    @Override  
    public void handleRequest() {  
        /** 
         * 判断是否有后继的责任对象 
         * 如果有,就转发请求给后继的责任对象 
         * 如果没有,则处理请求 
         */  
        if(getSuccessor() != null)  
        {              
            System.out.println("2放过请求");  
            getSuccessor().handleRequest();              
        }else  
        {              
            System.out.println("2处理请求");  
        }  
    }  

}

测试类————

package com.hy.chain;

public class Client {  

    public static void main(String[] args) {  
        //组装责任链  
        Handler handler1 = new ConcreteHandler1();  
        Handler handler2 = new ConcreteHandler2();  
        handler1.setSuccessor(handler2);  
        //提交请求  
        handler1.handleRequest();  
    }  

}  

客户端创建了两个处理者对象,并指定第一个处理者对象的继承者是第二个处理者对象,第二个对象没有继承者。
本例中的逻辑比较简单,有继承者就由继承者处理,否则自行处理。

以部门聚餐,申请聚餐费用为例:
不同级别的领导可以审批不同的额度。项目经理审批500元以内的,部门经理审批1000元以内的,总监审批任意额度的申请。
当申请人发起请求时,请求会被项目经理,部门经理和总监中的某一位来审批,但是他并不知道具体是谁审批。申请人一般是提交请求给项目经理,剩下的流程不需要关心。
图片描述
抽象处理者角色类:

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);
}

具体处理者角色:

项目经理------

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;
    }

}

部门经理

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;
    }

}

总监:

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;
    }

}

客户端测试类:

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);
    }

}

职责链模式可以灵活的改变内部的传递规则,每个人可以动态的制定自己的继承者。
如果初始层级暂时不在或消失,请求也可以直接发送给其他层级,后续职责链还会继续进行。而且可以随时增加和修改处理一个请求的结构,增加了给对象指派的职责的灵活性。
如果不用职责链,申请者需要和公司的每一层都发生耦合关系,代码里也会增加过多的if…else 语句。使用之后,我们只需要认识其中的一个部门,让职责链进行内部的职责传递。

需要注意的是,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,需要事先考虑全面。
重要的有两点,一是事先给每个具体管理者设置后继者,二是每个具体的管理者处理请求时,要有严格的界限判断------是处理请求还是交给后继者处理

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
27
获赞与收藏
233

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消