行为型设计模式之责任链模式

介绍 责任链模式是一种链式结构,就是由一个个节点首尾相接串起来的结构,具有很好的灵活性,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首端发出,沿着链的路径依此传递每一个节点对象,直到有对象处理这个请求为止,我们将这样一种模式称为责任链模式。
定义 使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
使用场景 (1)多个对象可以处理同一请求,但具体哪个对象处理则是在运行时动态决定
(2)在请求者不明确的情况下向多个对象中的一个提交一个请求
(3)需要动态指定一组对象的处理请求
类图 行为型设计模式之责任链模式
文章图片

角色介绍:

  • AbstractHandler - 抽象处理者角色,声明一个请求处理的方法(handle())、一个获得处理级别的方法(getHandlerLever())和封装了一个对具体的处理转发逻辑实现的方法(handleRequest()),并在其中保持对下一个处理节点的AbstractHandler对象的引用(nextHandler)
  • ConcreteHandler1、2 - 具体处理者角色,对请求进行处理,如果不能处理就将请求转发给下一个节点上的处理对象
  • AbstractRequest - 抽象的请求类,里面声明了一个获得请求内容的方法(getContent())和一个获得请求处理级别的方法(getRequestLever())
  • ConcreteRequest - 具体的请求类
简单实现 在一个公司中,员工拿到了一份合同,需要上级的签名,于是员工就把合同给组长,但是组长没有权限签名,于是组长就把合同给经理,但是经理也没有足够的权限签名,于是经理就把合同给老板,老板二话不说就把合同给签了。上面的例子就是责任链模式,员工是请求的发起者,处于链的底端,而老板是处于链条顶端的类,员工发起请求后,请求经过层层转发,直至请求被处理,员工只是和组长发生了关联,后面合同被谁处理,员工并不知道,也并不关心,他在乎的是合同签名的结果,责任链模式很好的将请求的发起者与处理者解耦,下面用代码来模拟。
抽象的员工,即AbstractHandler角色
public abstract class Staff {protected Staff nextHandler; //上一级领导处理者//处理转发的逻辑 public final void handleRequest(Contract contract){ if(contract.getContractLever() < getHandlerLever()){ handle(contract); }else { if(nextHandler != null){ nextHandler.handleRequest(contract); } } }public abstract int getHandlerLever(); //自身能处理请求的级别 public abstract void handle(Contract contract); //具体的处理过程 }

在这个抽象的处理者中,一是定义了两个接口来确定一个Staff应有的行为和属性,二是封装了一个处理请求的逻辑转发方法,确定当前Staff是否有足够的级别来处理当前合同,如果没有,就把合同转发给上一级Staff,接下来是各个实现类。
组长,即ConcreteHandler角色
public class CroupStaff extends Staff {@Override public int getHandlerLever() { return 1; }@Override public void handle(Contract contract) { System.out.println("组长签名了合同!"); }}

经理,即ConcreteHandler角色
public class ManagerStaff extends Staff { @Override public int getHandlerLever() { return 2; }@Override public void handle(Contract contract) { System.out.println("经理签名了合同!"); } }

老板,即ConcreteHandler角色
public class BossStaff extends Staff { @Override public int getHandlerLever() { return 3; }@Override public void handle(Contract contract) { System.out.println("老板签名了合同!"); } }

接下来看一看请求,就是合同
抽象的合同类,即AbstractRequest角色
public abstract class Contract { public abstract String getContext(); //获得合同具体内容 public abstract int getContractLever(); //获得合同处理级别 }

具体的合同类,即ConcreteRequest角色
public class ConcreteContract extends Contract {@Override public String getContext() { return "这是一份关于房产合作的合同"; }@Override public int getContractLever() { return 3; } }

最后员工从组长发起请求
请求发起者,员工
public class Employee {public static void main(String[] args){ //构造各个节点对象 GroupStaff groupStaff = new GroupStaff(); ManagerStaff managerStaff = new ManagerStaff(); BossStaff bossStaff = new BossStaff(); //构成一条链 groupStaff.nextHandler = managerStaff; managerStaff.nextHandler = bossStaff; //发起请求 Contract contract = new ConcreteContract(); groupStaff.handleRequest(contract); }}

输出结果

老板签名了合同!

其实这里也可以直接绕过组长和经理,直接找老板签名,这也是责任链模式的灵活性,请求的发起可以从任意节点发起,同时也可以改变责任链模式内部的传递规则,如直接找老板签名。
总结 对于责任链模式中的节点,有两个行为,一是处理请求,二是将请求转发给下一个节点,不允许某个节点处理者处理了请求后又把节点转发给下一个节点。对于责任链中的请求,只有俩个结果,一个是被某个节点处理,一个是所有对象均没有处理。
【行为型设计模式之责任链模式】本文相关源码位置






    推荐阅读