• 《设计模式之美》


    一、职责链模式介绍

    前几节课中,我们学习了模板模式、策略模式,今天,我们来学习职责链模式。这三种模式具有相同的作用:复用和扩展,在实际的项目开发中比较常用,特别是框架开发中,我们可以利用它们来提供框架的扩展点,能够让框架的使用者在不修改框架源码的情况下,基于扩展点定制化框架的功能。

    职责链模式将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。在职责链模式中,多个处理器(也就是刚刚定义中说的“接收对象”)依次处理同一个请求。一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。

    举例:

    public interface IHandler {
      boolean handle();
    }
    
    public class HandlerA implements IHandler {
      @Override
      public boolean handle() {
        boolean handled = false;
        //...
        return handled;
      }
    }
    
    public class HandlerB implements IHandler {
      @Override
      public boolean handle() {
        boolean handled = false;
        //...
        return handled;
      }
    }
    
    public class HandlerChain {
      private List<IHandler> handlers = new ArrayList<>();
    
      public void addHandler(IHandler handler) {
        this.handlers.add(handler);
      }
    
      public void handle() {
        for (IHandler handler : handlers) {
          boolean handled = handler.handle();
          if (handled) {
            break;
          }
        }
      }
    }
    
    // 使用举例
    public class Application {
      public static void main(String[] args) {
        HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA());
        chain.addHandler(new HandlerB());
        chain.handle();
      }
    }
    

      在 GoF 给出的定义中,如果处理器链上的某个处理器能够处理这个请求,那就不会继续往下传递请求。实际上,职责链模式还有一种变体,那就是请求会被所有的处理器都处理一遍,不存在中途终止的情况。举例:

    public abstract class Handler {
      protected Handler successor = null;
    
      public void setSuccessor(Handler successor) {
        this.successor = successor;
      }
    
      public final void handle() {
        doHandle();
        if (successor != null) {
          successor.handle();
        }
      }
    
      protected abstract void doHandle();
    }
    
    public class HandlerA extends Handler {
      @Override
      protected void doHandle() {
        //...
      }
    }
    
    public class HandlerB extends Handler {
      @Override
      protected void doHandle() {
        //...
      }
    }
    
    public class HandlerChain {
      private Handler head = null;
      private Handler tail = null;
    
      public void addHandler(Handler handler) {
        handler.setSuccessor(null);
    
        if (head == null) {
          head = handler;
          tail = handler;
          return;
        }
    
        tail.setSuccessor(handler);
        tail = handler;
      }
    
      public void handle() {
        if (head != null) {
          head.handle();
        }
      }
    }
    
    // 使用举例
    public class Application {
      public static void main(String[] args) {
        HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA());
        chain.addHandler(new HandlerB());
        chain.handle();
      }
    }

    二、职责链模式的应用场景举例

    我们学习一下职责链模式的应用场景。对于支持 UGC(User Generated Content,用户生成内容)的应用(比如论坛)来说,用户生成的内容(比如,在论坛中发表的帖子)可能会包含一些敏感词(比如涉黄、广告、反动等词汇)。针对这个应用场景,我们就可以利用职责链模式来过滤这些敏感词。对于包含敏感词的内容,我们有两种处理方式,一种是直接禁止发布,另一种是给敏感词打马赛克(比如,用 *** 替换敏感词)之后再发布。第一种处理方式符合 GoF 给出的职责链模式的定义,第二种处理方式是职责链模式的变体。

    应用设计模式主要是为了应对代码的复杂性,让其满足开闭原则,提高代码的扩展性。这里应用职责链模式也不例外。

    首先,我们来看,职责链模式如何应对代码的复杂性。

    将大块代码逻辑拆分成函数,将大类拆分成小类,是应对代码复杂性的常用方法。应用职责链模式,我们把各个敏感词过滤函数继续拆分出来,设计成独立的类。其次,我们再来看,职责链模式如何让代码满足开闭原则,提高代码的扩展性。当我们要扩展新的过滤算法的时候,只需要新添加一个 Filter 类,并且通过 addFilter() 函数将它添加到 FilterChain 中即可,其他代码完全不需要修改。

    本质上来说,它跟大部分设计模式一样,都是为了解耦代码,应对代码的复杂性,让代码满足开闭原则,提高代码的可扩展性。职责链模式常用在框架的开发中,为框架提供扩展点,让框架的使用者在不修改框架源码的情况下,基于扩展点添加新的功能。实际上,更具体点来说,职责链模式最常用来开发框架的过滤器和拦截器。

  • 相关阅读:
    [转]nginx+fastcgi+c/c++搭建高性能Web框架
    [转]向facebook学习,通过协程实现mysql查询的异步化
    [转]ReactPHP── PHP版的Node.js
    [转]nodejs npm常用命令
    [LINK]php的三种CLI常量:STDIN,STDOUT,STDERR
    苹果iPhone如何区分港版、国行、水货
    16进制字符串转36进制字符串
    设置apache https服务
    [转]Class 'ThinkLog' not found
    PHP PSR规范
  • 原文地址:https://www.cnblogs.com/sunada2005/p/14415818.html
Copyright © 2020-2023  润新知