美文网首页设计模式系列篇
设计模式系列篇(十五)——职责链模式

设计模式系列篇(十五)——职责链模式

作者: 复旦猿 | 来源:发表于2020-09-01 22:42 被阅读0次

    What

    职责链模式(Chain Of Responsibility Design Pattern)是一种行为设计模型。该模式将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。通过定义可以看出,请求只会被职责链上的某一节点处理,而且该请求一旦被处理,则不会继续往下传递。但在实际生产中,职责链模式则会十分灵活,允许请求经过职责链上的所有节点的处理,如敏感词过滤器的设计,我们会使用多种不同的敏感词过滤算法组成职责链,分别对输入文本进行敏感词的过滤。

    Why

    1. 对象仅需知道该请求会被处理即可,且链中的对象不需要知道链的结构,由客户端负责链的创建,降低了系统的耦合度。
    2. 请求处理对象仅需维持一个指向其后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的相互连接。
    3. 在给对象分派职责时,职责链可以给我们更多的灵活性,可以在运行时对该链进行动态的增删改,改变处理一个请求的职责。
    4. 新增一个新的具体请求处理者时无须修改原有代码,只需要在客户端重新建链即可,符合 "开闭原则"。

    When

    一个事件需要经过多个对象处理是一个挺常见的场景,譬如采购审批流程,请假流程,软件开发中的异常处理流程,web请求处理流程等各种各样的流程,可以考虑使用责任链模式来实现。

    How

    职责链模式包含以下几个类:
    Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象,作为其对下家的引用。通过该引用,处理者可以连成一条链。
    ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。
    HandlerChain(处理客户端):该类定义了对象链的初始化、增加及删除,以及职责链的调用入口。对象链有两种实现方式:一种是使用链表来存储处理器,另一种是使用数组来存储处理器,后面一种实现方式更加简单。
    下面,我们就以奖学金的申请流程为例,来向大家介绍职责链模式的实现方式。奖学金申请时需要经过填写奖学金申请表、导师签字、学院审核、学校审核这几个大的步骤,每一步都可以抽象为一个ConcreteHandler类,继承自一个抽象类Handler。
    首先,我们先定义奖学金申请表格——ScholarshipApplyForm类;

    public class ScholarshipApplyForm {
        private String name;
        private String ID;
        private String studentId;
        private String applyCause;
        private String mentor;
        private String school;
        private String mentorSuggestion;
        private String schoolSuggestion;
        private String universitySuggestion;
        private String status;
    
        // Omitting Getter And Setter
    }
    

    接下来,抽象类Handler及其子类。

    public abstract class Handler {
        protected Handler successor = null;
    
        public void setSuccessor(Handler successor) {
            this.successor = successor;
        }
    
        public final void handle() {
            doHandle();
            if (successor != null) {
                successor.handle();
            }
        }
    
        protected abstract void doHandle();
    }
    

    这里使用模版模式,将调用 successor.handle() 的逻辑从具体的处理器类中剥离出来,放到抽象父类中。这样具体的处理器类只需要实现自己的业务逻辑就可以了。

    接下来,我们分别实现其子类。

    public class StudentHandler extends Handler {
    
        @Override
        protected void doHandle(ScholarshipApplyForm form) {
            form.setStatus("The form has been fulfilled. Wait for mentor to sign");
        }
    }
    
    public class MentorHandler extends Handler {
    
        @Override
        protected void doHandle(ScholarshipApplyForm form) {
            form.setStatus("The mentor has signed. Wait for school to approve.");
        }
    }
    
    public class SchoolHandler extends Handler {
    
        @Override
        protected void doHandle(ScholarshipApplyForm form) {
            form.setStatus("The school has approved. Wait for university to approve.");
        }
    }
    
    public class UniversityHandler extends Handler {
    
        @Override
        protected void doHandle(ScholarshipApplyForm form) {
            form.setStatus("The university has approved. Award scholarships.");
        }
    }
    

    然后,我们定义HandlerChain类,这里我们采用链表的方式实现。

    public class HandlerChain {
        private Handler head = null;
        private Handler tail = null;
    
        public void addHandler(Handler handler) {
            handler.setSuccessor(null);
            if (head == null) {
                head = handler;
                tail = handler;
                return;
            }
            tail.setSuccessor(handler);
            tail = handler;
        }
    
        public void handle(ScholarshipApplyForm form) {
            if (head != null) {
                head.handle(form);
            }
        }
    }
    

    最后,测试类走起。

    public class TestMain {
        public static void main(String[] args) {
            ScholarshipApplyForm form = new ScholarshipApplyForm();
            form.setName("Jeremy");
            form.setID("302911202009010011");
            form.setStudentId("20200901111");
            form.setApplyCause("I am so great!");
            form.setMentor("Tom");
            form.setSchool("Software School");
    
            HandlerChain chain = new HandlerChain();
            Handler studentHandler = new StudentHandler();
            Handler mentorHandler = new MentorHandler();
            Handler schoolHandler = new SchoolHandler();
            Handler universityHandler = new UniversityHandler();
            chain.addHandler(studentHandler);
            chain.addHandler(mentorHandler);
            chain.addHandler(schoolHandler);
            chain.addHandler(universityHandler);
    
            chain.handle(form);
        }
    }
    

    输出如下:

    The form has been fulfilled. Wait for mentor to sign.
    The mentor has signed. Wait for school to approve.
    The school has approved. Wait for university to approve.
    The university has approved. Award scholarships.
    

    代码地址

    i-learning

    写在最后

    如果你觉得我写的文章帮到了你,欢迎点赞、评论、分享、赞赏哦,你们的鼓励是我不断创作的动力~

    相关文章

      网友评论

        本文标题:设计模式系列篇(十五)——职责链模式

        本文链接:https://www.haomeiwen.com/subject/njsbsktx.html