设计模式之职责链模式

定义

职责链( Chain of Responsibility )模式也被叫做责任链模式,在《设计模式》属于行为型模式,是一个请求有多个对象来处理,这些对象是一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到有对象处理它为止。责任链模式将请求和处理分离开来,进行解耦。

UML类图

这里写图片描述

具体角色

1、抽象处理者( Handler )角色:定义一个处理请求的抽象类。如果需要,可以定义一个方法以设定和返回对下家的引用。

2、具体处理者( ConcreteHandler ) 角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

举个例子

很常见的一个场景:请假。假定请假3天以内,由项目经理直接审批;3-5天,由部门经理审批通过;大于5天,则由总经理通过。

如果把上面的场景应用到责任链模式中去,项目经理、部门经理、总经理就是一个个具体的责任人,他们可以对请求做出处理,但是他们也只能在自己的权限范围内处理该请求。

编写代码

抽象处理类:

/**
 * 抽象处理者
 */
public static abstract class Handler {
    private Handler nextHandler;
    // 当前领导能审批通过的最多天数
    public int maxDay;
    protected Handler(int maxDay) {
        this.maxDay = maxDay;
    }
    //设置责任链中下一个处理请求的对象
    public void setNextHandler(Handler handler) {
        nextHandler = handler;
    }
    protected void handleRequest(int day) {
        if (day <= maxDay) {
            reply(day);
        } else {
            if (nextHandler != null) {
                //审批权限不够,继续上报
                nextHandler.handleRequest(day);
            } else {
                System.out.println("没有更高的领导审批了");
            }
        }
    }
    protected abstract void reply(int day);
}
具体处理者

项目经理

/**
 * 项目经理
 */
class ProjectManager extends Handler {
    public ProjectManager(int day) {
        super(day);
    }
    @Override
    protected void reply(int day) {
        LogUtil.d(day + "天请假,项目经理直接审批通过");
    }
}

部门经理

/**
 * 部门经理
 */
class DepartmentManager extends Handler {
    public DepartmentManager(int day) {
        super(day);
    }
    @Override
    protected void reply(int day) {
        LogUtil.d(day + "天请假,部门经理审批通过");
    }
}

总经理

/**
 * 总经理
 */
class GeneralManager extends Handler {
    public GeneralManager(int day) {
        super(day);
    }
    @Override
    protected void reply(int day) {
        LogUtil.d(day + "天请假,总经理审批通过");
    }
}

测试

Handler projectManager = new ProjectManager(3);
Handler departmentManager = new DepartmentManager(5);
Handler generalManager = new GeneralManager(15);
//创建职责链
projectManager.setNextHandler(departmentManager);
departmentManager.setNextHandler(generalManager);
//发起一次请求
projectManager.handleRequest(10);

结果:

10天请假,总经理审批通过

总结

应用场景

在实际软件开发中,如果遇到有多个对象可以处理同一请求时可以考虑使用职责链模式,最常见的例子包括在 Java Web 应用开发中创建一个过滤器(Filter)链来对请求数据进行过滤(中文字符乱码的处理)、在工作流系统中实现公文的分级审批、在Struts应用中添加不同的拦截器(常用的有类型转化、异常处理,数据校验…)以增强Struts2的功能等。

优点
  • 降低耦合度,使请求的发送者和接收者解耦,便于灵活的、可插拔的定义请求处理过程;
  • 简化、封装了请求的处理过程,并且这个过程对客户端而言是透明的,以便于动态地重新组织链以及分配责任,增强请求处理的灵活性;
  • 可以从职责链任何一个节点开始,也可以随时改变内部的请求处理规则,每个请求处理者都可以去动态地指定他的继任者;
  • 职责链可简化对象间的相互连接。它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用;
  • 增加新的请求处理类很方便。
缺点
  • 不能保证请求一定被接收。既然一个请求没有明确的接收者,那么就不能保证它一定会被处理;
  • 该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理;
  • 系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值