美文网首页程序员的小屋程序员Java 杂谈
设计模式学习笔记(10)职责链

设计模式学习笔记(10)职责链

作者: 摆码王子 | 来源:发表于2018-05-21 19:37 被阅读53次

    本文实例代码:https://github.com/JamesZBL/java_design_patterns

    职责链(Chain of Responsibility 亦译作 “责任链”)模式中,行为型模式的一种。它的具体特征是,几乎每个行为的实现者都持有职责链中下一个行为实现者的引用,在一个实现者无法完成指派给它的职责的时候,它就会将这一职责的请求传递给下一个实现者,多个传递关系就构成了一条职责链。

    实例

    在一场海上演习中,作战指挥官负责把控全局,指挥协调舰队的各部分。指挥官发出指挥命令后,命令在各部门传递执行的过程就是一条职责链。比如,命令全体炮手做好开炮的准备,职责链就是这样的:指挥官->舰长->枪炮长->炮手,用序列图表示就是这样的:

    2018-04-27_135628.png

    按照 OOP 的惯例,我们又要开始抽象了,将责任链上的传递的消息进行抽象,形成一个 Request 类。指挥官会发布一系列类型的命令,包括行进、停止和射击,每个命令还包括一些其他的描述,比如命令的具体参数等。

    Request.java

    
    public class Request {
    
      private boolean isHandled;
    
      private final String description;
    
      private final RequestType type;
    
      protected Request(String description, RequestType type) {
    
        this.description = description;
    
        this.type = type;
    
      }
    
      public boolean isHandled() {
    
        return isHandled;
    
      }
    
      public void setHandled(boolean handled) {
    
        isHandled = handled;
    
      }
    
      public String getDescription() {
    
        return description;
    
      }
    
      public RequestType getType() {
    
        return type;
    
      }
    
      public void markRequest() {
    
        setHandled(true);
    
      }
    
      @Override
    
      public String toString() {
    
        return getDescription();
    
      }
    
      public enum RequestType {
    
        // 射击
    
        SHOOTING,
    
        // 航行
    
        SAILING,
    
        // 待命
    
        AWAIT_ORDERS
    
      }
    
    }
    
    

    同样,职责链上每个节点的类都应当至少实现同一个命令处理接口,这个接口只有一个方法即 “处理请求”,这里就是根据上一级领导的命令作出具体的动作,这里用抽象类来实现:

    RequestHandler.java

    
    public abstract class RequestHandler {
    
      private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
    
      private RequestHandler next;
    
      public RequestHandler(RequestHandler next) {
    
        this.next = next;
    
      }
    
      public void handleRequest(Request request) {
    
        if (null != next) {
    
          next.handleRequest(request);
    
        }
    
      }
    
      @Override
    
      public abstract String toString();
    
      protected void printHandleMessage(Request request) {
    
        LOGGER.info("{}处理消息中,消息内容为:{}", this, request);
    
      }
    
    }
    
    

    那么,这条职责链由谁来创建呢?如果这只队伍是指挥官组织起来的,那么当然要由指挥官来创建了,那么就有了这个指挥官类:

    Commander.java

    
    public class Commander {
    
      private RequestHandler chain;
    
      public Commander() {
    
        createChain();
    
      }
    
      private void createChain() {
    
        chain = new Captain(new Gunny(new Gunner(null)));
    
      }
    
      public void handleRequest(Request request) {
    
        chain.handleRequest(request);
    
      }
    
    }
    
    

    指挥官通过三种级别的成员的构造方法,构造出一条完整的职责链,然后将命令发送给链上的第一个节点,那么这条命令就会逐级传递下去,最终被执行了。

    App.java

    
    public class Application {
    
      public static void main(String[] args) {
    
        Commander commander = new Commander();
    
        commander.handleRequest(new Request("正常航行", Request.RequestType.SAILING));
    
        commander.handleRequest(new Request("原地待命", Request.RequestType.AWAIT_ORDERS));
    
        commander.handleRequest(new Request("发射驱逐导弹", Request.RequestType.SHOOTING));
    
      }
    
    }
    
    

    总结

    职责链模式在现实世界中的应用:

    • Tomcat 服务器对编码的处理

    • Spring MVC 的拦截器

    • Servlet 的 Filter

    客户端发送给服务器的请求由 Filter(过滤器)进行预先处理,多个不同功能的 Filter 构成一条 FilterChian,请求经过这条 FilterChian 处理后最终到达 Servlet,在这里被最终处理。

    职责链模式的侧重点在单个环节上,它不过多的关注其他行为实现者的特征。职责链上的每个节点都至少持有下一个实现者的引用,和数据结构中的 “链表” 类似,链上的消息具有单项传递性,这个节点任务完成后将消息发送给链上的下一个节点,依次传递下去,最终构成一条职责链。

    个人博客同步更新,获取更多技术分享请关注:郑保乐的博客

    相关文章

      网友评论

        本文标题:设计模式学习笔记(10)职责链

        本文链接:https://www.haomeiwen.com/subject/dtbqjftx.html