资讯专栏INFORMATION COLUMN

Java设计模式之职责链模式

bergwhite / 765人阅读

摘要:简介职责链模式有时候也叫责任链模式,它是一种对象行为的设计模式。中的就是使用了责任链模式。纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。

Java设计模式之职责链模式

前几天复习java的异常处理时,接触到了责任链模式。在企业级应用中,从前台发过来的请求在后台抛出异常,异常处理的设计一般会用到责任链模式,比如sql异常并不会直接抛出给前台,而是经过一系列的处理和再封装,抛给前台一个用户可识别的异常信息。

简介

职责链模式有时候也叫责任链模式,它是一种对象行为的设计模式。目的是:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。发送请求的客户端并不知道链上的哪个对象会处理这个请求,这使得系统在不影响客户端的情况下动态的组织和分配责任。

这里需要注意的是,职责链可以是一条直线、一个环链或者是一个树结构的一部分。

Tomcat中的Filter就是使用了责任链模式。

参与者

职责链模式UML图:

一个典型的职责链对象图可能这样的:

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

ConcreteHandler:具体处理者。具体处理者接受到请求后,可以选择立即处理这个请求或者将请求传递给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

Client:客户端。向处理者提交请求对象。

代码示例

需求:部门搞活动向公司申请经费,金额小于1000的项目经理就可以审批,小于2000的部门经理可以审批,大于2000的只能总经理审批。

这里就使用职责链模式。申请人提交给项目经理申请经费,项目经理如果权限够的话就审批,不够的话就提交到上级领导,依次类推,直到能够处理请求为止。

代码实现:

Handler:审批人员的抽象父类

package com.wangjun.designPattern.chainOfResponsibility;

public abstract class Handler {
    protected Handler successor;
    
    public abstract boolean handler(int fee);
    
    public abstract void setSuccessor(Handler successor);
    
    public abstract Handler getSuccessot();
}

ConcreteHandler1:项目经理

package com.wangjun.designPattern.chainOfResponsibility;

public class ProjectManager extends Handler {

    @Override
    public boolean handler(int fee) {
        if(fee <= 1000) {
            System.out.println("项目经理:审批通过。金额:" + fee);
            return true;
        }else {
            System.out.println("金额大于1000,项目经理无权审批,移交给部门经理!");
            setSuccessor(new DepartmentManager());
            return successor.handler(fee);
        }
    }

    @Override
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    @Override
    public Handler getSuccessot() {
        return successor;
    }

}

ConcreteHandler2:部门经理

package com.wangjun.designPattern.chainOfResponsibility;

public class DepartmentManager extends Handler {

    @Override
    public boolean handler(int fee) {
        if(fee <= 2000) {
            System.out.println("部门经理:审批通过。金额:" + fee);
            return true;
        }else {
            System.out.println("金额大于2000,部门经理无权审批,移交给总经理!");
            setSuccessor(new Manager());
            return successor.handler(fee);
        }
    }

    @Override
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    @Override
    public Handler getSuccessot() {
        return successor;
    }

}

ConcreteHandler3:总经理

package com.wangjun.designPattern.chainOfResponsibility;

public class Manager extends Handler {

    @Override
    public boolean handler(int fee) {
        if(fee <= 10000) {
            System.out.println("总经理:审批通过。金额:" + fee);
            return true;
        }else {
            System.out.println("金额大于10000,审批不通过!申请金额:" + fee);
            return false;
        }
    }

    @Override
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    @Override
    public Handler getSuccessot() {
        return successor;
    }

}

Client:客户端申请费用

package com.wangjun.designPattern.chainOfResponsibility;

public class Client {

    public static void main(String[] args) {
        // 测试申请费用列表
        int[] arr = {500, 1500, 2500, 29000}; 
        
        // 将申请提交给的项目经理
        ProjectManager pm = new ProjectManager();
        
        for(int i = 0; i < arr.length; i++) {
            System.out.println("第" + (i+1) + "笔费用");
            if(pm.handler(arr[i])) {
                System.out.println("申请经费成功!");
            }else {
                System.out.print("申请经费失败!");
            }
            System.out.println();
        }
    }

}

运行结果:

第1笔费用
项目经理:审批通过。金额:500
申请经费成功!

第2笔费用
金额大于1000,项目经理无权审批,移交给部门经理!
部门经理:审批通过。金额:1500
申请经费成功!

第3笔费用
金额大于1000,项目经理无权审批,移交给部门经理!
金额大于2000,部门经理无权审批,移交给总经理!
总经理:审批通过。金额:2500
申请经费成功!

第4笔费用
金额大于1000,项目经理无权审批,移交给部门经理!
金额大于2000,部门经理无权审批,移交给总经理!
金额大于10000,审批不通过!申请金额:29000
申请经费失败!
总结

可以在一下情况下使用职责链模式:

有多个对象可以处理同一个请求,哪个对象处理请求在运行时刻自动确定;

你想在不明确指定接受者的情况下,向多个对象的一个提交请求;

可处理一个请求的对象集合应被动态指定。

纯的与不纯的责任链模式

一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又 把责任向下传的情况。

在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。

纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。有些人认为不纯的责任链根本不是责任链模式,这也许是有道理的。但是在实际的系统里,纯的责任链很难找到。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。

loading...

后续研究一下tomcat的Filter机制。

参考:

《设计模式》

https://blog.csdn.net/m136663...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69452.html

相关文章

  • 传递请求职责模式

    摘要:想一想,这个和我们的迭代器模式有着异曲同工的妙处,迭代器模式同样也是遍历选出最优解,但是相比而言,职责链模式的直观性个书写的幸福感是远远超过迭代器模式的。 职责链模式其实很好理解,由于一个链字出卖了它的灵魂。我们可以从这个字得到很大的提示。首先这个模式一定有传递性,而且,节点是可以重复拼接的,并且每个节点都具有一定的过滤功能,一定的职责。 是不是想起了组合模式里的一些内容呢? 是的,他...

    wslongchen 评论0 收藏0
  • 函数式编程让你忘记设计模式

    摘要:面向对象常见的设计模式有策略模式模板方法观察者模式责任链模式以及工厂模式,使用表达式函数式编程思维有助于避免面向对象开发中的那些固定代码。 本文是一篇《Java 8实战》的阅读笔记,阅读大约需要5分钟。 有点标题党,但是这确实是我最近使用Lambda表达式的感受。设计模式是过去的一些好的经验和套路的总结,但是好的语言特性可以让开发者不去考虑这些设计模式。面向对象常见的设计模式有策略模式...

    or0fun 评论0 收藏0
  • Java设计模式概述

    摘要:设计模式的类别设计模式一共分为种类型,共种。属于结构型的设计模式适配器模式桥接模式装饰模式组合模式外观模式享元模式代理模式。问题描述了应该在何时使用设计模式。解决方案描述了设计的组成成分,它们之间的相互关系及各自的职责和协作方式。 设计模式概述 1. 设计模式是什么 我们在平时编写代码的过程中,会遇到各种各样的问题,细想一下很多问题的解决思路大致一样的,这时候你就可以把解决问题的思路整...

    leon 评论0 收藏0
  • JS每日一题:设计模式-如何理解职责模式?

    摘要:提交请求的对象并不明确知道哪一个对象将会处理它也就是该请求有一个隐式的接受者。 20190412期 设计模式-如何理解职责链模式? 定义: 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止 也就是说,请求以后,从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。提...

    lifesimple 评论0 收藏0
  • 忘了再看设计模式-行为型

    摘要:推文用设计模式解构三国是一种什么体验行为型设计模式一策略模式工厂模式优化结构状态模式随着状态改变而改变行为。推文状态机与状态模式责任链模式多个对象依次处理请求前者指定后者。代理模式代理针对一个对象,为了增加控制等中介双方都是多个,为了解耦。 策略模式 选择使用封装好的一系列算法,可相互替换。 类比:商店[Context]买完衣服买单[Stratege](现金[Concrete Stra...

    ShevaKuilin 评论0 收藏0

发表评论

0条评论

bergwhite

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<