• 职责链模式


    OA系统采购审批问题

    现有一个学校OA采购审批项目,需求:

    1. 采购员采购器材
    2. 如果金额小于等于5000,由教学主任审批
    3. 如果金额小于等于10000,由院长审批
    4. 如果金额小于等于30000,由副校长审批
    5. 如果金额超过30000,由校长审批

    传统方案解决OA系统审批

    在这里插入图片描述

    问题分析

    1. 调用端使用到分支判断,来对不同的采购请求处理,这样就存在以下问题:1、如果不同级别的审批金额发生变化,需要修改代码;2、调用端必须明确的知道:有多少个审批级别
    2. 这样的方案,处理请求和审批人之间存在强耦合关系,不利于代码的扩展和维护

    职责链模式

    基本介绍

    1. 职责链模式,又称责任链模式;为请求创建了一个接收者对象的链。这种模式对请求的发送者和接收者进行解耦
    2. 职责链模式通常每个接收者都包含对另一个接收者的引用,如果档期那接收者不能处理,就将请求交给下一个接收者处理
    3. 职责链模式属于行为型模式

    原理

    在这里插入图片描述

    1. Handler(Approver):抽象的处理者,定义了一个处理请求的接口,同时含有另一个Handler
    2. ConcreteHandler:具体的处理者,实现自己负责的请求的处理逻辑,可以访问后继处理者
    3. Request:一个待处理的请求
      在这里插入图片描述

    职责链模式解决OA采购审批问题

    在这里插入图片描述

    /***
     * @author shaofan
     * @Description 职责链模式解决OA采购审批问题
     */
    public class Oa {
        public static void main(String[] args) {
            PurchaseRequest request = new PurchaseRequest(25000,1);
            Approver departmentApprover = new DepartmentApprover("主任");
            Approver collegeApprover = new CollegeApprover("院长");
            Approver viceSchoolMasterApprover = new ViceSchoolMasterApprover("副校长");
            Approver schoolMasterApprover = new SchoolMasterApprover("校长");
    
            //环形链,保证请求一定会被处理
            departmentApprover.setApprover(collegeApprover);
            collegeApprover.setApprover(viceSchoolMasterApprover);
            viceSchoolMasterApprover.setApprover(schoolMasterApprover);
            schoolMasterApprover.setApprover(departmentApprover);
    
            
            departmentApprover.processRequest(request);
        }
    }
    class PurchaseRequest{
        private double amount;
        private int id;
    
        public PurchaseRequest(double amount,int id){
            this.amount = amount;
            this.id = id;
        }
    
    
        public double getAmount() {
            return amount;
        }
    
        public int getId() {
            return id;
        }
    }
    
    abstract class Approver{
        Approver approver;
        String name;
        public Approver(String name){
            this.name = name;
        }
        public void setApprover(Approver approver){
            this.approver = approver;
        }
    
        public abstract void processRequest(PurchaseRequest request);
    }
    
    class DepartmentApprover extends  Approver{
    
        public DepartmentApprover(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest request) {
            if(request.getAmount()<=5000){
                System.out.println(request.getId()+"被"+this.name+"处理");
                return;
            }
            approver.processRequest(request);
        }
    }
    
    class CollegeApprover extends  Approver{
    
        public CollegeApprover(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest request) {
            if(request.getAmount()>5000&&request.getAmount()<=10000){
                System.out.println(request.getId()+"被"+this.name+"处理");
                return;
            }
            approver.processRequest(request);
        }
    }
    
    class ViceSchoolMasterApprover extends  Approver{
    
        public ViceSchoolMasterApprover(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest request) {
            if(request.getAmount()>10000&&request.getAmount()<=30000){
                System.out.println(request.getId()+"被"+this.name+"处理");
                return;
            }
            approver.processRequest(request);
        }
    }
    
    class SchoolMasterApprover extends  Approver{
    
        public SchoolMasterApprover(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest request) {
            if(request.getAmount()>30000){
                System.out.println(request.getId()+"被"+this.name+"处理");
                return;
            }
            approver.processRequest(request);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117

    总结

    1. 将请求和处理分开,实现解耦,提高系统的灵活性
    2. 简化了对象,对象不需要知道链的结构
    3. 性能会受到影响,特别在链比较厂的时候,所以需要控制链的长度,一般在Handler中设置一个最大节点数量,在setNext()方法中判断是否已经超过限制,超过则不允许该链建立,避免出现超长链无意识的破坏系统性能
    4. 调试不方便,采用了类似递归的方式,调试时逻辑层可能比较复杂
    5. 应用场景:多个对象可以处理同一个请求,如多级请求、审批流程、JavaWeb中的过滤器、拦截器
  • 相关阅读:
    申请专利的好处!这份清单告诉你,为什么要申请专利?
    c# iis Oracle链接
    63.【c++基础篇.三个文件实现】
    加载报错 Unsupported version (not an attribute), or file does not exist
    敏捷整洁之道
    Vue3 源码解读系列(十四)——内置组件
    路由器虚拟服务器有什么作用
    Jupyter运行显存爆炸,明明上一个单元格已经运行完毕为什么还是会炸?
    数据仓库(5)数仓Kimball与Inmon架构的对比
    C++ MFC窗口与WPF 窗口的相互嵌套
  • 原文地址:https://blog.csdn.net/m0_48468380/article/details/126638067