zoukankan      html  css  js  c++  java
  • 责任链模式

    一、责任链模式介绍

    1、定义与类型

    为请求创建一个接收此次请求对象的链
    类型:行为型

    2、适用场景

    一个请求的处理需要多个对象当中的一个或几个协作处理

    3、优点

    请求的发送者和接收者(请求的处理)解耦
    责任链可以动态组合

    4、缺点

    责任链太长或者处理时间过长,影响性能
    责任链有可能过多

    5、相关设计模式

    责任链模式和状态模式
    责任链模式中,各个对象并不指定下一个处理对象者是谁,只有客户端来设置顺序和元素,直到被某个责任链元素处理或者整个责任链结束。
    状态模式是让每个状态对象知道下一个状态对象是谁,在编译时就设定好了。

    二、代码示例

    模拟场景:发布课程,课程中需要含有手记和视频,才能批准;
    第一步,先检查手记,不为空才能批准,否则不批准
    第二步,再检查视频,不为空才能批准,否则不批准

    课程类:

    public class Course {
        private String name;
        private String article;
        private String video;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getArticle() {
            return article;
        }
    
        public void setArticle(String article) {
            this.article = article;
        }
    
        public String getVideo() {
            return video;
        }
    
        public void setVideo(String video) {
            this.video = video;
        }
    
        public Course(String name, String article, String video) {
            this.name = name;
            this.article = article;
            this.video = video;
        }
    
        public Course() {
        }
    }
    

    1、v1版本(Appover):

    处理抽象类:

    public abstract class Appover {
        protected Appover nextAppover;
    
        public void setNextAppover(Appover nextAppover){
            this.nextAppover = nextAppover;
        }
    
        public abstract void deploy(Course course);
    }
    

    手记处理类:

    public class ArticleAppover extends Appover {
        @Override
        public void deploy(Course course) {
            if (StringUtil.isNotEmpty(course.getArticle())){
                System.out.println(course.getName() + " 含有手记, 批准");
                if (nextAppover != null){
                    nextAppover.deploy(course);
                } else  {
                    System.out.println("链条结束");
                }
            } else {
                System.out.println(course.getName() + " 不包含有手记, 不批准,流程结束");
                return;
            }
        }
    }
    

    视频处理类:

    public class VideoAppover extends Appover {
        @Override
        public void deploy(Course course) {
            if (StringUtil.isNotEmpty(course.getVideo())){
                System.out.println(course.getName() + " 含有视频, 批准");
                if (nextAppover!= null){
                    nextAppover.deploy(course);
                } else  {
                    System.out.println("链条结束");
                }
            } else {
                System.out.println(course.getName() + " 不包含有视频, 不批准,流程结束");
                return;
            }
        }
    }
    

    测试类:

    public class Test {
        public static void main(String[] args) {
            Appover articleAppover = new ArticleAppover();
            Appover videoAppover = new VideoAppover();
            articleAppover.setNextAppover(videoAppover);
    
            Course course1 = new Course("责任链模式讲解", "手记", "视频");
            articleAppover.deploy(course1);
    
            Course course2 = new Course();
            course2.setName("设计模式");
            articleAppover.deploy(course2);
        }
    }
    

    输出:
    责任链模式讲解 含有手记, 批准
    责任链模式讲解 含有视频, 批准
    链条结束
    设计模式 不包含有手记, 不批准,流程结束

    2、v2版本(Handler),(推荐,使用起来更加灵活):

    处理抽象类:

    public abstract class AbstractHandler {
        abstract void doHandler(HandlerChainContext handlerChainContext, Course course); // handler方法
    }
    

    处理类上下文(对处理类进行包装):

    /**
     * handler上下文,主要负责维护链,和链的执行
     */
    public class HandlerChainContext {
        HandlerChainContext next; // 下一个节点
        AbstractHandler handler;
    
        public HandlerChainContext(AbstractHandler handler) {
            this.handler = handler;
        }
    
        void handler(Course course) {
            this.handler.doHandler(this, course);
        }
    
        /**
         * 继续执行下一个
         */
        void runNext(Course course) {
            if (this.next != null) {
                this.next.handler(course);
            } else {
                System.out.println("链条结束");
            }
        }
    }
    

    手记处理类:

    public class ArticleHandler extends AbstractHandler{
        @Override
        void doHandler(HandlerChainContext handlerChainContext, Course course) {
            if (StringUtil.isNotEmpty(course.getArticle())){
                System.out.println(course.getName() + " 含有手记, 批准");
                // 继续执行下一个
                handlerChainContext.runNext(course);
            } else {
                System.out.println(course.getName() + " 不包含有手记, 不批准,流程结束");
                return;
            }
        }
    }
    

    视频处理类:

    public class VideoHandler extends AbstractHandler {
        @Override
        void doHandler(HandlerChainContext handlerChainContext, Course course) {
            if (StringUtil.isNotEmpty(course.getVideo())){
                System.out.println(course.getName() + " 含有视频, 批准");
                // 继续执行下一个
                handlerChainContext.runNext(course);
            } else {
                System.out.println(course.getName() + " 不包含有视频, 不批准,流程结束");
                return;
            }
        }
    }
    

    链路类:

    public class PipelineChain {
        /**
         * 初始化的时候造一个head,作为责任链的开始,但是并没有具体的处理
         * 目的就是启动下一个handler
         */
        public HandlerChainContext head = new HandlerChainContext(new AbstractHandler() {
            @Override
            void doHandler(HandlerChainContext handlerChainContext, Course course) {
                handlerChainContext.runNext(course);
            }
        });
    
        public void requestProcess(Course course) {
            this.head.handler(course);
        }
    
        public void addLast(AbstractHandler handler) {
            HandlerChainContext context = head;
            while (context.next != null) {
                context = context.next;
            }
            context.next = new HandlerChainContext(handler);
        }
    }
    

    测试类:

    public class Test {
    
        public static void main(String[] args) {
            PipelineChain pipelineChain = new PipelineChain();
    
            // 优点:此处的 ArticleHandler 和 VideoHandler 不需要直接产生关联
            // 即可以直接在中间增加其他 Handler
            pipelineChain.addLast(new ArticleHandler());
            pipelineChain.addLast(new VideoHandler());
    
            Course course1 = new Course("责任链模式讲解", "手记", "视频");
            // 发起请求
            pipelineChain.requestProcess(course1);
    
    
            Course course2 = new Course();
            course2.setName("设计模式");
            // 发起请求
            pipelineChain.requestProcess(course2);
    
        }
    }
    

    输出:
    责任链模式讲解 含有手记, 批准
    责任链模式讲解 含有视频, 批准
    链条结束
    设计模式 不包含有手记, 不批准,流程结束

    三、源码示例

    Servlet中的Filter



  • 相关阅读:
    .NET委托与事件文章收集
    WCF简介
    设计模式之单例模式
    设计模式之工厂模式
    设计模式之简单工厂模式
    Jquery中bind和live的区别
    C#性能优化实践
    蒋金楠How ASP.NET MVC Works?[持续更新中…]
    按指定质量保存图片
    .net 获取网站根目录总结
  • 原文地址:https://www.cnblogs.com/weixk/p/13533146.html
Copyright © 2011-2022 走看看