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

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

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

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

故事背景

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

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

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

说白就是:当一个人被要求做什么事情的时候,如果他自己可以做就自己做,如果不能做就将“要求”转为另一个人处理,下一个如果可以自己处理,就直接处理,如果不能处理依旧转为另一个人,这就是 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博客,我们一同成长!

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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

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