责任链模式(Chain of Responsibility Pattern)使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
责任链模式包含一下角色:
Handler: 抽象处理者。定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。ConcreteHandler:具体处理者。具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。Client:客户类下面我们以一个简单的请假作为示例。假设请假一天,项目经理处理就能处理,三天之类归项目总监处理,七天内归老板处理,请假不允许超过七天。 抽象处理者
public abstract class AbstractHandler { /** * 下一个处理对象 */ private AbstractHandler next; /** * 处理请假 * * @param leaveDays 天数 * @return 处理结果 */ public final String handleLeave(int leaveDays) { if (this.getLeaveDays() >= leaveDays) { return this.handle(); } else { if (Objects.nonNull(next)) { return next.handleLeave(leaveDays); } else { return "大老板都不能处理你的假期了~~"; } } } /** * 具体处理 * * @return 处理结果 */ protected abstract String handle(); /** * 每个处理类能处理的天数,数据可以使数据库获取,这里简单就写死了 * * @return 请假天数 */ protected abstract Integer getLeaveDays(); /** * 设置下一个处理类 * * @param next */ public void setNext(AbstractHandler next) { this.next = next; } }具体处理者
// 项目经理处理 public class PMHandler extends AbstractHandler { @Override protected String handle() { return "你的请假被项目经理处理了"; } @Override protected Integer getLeaveDays() { return 1; } } // 项目总监处理 public class PDHandler extends AbstractHandler { @Override protected String handle() { return "你的请假被项目总监处理了"; } @Override protected Integer getLeaveDays() { return 3; } } // 大老板处理 public class BossHandler extends AbstractHandler { @Override protected String handle() { return "你的请假被大老板处理了"; } @Override protected Integer getLeaveDays() { return 7; } }客户端
@Test public void test() { PMHandler pmHandler = new PMHandler(); PDHandler pdHandler = new PDHandler(); BossHandler bossHandler = new BossHandler(); pmHandler.setNext(pdHandler); pdHandler.setNext(bossHandler); String leaveRes = pmHandler.handleLeave(1); System.out.println(leaveRes); String leaveRes1 = pmHandler.handleLeave(3); System.out.println(leaveRes1); String leaveRes2 = pmHandler.handleLeave(7); System.out.println(leaveRes2); String leaveRes3 = pmHandler.handleLeave(8); System.out.println(leaveRes3); }责任链模式有两种使用形式:纯责任链模式和不纯的责任链模式。
如果一个类要么承担责任处理请求要么将请求踢给下一个皮球,则被称为纯责任链模式;如果一个类承担了一部分责任,还将请求踢给下一个皮球,则被称为不纯的责任链模式。纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。