责任链模式

一、责任链模式介绍

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

(0)

相关推荐

  • 阿里大佬告诉我,想学习设计模式,得先学好这些硬核技能

    回复"000"获取大量电子书 写在前面 我们继续学习架构师技能,今天是本系列的第二篇,希望大家持续关注. 可能你不是科班出生,甚至大学都没念,没背景没关系.我们只要每天进步一点点, ...

  • 快速掌握模板方法模式

    概述 模板模式就是定义一个操作中的算法骨架,然后将一些步骤延迟到子类中.模板方法使得子类在不改变算法的结构即可重定义该算法的某些步骤. 使用场景 泡茶 我们都知道泡茶基本步骤有: 烧水.选茶叶.泡茶. ...

  • 设计模式(七)——适配器模式(SpringMVC框架分析)

    适配器模式1 现实生活中的适配器例子泰国插座用的是两孔的(欧标),可以买个多功能转换插头 (适配器) ,这样就可以使用了. 2 基本介绍1) 适配器模式(Adapter Pattern)将某个类的接口 ...

  • 【5/25】责任链模式(Chain of Responsibility Pattern)

    这是<小游戏从0到1设计模式重构>系列内容第5篇,所有源码及资料在"程序员LIYI"公号回复"小游戏从0到1"获取. 这一小节我们尝试应用责任链模式 ...

  • PHP设计模式之责任链模式

    PHP设计模式之责任链模式 责任链模式,属于对象行为型的设计模式. Gof类图及解释 GoF定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这 ...

  • [PHP小课堂]PHP设计模式之责任链模式

    [PHP小课堂]PHP设计模式之责任链模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 三国演义:责任链模式

    单例模式 模板方法模式 装饰器模式 门面模式 策略模式 委派模式 故事 前两天,没事又刷了一遍三国演义,看到关羽身在曹营心在汉,听说刘备在袁绍那里,然后就上演了"过五关,斩六将". ...

  • 通俗易懂系列 | 设计模式(六):责任链模式

    责任链设计模式是行为设计模式之一. 责任链模式用于在软件设计中实现松散耦合,其中来自客户端的请求被传递到对象链以处理它们.然后链中的对象将自己决定谁将处理请求以及是否需要将请求发送到链中的下一个对象. ...

  • 设计模式之责任链模式

    设计模式之责任链模式

  • 责任链设计模式案例详解,看这一篇就够了

    老哥哔哔哔 责任链设计模式在日常工作中很常见,也很重要,很多开源框架都采用了责任链设计模式,比如:servlet中的Filter.Dubbo中的Filter.Mybatis中的Plugin.sprin ...

  • 崔日明:中国嵌入亚太价值链模式与中国角色变迁之路

    作为全球经济最有活力、对全球经贸增长的贡献超过2/ 3 的地区,毫无疑问,亚太地区已成为全球经贸中心,21 世纪将是亚太地区的世纪。在全球价值链已成为全球经贸合作主要形式的背景下,20 世纪90 年代 ...

  • Chain of Responsibility 职责链模式

    >>返回<C#常用设计模式> 1. 简介 2. 示例 1. 简介 定义 很多对象由每一个对象对其下家的引用而连接起来形成一条链. 请求在这个链上传递,直到链上的某一个对象决定处 ...