设计模式之职责链模式

设计模式之职责链模式

  职责链模式主要是为了解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求,将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象。

职责链模式结构图

  Handler(抽象处理者),ConcreteHandler(具体处理者)和Client(客户类)。
在这里插入图片描述
Handler(抽象处理者):抽象处理者定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家是一个矗立着,因此抽象处理者,因此抽象处理者中定义了一个自类型(抽象处理者类型)的对象,作为下家的引用。

ConcreteHandler(具体处理者):具体处理者是抽象处理者的子类,它可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者。具体处理者中可以访问链中下一个对象,以便请求的转发。

Client(客户类):客户类用于向链中的对象提出最初的请求,客户类只需要关心链的源头,而无须关心请求的处理细节以及请求的传递过程。

职责链模式示例

  在公司里,我们请假实际上也是有流程需要走的,主要是请假审批的流程,当普通员工小李,想要请假;公司的规章制度规定了,如果小于1天,包含1天,则可以直接部门主管审批;如果请假1-3天,主管审批后,还需要部门经理审批;如果请假大于3天,除了主管和部门经理审批,还需要公司的总经理审批才可以。公司的请假规定的请假审批流程,就是一种典型的职责链模式。

LeaveRequest(请求类),报表显示方式的抽象类:

/*请求类,请假条类*/
public class LeaveRequest {

    private String leaveName;
    private int leaveDays;

    public LeaveRequest(String leaveName, int leaveDays) {
        this.leaveName = leaveName;
        this.leaveDays = leaveDays;
    }
    //getter and setter
}

  Handler(抽象处理者),在这个例子中,它的具体处理者类有主管,部门经理和公司总经理:

/*抽象处理者,领导类*/
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);
}

  ConcreteHandler(具体处理者),主管类(Supervisor)继承自Handler(抽象处理者)Leader类:

/*具体处理者类,主管*/
public class Supervisor extends Leader{

    public Supervisor(String name) {
        super(name);
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        //小于等于1天,主管审批即可
        if (request.getLeaveDays() <= 1){
            System.out.println("主管:" + name + "同意" +request.getLeaveName() + "请假" + request.getLeaveDays() + "天");
        }else {
            System.out.println("主管:" + name + "同意" +request.getLeaveName() + "请假" + request.getLeaveDays() + "天");
            //其他情况继续给其他领导审批
            if (this.successor != null){
                this.successor.handleRequest(request);
            }
        }
    }
}

  ConcreteHandler(具体处理者),部门经理类(DepartmentManager)继承自Handler(抽象处理者)Leader类:

/*具体处理者类,部门经理*/
public class DepartmentManager extends Leader {

    public DepartmentManager(String name) {
        super(name);
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        //大于1天,小于等于3天的,部门经理审批即可
        if (request.getLeaveDays() <= 3){
            System.out.println("部门经理:" + name + "同意" +request.getLeaveName() + "请假" + request.getLeaveDays() + "天");
        }else {
            System.out.println("部门经理:" + name + "同意" +request.getLeaveName() + "请假" + request.getLeaveDays() + "天");
            //其他情况继续给其他领导审批
            if (this.successor != null){
                this.successor.handleRequest(request);
            }
        }
    }
}

  ConcreteHandler(具体处理者),公司总经理类(GeneralManager)继承自Handler(抽象处理者)Leader类:

/*具体处理者类,公司总经理*/
public class GeneralManager extends Leader {

    public GeneralManager(String name) {
        super(name);
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        //大于3天的,需要公司总经理审批
        if (request.getLeaveDays() > 3){
            System.out.println("公司总经理:" + name + "同意" +request.getLeaveName() + "请假" + request.getLeaveDays() + "天");
        }
    }
}

  客户类,也就是测试类实现如下:

/*客户端测试类,Client*/
public class Client {
    public static void main(String[] args) {
        Leader supervisor,departmentManager,generalManager;

        supervisor = new Supervisor("张三三");
        departmentManager = new DepartmentManager("王五五");
        generalManager = new GeneralManager("李六六");

        supervisor.setSuccessor(departmentManager);//主管处理完,下一个处理的是部门经理
        departmentManager.setSuccessor(generalManager);//部门经理处理完是公司总经理处理

        System.out.println("-------------------------请1天---------------------------------");
        LeaveRequest leaveRequest1 = new LeaveRequest("小李",1);
        supervisor.handleRequest(leaveRequest1);

        System.out.println("-------------------------请2天---------------------------------");
        LeaveRequest leaveRequest2 = new LeaveRequest("小李",2);
        supervisor.handleRequest(leaveRequest2);

        System.out.println("-------------------------请5天---------------------------------");
        LeaveRequest leaveRequest3 = new LeaveRequest("小李",5);
        supervisor.handleRequest(leaveRequest3);
    }
}

  测试程序执行结果:
在这里插入图片描述

什么场景下使用职责链模式

  一种情况是如果有多个对象需要处理同一个请求,具体哪个独享处理该请求由运行时刻自动确定,客户端只需要将请求提交到链上。另外一种情况,如果需要可动态指定一组对象处理请求,客户端可以动态的创建职责量来处理请求,还可以动态改变链中处理者之间的先后次序。

职责链模式优缺点
优点:
  • 降低耦合度,职责链模式使得一个对象无需知道是其他哪一个对象处理其请求。对象只需要知道该请求会处理即可,客户端负责链的创建。
  • 简化了对象的互相连接,只需要维持一个指向其后继者的应用而不需要维持它对所有候选处理者的应用。
  • 增加请求处理类方便,新增一个,只需要客户端重新建链即可,不需要修改其他具体的请求处理类。
缺点:
  • 没法保证请求一定被接收,既然一个请求没有明确的接收者,那么就没法保证一定会被处理。
  • 较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响,并且调试也很不方便变。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值