【设计模式In Java】十二、职责链模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CL_YD/article/details/88079141

职责链模式

定义

职责链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。

场景

在web应用程序中,一般都会使用到filter,即拦截请求并对请求做一定处理,比如解码、验证是否登录、验证用户是否有权限、token是否失效等,可能会有新的操作加入,也可能会去掉一些filter,客户端可以直接依次调用filter,但是一旦修改顺序或增删filter就必须修改代码,这时候可以使用职责链模式,可以将filter信息放入配置,方便灵活地组合和使用。

UML类图

在这里插入图片描述

代码

public class TestChain {

    @Test
    public void test() {
        Filter filter = new LoginCheckFilter().setNext(new TokenFilter().setNext(new PermissionFilter().setNext(new UrlDecodeFilter())));
        Map<String, String> header = new HashMap<>();
        header.put("token", "1");
        header.put("user", "admin");
        Request request = new Request("http://www.google.com/s=%7B%7D", header);
        filter.handle(request);
        System.out.println(request.getUrl());

        header.put("user", "ashe");
        filter.handle(new Request("http://www.google.com/s=%7B%7D", header));


        /*
        Check login status...
        Check token...
        Check permission...
        URL decode...
        http://www.google.com/s={}
        Check login status...
        Check token...
        Check permission...
        user ashe has no permission...
         */
    }

}

总结

职责链模式一般在有链式请求的场景使用,比如审批流程、冒泡事件、过滤、预处理等等,职责链分为两种:纯的职责链和不纯的职责链,前者是需要被处理的对象最多只会在某一个处理器中得到处理,比如冒泡事件,一旦事件被处理了,就不会再向上传递;后者是需要被处理的对象会在多个处理器中被处理,比如Filter、请假条等,因为这些待处理对象不仅要被前面的处理器处理,同样需要被后面的处理器处理,处理过程中一旦检测到不满足条件就会中断。

职责链模式的主要优点如下:

  • 职责链模式使得一个对象无须知道是其他哪一个对象处理其请求,对象仅需知道该请求会被处理即可,接收者和发送者都没有对方的明确信息,且链中的对象不需要知道链的结构,由客户端负责链的创建,降低了系统的耦合度。
  • 请求处理对象仅需维持一个指向其后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的相互连接。
  • 在给对象分派职责时,职责链可以给我们更多的灵活性,可以通过在运行时对该链进行动态的增加或修改来增加或改变处理一个请求的职责。
  • 在系统中增加一个新的具体请求处理者时无须修改原有系统的代码,只需要在客户端重新建链即可,从这一点来看是符合“开闭原则”的。

职责链模式的主要缺点如下:

  • 由于一个请求没有明确的接收者,那么就不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理;一个请求也可能因职责链没有被正确配置而得不到处理。
  • 对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。
  • 如果建链不当,可能会造成循环调用,将导致系统陷入死循环。

在以下情况下可以考虑使用职责链模式:

  • 有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。
  • 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  • 可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。

猜你喜欢

转载自blog.csdn.net/CL_YD/article/details/88079141