责任链模式(Iterator Pattern)是行为型设计模式之一,我们将多个节点首尾相连所构成的模型称为链,如锁链,就是由一个个铁环串起来的结构。对于链式结构,每个节点都可以被拆开再连接,因此,链式结构也具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首端发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,我们将这样的一种模式称为责任链模式,
定义:
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,只到有对象处理为止。
使用场景:
多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
在请求处理者不明确的情况下向多个对象中的一个提交一个请求。
需要动态指定一组对象处理请求。
UML类图:
Handler:抽象处理者角色,声明一个请求处理方法,并在其中保持一个对下一个处理节Handler对象的引用
ConcreteHandler:具体处理者角色,对请求进行处理,如果不能处理则将该请求转发给下一个节点上的处理对象
示例:
1.
public abstract class Handler {
protected Handler successor; //下一节点的处理者
/**
* 请求处理
* @param action 条件
*/
public abstract void handlerRequest(String action);
}
public class ConcreteHandler1 extends Handler{
@Override
public void handlerRequest(String action) {
if("ch1".equals(action)){
System.out.println("ch1当前对象处理");
}else {
successor.handlerRequest(action);
}
}
}
public class ConcreteHandler2 extends Handler {
@Override
public void handlerRequest(String action) {
if("ch2".equals(action)){
System.out.println("ch2当前对象处理");
}else {
successor.handlerRequest(action);
}
}
}
public class Client {
public static void main(String[] args) {
//构造ConcreteHandler对象
ConcreteHandler1 handler1 = new ConcreteHandler1();
ConcreteHandler2 handler2 = new ConcreteHandler2();
//设置对象的下一个节点
handler1.successor = handler2;
handler2.successor = handler1;
//处理请求
handler1.handlerRequest("ch2");
}
}
2.
假如我出差回来向组长报销费用,假如费用为9万,如果他没有权限审批,组长就拿着发票去找主管,如主管也没有权限,主管再去找经理,最后经理把票据交到老板那审批,每一类人为这条链上的一个节点,老王为发起者,如果审批的权限不够,会一层一层的向上级请求审批。该流程中老王只与组长产生关联,后面具体谁处理,他并不关心,唯一只在乎结果。 责任链模式很好的将请求的发起者与处理者解耦
public abstract class Leader {
protected Leader nextHandler; //上一级领导处理者
public final void handlerRequest(int money){
if(money <= limit()){
handle(money);
}else {
if(null != nextHandler){
nextHandler.handlerRequest(money);
}
}
}
/**
* 自身能批复的额度权限
* @return
*/
public abstract int limit();
/**
* 具体金额
* @param money
*/
public abstract void handle(int money);
}
//1.定义了两个抽象接口方法来确定一个领导者应有的行为和属性
//2.声明了一个处理报账请求的方法来确定当前领导是否有能力处理报账请求,如果没有权限,则将该请求转发给上级领导
public class GroupLeader extends Leader {
@Override
public int limit() {
// TODO Auto-generated method stub
return 1000;
}
@Override
public void handle(int money) {
System.out.println("组长审批" + money + "元");
}
}
public class Director extends Leader {
@Override
public int limit() {
// TODO Auto-generated method stub
return 5000;
}
@Override
public void handle(int money) {
System.out.println("主管审批" + money + "元");
}
}
public class Manager extends Leader {
@Override
public int limit() {
// TODO Auto-generated method stub
return 10000;
}
@Override
public void handle(int money) {
System.out.println("经理审批" + money + "元");
}
}
public class Boss extends Leader {
@Override
public int limit() {
// TODO Auto-generated method stub
return 100000;
}
@Override
public void handle(int money) {
System.out.println("老板审批" + money + "元");
}
}public class Boss extends Leader {
@Override
public int limit() {
// TODO Auto-generated method stub
return 100000;
}
@Override
public void handle(int money) {
System.out.println("老板审批" + money + "元");
}
}
public class LaoWang {
public static void main(String[] args) {
GroupLeader group = new GroupLeader();
Director director = new Director();
Manager manager = new Manager();
Boss boss = new Boss();
//设置上级对象
group.nextHandler = director;
director.nextHandler = manager;
manager.nextHandler = boss;
//发起报销申请
group.handlerRequest(90000);
}
}
责任链模式的发起可以从责任链的任何一个节点处开始,同时也可以改变责任链内部传递的规则。
对于责任链中的一个处理者对象,其只有两个行为:一是处理请求,二是将请求转送给下一个节点,一个请求最终只有两种情况,一是被某个处理对象所处理,另一个是所有对象均未对其处理,前一种称为纯的责任链,后一种情况称为不纯的责任链,实际应用中,所见的大部分为不纯的责任链。
总结:
优点:可以对请求者和处理者关系解耦,提高代码的灵活性。
缺点:对链的请求处理者遍历,如果处理过多那么遍历必定会影响性能,特别是在一些递归调用中,要慎重