十八、职责链模式-推卸责任,不关我的事,我不管!#和设计模式一起旅行#

不在其位,不谋其政! –出自《论语·泰伯》故事背景在现实世界中,有很多情况下会遇到一些推卸责任的场景,比如要办理一件事的时候,被告诉你要去做个做这个事情,但是去了这个地方,确告诉要到另一个地方去,最后搞了很久,才办完这一件事。这种情况下,就可以简单的称为踢皮球,也就是推卸责任。在软件中,当外部请求程序进行某个出来,这个程序无法处理就把该请求转给其他对象负责,当对个对象组…

大家好,又见面了,我是全栈君。

不在其位,不谋其政! –出自《论语·泰伯》

故事背景

在现实世界中,有很多情况下会遇到一些推卸责任的场景,比如要办理一件事的时候,被告诉你要去做个做这个事情,但是去了这个地方,确告诉要到另一个地方去,最后搞了很久,才办完这一件事。

这种情况下,就可以简单的称为踢皮球,也就是推卸责任。

在软件中,当外部请求程序进行某个出来,这个程序无法处理就把该请求转给其他对象负责,当对个对象组成在一起,就成为一个职责链。

说白就是:当一个人被要求做什么事情的时候,如果他自己可以做就自己做,如果不能做就将“要求”转为另一个人处理,下一个如果可以自己处理,就直接处理,如果不能处理依旧转为另一个人,这就是 Chain of Responsibility模式。

故事主角

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

职责链类图

在职责链模式结构图中包含如下几个角色:

  • Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象(如结构图中的successor),作为其对下家的引用。通过该引用,处理者可以连成一条链。

  • ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。

    需要注意:职责链模式并不创建职责链,职责链的创建工作必须由系统的其他部分来完成,一般是在使用该职责链的客户端中创建职责链。职责链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。

武功修炼

使用责任链模式实现,讲一句话进行过滤。实现过程参考java web中的filter!也顺便让大家了解filter的简单的实现!

<p> 已经很晚了 ,888 ,晚安!</p> 处理为 哈哈 已经很晚了 ,888 ,晚安!啊啊

// request 请求类
public class Request { 
   
    String requestStr;

    public String getRequestStr() {
        return requestStr;
    }

    public void setRequestStr(String requestStr) {
        this.requestStr = requestStr;
    }
}
// 响应类
public class Response { 
   
    String responseStr;

    public String getResponseStr() {
        return responseStr;
    }

    public void setResponseStr(String responseStr) {
        this.responseStr = responseStr;
    }
}
//过滤器链
public class FilterChain { 
   
    private List<Filter> filters = new ArrayList<>();

    int index = 0;
    public List<Filter> getFilters() {
        return filters;
    }


    public FilterChain addFilters(Filter filter) {
        filters.add(filter);
        return this;
    }

    public void doFilter(Request request, Response response,FilterChain filterChain) {
        if(index == filters.size()) {
            return;
        }
        Filter f = filters.get(index);
        index++;
        f.doFilter(request,response,this);

    }

}
// 过滤器接口
public interface Filter { 
   
    void doFilter(Request request, Response response, FilterChain filterChain);
}
// 过滤器
public class HTMLFilter implements Filter { 
   

    @Override
    public void doFilter(Request request, Response response,FilterChain filterChain) {
    request.setRequestStr(request.getRequestStr().replace("<p>", "哈哈"));
        request.setRequestStr(request.getRequestStr().replace("</p>", "啊啊"));

        System.out.println("request--> HTMLFilter : " +  request.getRequestStr());


        filterChain.doFilter(request, response, filterChain);
        response.setResponseStr(response.getResponseStr() + "--> HTMLFilter");
    }
}
// 过滤器
public class NumberFilter implements Filter{ 
   

    @Override
    public void doFilter(Request request, Response response, FilterChain filterChain) {
        request.setRequestStr(request.getRequestStr().replace("888", "发发发"));

        System.out.println("request--> NumberFilter : " +  request.getRequestStr());
        filterChain.doFilter(request, response, filterChain);

        response.setResponseStr(response.getResponseStr() + "--> NumberFilter");
    }
}
public class TestFilter { 
   

    public static void main(String[] args) {
        String msg = "哈哈 已经很晚了 ,888 ,晚安!啊啊";
        Request request = new Request();
        request.setRequestStr(msg);
        Response response = new Response();
        response.responseStr = "response";

        FilterChain filterChain = new FilterChain();
        filterChain.addFilters(new HTMLFilter()).addFilters(new NumberFilter());

        filterChain.doFilter(request,response,filterChain);

        System.out.println("过滤后结果:" + request.requestStr);
        System.out.println(response.responseStr);


    }
}
request--> HTMLFilter : 哈哈 已经很晚了 ,888  ,晚安!啊啊
request--> NumberFilter : 哈哈 已经很晚了 ,发发发  ,晚安!啊啊
过滤后结果:哈哈 已经很晚了 ,发发发  ,晚安!啊啊
response--> NumberFilter--> HTMLFilter

总结

职责链模式通过建立一条链来组织请求的处理者,请求将沿着链进行传递,请求发送者无须知道请求在何时、何处以及如何被处理,实现了请求发送者与处理者的解耦。
Web应用开发中创建一个过滤器(Filter)链来对请求数据进行过滤就是很好的职责链模式,上面例子就是简单实现filter中的职责链模式的代码。

优点

  • 请求和处理之间解耦
  • 明确职责和职责的分派
  • 新增职责的时候,无须修改代码

缺点

  • 对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。

  • 如果建链不当,可能会造成循环调用,将导致系统陷入死循环

Next 期待下一篇吧!下一篇讲讲原型模式!

参考

本专栏文章列表

一、设计模式-开篇—为什么我要去旅行? #和设计模式一起旅行#
二、设计模式-必要的基础知识—旅行前的准备 #和设计模式一起旅行#
三、设计模式介绍—她是谁,我们要去哪里? #和设计模式一起旅行#
四、单例模式—不要冒充我,我只有一个! #和设计模式一起旅行#
五、工厂模式—旅行的钱怎么来 #和设计模式一起旅行#
六、策略模式—旅行的交通工具 #和设计模式一起旅行#
七、观察者模式——关注我,分享旅途最浪漫的瞬间! #和设计模式一起旅行#
八、装饰者模式—巴厘岛,奶茶店的困扰! #和设计模式一起旅行#
九、命令模式—使用命令控制奶茶店中酷炫的灯 #和设计模式一起旅行#
十、模板方法模式—制作更多好喝的饮品! #和设计模式一起旅行#
十一、代理模式 —专注,做最好的自己!#和设计模式一起旅行#
十二、适配器模式——解决充电的烦恼 #和设计模式一起旅行#
十三、外观模式—— 简化接口 #和设计模式一起旅行#
十四、迭代器模式—— 一个一个的遍历 #和设计模式一起旅行#
十五、组合模式—— 容器与内容的一致性 #和设计模式一起旅行#
十六、状态模式—用类表示状态 #和设计模式一起旅行#
十七、访问者模式-访问数据结构并处理数据 #和设计模式一起旅行#
十八、职责链模式-推卸责任,不关我的事,我不管!#和设计模式一起旅行#
十九、原型模式—通过复制生产实例 #和设计模式一起旅行#
二十、设计模式总结—后会有期 #和设计模式一起旅行#


如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到,谢谢!

如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!


欢迎访问我的csdn博客,我们一同成长!

不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/121079.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java常用设计模式

    Java常用设计模式一、设计模式概念1、定义​Java包含23种设计模式,是一套对代码设计经验的总结,被人们反复利用,多人熟知的代码设计方式。2、目的​为了提高代码的可读性,可扩展性以及代码的复用性,为了解决在写代码过程中遇到的代码设计问题。3、设计模式的六大原则​3.1开闭原则​对扩展开放,对修改关闭(尽可能对代码少修改)​3.2里氏替换原则​它是面向对象基本原则之一,任何父类(基类)出现的地方,子类都可以出现,也就是子类可以替换父类的任何功能(体现了父类的可扩展性)3.3依赖

    2022年7月8日
    20
  • 设计模式——六大原则[通俗易懂]

    设计模式——六大原则[通俗易懂]设计模式——六大原则

    2022年4月24日
    33
  • 十三、外观模式—— 简化接口 #和设计模式一起旅行#

    我不想成为上帝或英雄,只想成为一棵树,为岁月而生长,不伤害任何人。 ——米沃什故事背景在英国体验了康桥的魅力,我挥一挥衣袖,不带走一片云彩,但是 英国的天空没有留下我的痕迹,但我曾去过。哈哈!从英国到法国,在浪漫的巴黎,我和设计模式MM感受到这个城市别样的风景,很是吸引人,我们决定在这里待一段时间在走。于是去政府部门办理一些手续,本来以为会花费很多时间的,因为之前办…

    2022年2月27日
    40
  • JAVA设计模式之享元模式

    解释一下概念:也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。比如说一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象。如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了。那么如果要是每个字母都共享一个对象,那么就大大节约了资源。  在Flyweight模式中,由于要产生各种各样

    2022年3月11日
    46
  • Java中常用的设计模式

    Java中常用的设计模式文章转载借鉴:http://blog.csdn.net/zhangerqing一、什么是设计模式设计模式(Designpattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块…

    2022年7月8日
    15
  • 深入理解适配器设计模式(java版本)

    深入理解适配器设计模式(java版本)

    2021年8月3日
    55

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号