软件设计模式学习(十七)职责链模式


系统中若是存在多个对象能够处理一个同一请求,能够经过职责链模式将这些处理请求的对象连成一条链,让请求沿着该链进行传递。若是链上的对象能够处理该请求则进行处理,不然将请求转发给下家处理html


模式动机

不少状况下,能够处理某个请求的对象不止一个,如大学里的奖学金审批,学生先向辅导员提交审批表,辅导员签字审批后再交给系主任签字审批,接着是院长审批,最后多是校长审批,在这个过程当中,奖学金申请表能够看做一个请求对象,不一样级别审批者均可以处理该请求,除了辅导员以外,学生不需一一和其余审批者交互,只需等待结果便可。审批过程当中若是某一审批者认为不符合条件,则请求停止,不然将请求传递给下一审批者,最后由校长拍板。java

在这个过程当中,辅导员、系主任、院长、校长构成一条链,申请表沿着这条链传递,就叫职责链。职责链能够是一条直线、一个环或一个树形结构,常见的职责链是直线型。请求沿着链传递,由链上的处理者对请求进行处理,客户无须关心请求的处理和传递细节,实现请求发送者和请求处理者解耦。设计模式


模式定义

避免请求者与接收者耦合在一块儿,让多个对象都有可能接受请求,将这些对象链接成一条链,而且沿着这条链传递请求,直到有对象处理为止。职责链模式也叫责任链模式,它是一种对象行为型模式。ide


模式结构

  1. Handler(抽象处理者)性能

    定义了一个处理请求的接口,因为不一样的具体处理者处理请求方式不一样,所以在其中定义抽象请求处理方法。在抽象处理者中定义一个自类型(抽象处理者类型)的对象,做为对下家的引用。学习

  2. ConcreteHandler(具体处理者)测试

    具体处理者是抽象处理者子类,实现抽象请求处理方法,处理用户请求。在处理请求以前要进行判断,看是否具备相应处理权限,若是能够处理就处理,不然将请求转发给后继者。this

  3. Client(客户类)设计

    用于向链中对象提出最初的请求,客户类只关心链的源头,而无须关心请求的处理细节和传递过程。代理


模式实例

某系统提供一个假条审批的模块,若是员工请假天数小于 3 天,主任能够审批该假条;若是员工请假天数大于等于 3 天,小于 10 天,经理能够审批;若是员工请假天数大于等于 10 天,小于 30 天,总经理能够审批;若是超过 30 天,总经理也不能审批,提示相应的拒绝信息。

  1. 请求类 LeaveRequest(请假条类)

    //	封装请求的相关信息,以便处理者对其进行处理
    public class LeaveRequest {
    
        private String leaveName;
        private int leaveDays;
    
        public LeaveRequest(String leaveName, int leaveDays) {
            this.leaveName = leaveName;
            this.leaveDays = leaveDays;
        }
    
        public void setLeaveName(String leaveName) {
            this.leaveName = leaveName;
        }
    
        public void setLeaveDays(int leaveDays) {
            this.leaveDays = leaveDays;
        }
    
        public String getLeaveName() {
            return leaveName;
        }
    
        public int getLeaveDays() {
            return leaveDays;
        }
    }
  2. 抽象处理类 Leader(领导类)

    public abstract class Leader {
    
        protected String name;
        protected Leader successor;	//	做为对下家的引用
    
        public Leader(String name) {
            this.name = name;
        }
    
        public void setSuccessor(Leader successor) {
            this.successor = successor;
        }
    
        public abstract void handleRequest(LeaveRequest request);
    }
  3. 具体处理者 Director(主任类)

    public class Director extends Leader {
    
        public Director(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveRequest request) {
            if (request.getLeaveDays() < 3) {
                System.out.println("主任" + name + "审批员工" + request.getLeaveName() +
                        "的请假条,请假天数为" + request.getLeaveDays() + "天");
            } else {
                if (this.successor != null) {
                    this.successor.handleRequest(request);
                }
            }
        }
    }
  4. 具体处理者 Manager(经理类)

    public class Manager extends Leader {
    
        public Manager(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveRequest request) {
            if (request.getLeaveDays() < 10) {
                System.out.println("经理" + name + "审批员工" + request.getLeaveName() +
                        "的请假条,请假天数为" + request.getLeaveDays() + "天");
            } else {
                if (this.successor != null) {
                    this.successor.handleRequest(request);
                }
            }
        }
    }
  5. 具体处理者 GeneralManager(总经理类)

    public class GeneralManager extends Leader {
    
        public GeneralManager(String name) {
            super(name);
        }
    
        @Override
        public void handleRequest(LeaveRequest request) {
            if (request.getLeaveDays() < 30) {
                System.out.println("总经理" + name + "审批员工" + request.getLeaveName() +
                        "的请假条,请假天数为" + request.getLeaveDays() + "天");
            } else {
                System.out.println("想请假" + request.getLeaveDays() + "天?你是不想干了吧!");
            }
        }
    }
  6. 客户端测试类 Client

    public class Client {
    
        public static void main(String[] args) {
    
            Leader director = new Director("王明");
            Leader manager = new Manager("赵强");
            Leader generalManager = new GeneralManager("陈勇");
    
            director.setSuccessor(manager);
            manager.setSuccessor(generalManager);
    
            LeaveRequest lr1 = new LeaveRequest("张三", 2);
            director.handleRequest(lr1);
    
            LeaveRequest lr2 = new LeaveRequest("李四", 5);
            director.handleRequest(lr2);
    
            LeaveRequest lr3 = new LeaveRequest("王五", 15);
            director.handleRequest(lr3);
    
            LeaveRequest lr4 = new LeaveRequest("赵六", 45);
            director.handleRequest(lr4);
        }
    }
  7. 运行结果


模式优缺点

职责链模式优势以下:

  1. 下降耦合度。对象不需知道是谁处理请求,之需等待处理结果便可。接收者和发送则都没有对方的明确信息,且链中的对象不须要知道链的结构,由客户端负责链的建立
  2. 简化对象的相互链接。请求处理对象仅需维持一个指向其后继者的引用,而不需维持对全部候选处理者的引用
  3. 加强给对象指派职责的灵活性。能够经过在运行时对该链进行动态的增长或修改来增长或改变一个请求
  4. 增长新的请求处理类很方便。增长一个新的具体请求处理者无须修改源代码,只需在客户端从新建链便可,符合开闭原则

职责链模式缺点以下:

  1. 不能保证请求必定被接收。该请求可能一直到末端都得不处处理,也有可能没有被正确配置而得不处处理
  2. 对于较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到必定影响,进行代码调式也不方便

模式适用环境

如下状况能够考虑使用职责链模式:

  1. 有多个对象能够处理同一请求,具体哪一个对象处理由运行时刻决定
  2. 在不明确指定接收者的状况下,向多个对象中的一个提交请求。请求沿着链进行传递,寻找相应的处理者
  3. 动态指定一组对象处理请求,客户端能够动态建立职责链来处理请求,还能够动态改变链中处理者之间的前后次序

纯与不纯的职责链模式

一个纯的职责链模式要求某一处理者对象要么接收请求,承担责任,要么把责任推给下家。在一个不纯的职责链模式里面,一个请求能够被由某一处理对象承担一部分责任后,又将责任往下传,或者最终不被任何接收端对象所接收。实际中咱们接触到的大可能是不纯的职责链模式。


上一站:软件设计模式学习(十六)代理模式
下一站:软件设计模式学习(十八)命令模式

相关文章
相关标签/搜索