责任链模式

        行为型设计模式;收到请求后,链上的每个处理者都可以对请求进行处理,或可以将请求传递给下个处理者。

为什么需要责任链模式

        如果不直接使用责任链模式,有下面一个场景:用户在使用一个在线交易系统,目前已经有如下权限控制:只允许认证用户创建订单,管理员可以查看所有订单。

        在几个月的开发中,又实现了几个过滤。如防止暴力破解密码,相同的请求缓存等。

        问题在于,代码本就臃肿不堪,然后还不断增加新的过滤逻辑。

        这也就是责任链模式出现的原因。

        像上面的场景,就可以使用责任链,定义清楚需要进行的过滤,每个功能建个相应的类,进行链式处理。

责任链模式的优点

  • 单一职责原则。可以对发起操作和执行操作的类进行解耦。
  • 开闭原则。可以在不更改现有代码的情况下新增处理者。

源码实现

        实现场景:从小明参加某公司的面试开始,某公司的招聘流程就是上面说的 3 轮面试。招聘流程的面试官分别是:第一面是组长老刚,第二面是部门经理老孙,第三面也就是终面是 HR 老刘。为什么说这个场景符合责任链模式呢?首先不管是组长还是部门经理还是 HR,他们都作为面试官,面试官赋予他们的权利是去面试来公司面试的同学,而面试的结果是可传递性的,也就是如果面试通过,就会到下一轮面试,最终成为一条传递链。

@Data
@NoArgsConstructor
class Interviewee {
    private String name;
    private String age;
    private Boolean teamLeaderOpinion;
    private Boolean departmentManagerOpinion;
    private Boolean hrOpinion;
}

abstract class Interviewer {
    protected String name;
    protected Interviewer nextInterviewer;

    public Interviewer() {}

    public void setNextInterviewer(Interviewer nextInterviewer) {
        this.nextInterviewer = nextInterviewer;
    }

    public abstract void handleInterview(Interviewee interviewee) throws Exception;
}

@Data
@Slf4j
class TeamLeader extends Interviewer {

    @Override
    public void handleInterview(Interviewee interviewee) throws Exception {
        log.info("team leader interviewing!");
        interviewee.setTeamLeaderOpinion(new Random().nextBoolean());
        if (interviewee.getTeamLeaderOpinion()) {
            log.info("team leader passed!");
            nextInterviewer.handleInterview(interviewee);
        } else {
            //抛出定制化错误,这里就直接抛出通用错误了
            throw new Exception("组长面试不通过!");
        }
    }
}

@Data
@Slf4j
class DepartmentManager extends Interviewer {

    @Override
    public void handleInterview(Interviewee interviewee) throws Exception {
        log.info("department manager interviewing!");
        interviewee.setDepartmentManagerOpinion(new Random().nextBoolean());
        if (interviewee.getDepartmentManagerOpinion()) {
            log.info("department manager passed!");
            nextInterviewer.handleInterview(interviewee);
        } else {
            //抛出定制化错误
            throw new Exception("部门主管面试不通过!");
        }
    }
}

@Data
@Slf4j
class Hr extends Interviewer {

    @Override
    public void handleInterview(Interviewee interviewee) throws Exception {
        log.info("hr interviewing!");
        interviewee.setHrOpinion(new Random().nextBoolean());
        if (interviewee.getHrOpinion()) {
            log.info("hr passed!");
        } else {
            //抛出定制化错误
            throw new Exception("HR面试不通过!");
        }
    }
}

		@Test
    public void interviewChainTest() {
        int i = 0;
        while (i < 10) {
            try {
                Interviewee interviewee = new Interviewee();
                interviewee.setName("面试者");

                TeamLeader teamLeader = new TeamLeader();
                teamLeader.name = "组长";

                DepartmentManager dm = new DepartmentManager();
                dm.name = "部门主管";

                Hr hr = new Hr();
                hr.name = "HR";

                teamLeader.setNextInterviewer(dm);
                dm.setNextInterviewer(hr);

                teamLeader.handleInterview(interviewee);
                i++;
            } catch (Exception e) {
                log.error("面试不通过", e);
            }
        }

    }

若有收获,就点个赞吧

上一篇:操作系统


下一篇:力扣98——验证搜索二叉树