行为型模式:责任链模式

责任链模式的定义

Avoid coupling the sender of a request to its receiver by giving more than one object achance to handle the request.

Chain the receiving objects and pass the request alongthe chain until an object handles it.

意思是:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。

将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

责任链模式的重点是在“链”上,由一条链去处理相似的请求,在链中决定谁来处理这个请求,并返回相应的结果

 

责任链模式涉及以下两个角色。

■ 抽象处理者(Handler)角色:该角色对请求进行抽象,并定义一个方法以设定和返回对下一个处理者的引用。

■ 具体处理者(Concrete Handler)角色:该角色接到请求后,可以选择将请求处理掉,或者将请求传给下一个处理者。

由于具体处理者持有对下一个处理者的引用,因此,如果需要,具体处理者可以访问下一个处理者。

package com.yl.design.responsible.example;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public abstract class Handler {
    private Handler successor;
    public abstract void handleRequest();
}

package com.yl.design.responsible.example;
public class ConcreteHandler extends Handler {
    @Override
    public void handleRequest() {
        if(getSuccessor()!=null){
            System.out.println("请求传递给:"+getSuccessor());
            getSuccessor().handleRequest();
        }else {
            System.out.println("请求进行处理");
        }
    }
}

package com.yl.design.responsible.example;
public class Client {
    public static void main(String[] args) {
        Handler handler1=new ConcreteHandler();
        Handler handler2=new ConcreteHandler();
        handler1.setSuccessor(handler2);
        handler1.handleRequest();
    }
}
View Code

 责任链模式的应用

1. 责任链模式的优缺点责任链模式的优点如下

■ 责任链模式将请求和处理分开,请求者不知道是谁处理的,处理者可以不用知道请求的全貌。

■ 提高系统的灵活性。责任链模式的缺点如下。

■ 降低程序的性能,每个请求都是从链头遍历到链尾,当链比较长的时候,性能会大幅下降。

■ 不易于调试,由于采用了类似递归的方式,调试的时候逻辑比较复杂。

注意责任链中的节点数量需要控制,避免出现超长链的情况,这就需要设置一个最大的节点数量,超过则不允许增加节点,避免无意识地破坏系统性能。

2. 责任链模式的应用场景

责任链模式是一种常见的模式,Struts2的核心控件FilterDispatcher是一个Servlet过滤器,该控件就是采用责任链模式,可以对用户请求进行层层过滤处理。

责任链模式在实际的项目中使用的比较多,其典型的应用场景如下。

■ 一个请求需要一系列的处理工作。

■ 业务流的处理,例如,文件审批。

■ 对系统进行补充扩展。

责任链模式的实例

击鼓传花是一种热闹而又紧张的饮酒游戏。在酒宴上宾客依次坐定位置,由一人击鼓,击鼓的地方与传花的地方是分开的,以示公正。开始击鼓时,花束就开始依次传递,鼓声一落,如果花束在某人手中,则该人就得饮酒。

击鼓传花便是责任链模式的应用。在责任链模式里,很多的对象由每一个对象对其下家的引用而连接起来形成一条链。

请求在这个链上传递,直到链上的某一个对象决定处理此请求。

发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。

显然,击鼓传花符合责任链模式的定义。

参加游戏的人是一个一个具体的处理者对象,击鼓的人便是客户端对象。花代表酒令,是传向处理者的请求,每一个参加游戏的人在接到传来的花时,

可选择的行为只有两个:将花向下传;或执行酒令喝酒。一个人不能既执行酒令,又向下家传花;当某一个人执行了酒令之后,游戏重新开始。

击鼓的人并不知道最终是由哪一个做游戏的人执行酒令,当然执行酒令的人必然是做游戏的人们中的一个。

■ 传花者就是抽象Handler角色,定义出参加游戏的传花人要遵守的规则;

■ 具体传花者是Concrete Handler角色,每一个传花者都知道下家是谁,或者执行酒令,或者把花向下传;

■ 击鼓者是Client角色,控制游戏的开始和结束

 

posted @ 2020-06-07 19:50  弱水三千12138  阅读(260)  评论(0)    收藏  举报