Java设计模式之责任链模式

上一篇文章讨论到设计者往往会用拦截器去代替动态代理,然后将拦截器的接口提供给开发者,从而简化开发者的开发难度,但是拦截器可能有多个。举个例子,一个程序员需要请假一周,如果把请假申请单看成一个对象,那么它需要经过项目经理、部门经理、人事等多个角色的审批,每个角色都有机会通过拦截这个申请单进行审批或者修改,这个时候就要考虑提供项目经理、部门经理和人事的处理逻辑,所以需要提供3个拦截器,而传递的则是请假申请单,如下图所示:

当一个对象在一条链上被多个拦截器拦截处理(拦截器也可以选择不拦截处理它)时, 我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景。还是刚才的例子,申请单走到项目经理那,经理可能把申请时间"一周"改为"5天",从而影响了后面的审批,后面的审批都要根据前面的结果进行。这个时候可以考虑用层层代理来实现,就是当申请单走到项目经理处,使用第一个动态代理(proxy1)。当它走到部门经理处,部门经理会得到一个在项目经理的代理proxy1基础上生成proxy2来处理部门经理的逻辑。当它走到人事处时,会在proxy2的基础上生成proxy3。如果还有其他角色,以此类推即可,用下图来描述拦截器逻辑会更加清晰。

仍依代码定义的拦截器接口为例,定义3个拦截器,如一下代码为例:

拦截器1:

 /************************** 拦截器1 ***************************/
    
    public boolean before(Object proxy, Object target, Method method,Object[] args) {
        System.out.println("[拦截器1]的before方法。。。");
        return true;
    }

    public void around(Object proxy,Object target,Method method,Object[] args) {

    }
    public void after(Object proxy,Object target,Method method,Object[] args){
        System.out.println("[拦截器1]的after方法。。。");
    }

拦截器2: 

 /************************** 拦截器2 ***************************/
    
    public boolean before(Object proxy, Object target, Method method,Object[] args) {
        System.out.println("[拦截器2]的before方法。。。");
        return true;
    }

    public void around(Object proxy,Object target,Method method,Object[] args) {

    }
    public void after(Object proxy,Object target,Method method,Object[] args){
        System.out.println("[拦截器2]的after方法。。。");
    }

拦截器3: 

 /************************** 拦截器3 ***************************/
    
    public boolean before(Object proxy, Object target, Method method,Object[] args) {
        System.out.println("[拦截器3]的before方法。。。");
        return true;
    }

    public void around(Object proxy,Object target,Method method,Object[] args) {

    }
    public void after(Object proxy,Object target,Method method,Object[] args){
        System.out.println("[拦截器3]的after方法。。。");
    }

测试main方法:

 public void main(String[] args) {
        HelloWorld proxy1 = InterceptorJdkProxy.bind(
                new HelloWorldImpl(),"com.busi.service.Inteceptor1");

        HelloWorld proxy2 = InterceptorJdkProxy.bind(
                new HelloWorldImpl(),"com.busi.service.Inteceptor1");

        HelloWorld proxy3 = InterceptorJdkProxy.bind(
                new HelloWorldImpl(),"com.busi.service.Inteceptor1");


    }

 运行结果如下:

[拦截器3] 的before方法
[拦截器2] 的before方法
[拦截器1] 的before方法
 Hello World
[拦截器1] 的after方法 
[拦截器2] 的after方法
[拦截器3] 的after方法

befor方法按照从最后一个拦截器到第一个拦截器的加载顺序运行,而after方法则按照从第一个拦截器到最后一个拦截器的加载顺序运行。

从代码中可见,责任链模式的优点在于我们可以在传递链上加入新的拦截器,增加拦截逻辑,其缺点是会增加代理和反射,而代理和反射的性能不高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunshineAndAlways

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值