设计模式(九)责任链(Chain of Responsibility)

说明

定义:

职责链模式(Chain of Responsibility),使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

UML图:

包含角色:

1)Handler:抽象处理着;

2)ConcreteHandler:具体处理者。

代码实现:

典型的"抽象处理者"代码
复制代码
// 典型的"抽象处理者"代码
abstract class Handler {
    // 为了使得handler之间连接起来像一个链,这里用来存储下处理者
    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(String request);
}
复制代码

典型的"具体处理者"代码

复制代码
// 典型的"具体处理者"代码
class ConcreteHandler extends  Handler{
    @Override
    public void handleRequest(String request) {
        // 场景1)自己满足处理条件,就不往下流转;自己不满足处理条件,就往下流转
        if(满足条件){
            //1)处理
        }else{
            //2) 交给其他处理者处理
            this.successor.handleRequest(request);
        }

        // 场景2)当然也可能是自己处理完,之后又交给下一个处理者处理
        //1)当前处理
        //2)交个下一个处理者处理
        this.successor.handleRequest(request);

    }
}
复制代码

注意:

handleReuqest方法内部具体场景可以根据自己实际需求而定:

场景1)自己满足处理条件,就不往下流转;自己不满足处理条件,就往下流转
场景2)当然也可能是自己处理完,之后又交给下一个处理者处理

典型客户端调用代码:

复制代码
Handler handler1=new ConcreteHandler1();
Handler handler2=new ConcreteHandler2();
Handler handler3=new ConcreteHandler3();

// 创建职责链
handler1.setSuccessor(handler2);
handler2.setSuccessor(handler3);

// 发送请求,请求对象通常为根据需求而定。
handler1.handleRequest("xxx");
复制代码

Java Web Servlet Filter职责链应用

filter/servlet/filterChain定义:

定义“处理者抽象管理者”

// 首先定义一个 过滤器链接口,包含一个doFilter方法
interface IFilterChain { 
    void doFilter(); 
}

定义“抽象处理类者”

// Filter接口类,包含一个doFilter方法,方法包含一个FilterChain参数
interface IFilter {
    void doFilter(IFilterChain chain); 
}

定义“处理者具体管理者”扩展业务接口:

// Servlet接口类,包含一个servcie方法
interface IServlet {
    void service(); 
}

业务接口具体实现:

class MyServlet implements IServlet {
    @Override
    public void service() {
        System.out.println("MyServlet#service()");
    }
}

定义2个“处理者”

复制代码
class MyFilter1 implements IFilter {
    @Override
    public void doFilter(IFilterChain chain) {
        System.out.println("MyFilter1#doFilter() before");
        chain.doFilter();
        System.out.println("MyFilter1#doFilter() after");
    }
}

class MyFilter2 implements IFilter {
    @Override
    public void doFilter(IFilterChain chain) {
        System.out.println("MyFilter2#doFilter() before");
        chain.doFilter();
        System.out.println("MyFilter2#doFilter() after");
    }
}
复制代码

一个处理者处理完交给下一个处理者处理。

处理者管理类实现:

复制代码
class MyFilterChain implements IFilterChain {
    private int pos = 0; // 标记filter执行索引位置
    private int n = 0; // 已经拥有的filter个数
    private IServlet servlet; // 存储 当前servlet
    private List<IFilter> filters = new ArrayList<>(); // 存储过滤器

    public void addFilter(IFilter filter) {
        this.filters.add(filter);
        n++;
    }

    public void setServlet(IServlet servlet) {
        this.servlet = servlet;
    }

    // 责任链的核心方法,执行filter到最底一层后调用 servlet#service 方法。
    @Override
    public void doFilter() {
        // Call the next filter if there is one
        if (pos < n) {
            IFilter filter = filters.get(pos++);
            filter.doFilter(this);

            return;
        }

        servlet.service();
    }
}
复制代码

客户端调用:

复制代码
import java.util.ArrayList;
import java.util.List;

public class FilterTest {
    public static void main(String[] args) {
        MyFilterChain filterChain = new MyFilterChain();
        filterChain.addFilter(new MyFilter1());
        filterChain.addFilter(new MyFilter2());
        filterChain.setServlet(new MyServlet());

        filterChain.doFilter();
    }
}
复制代码

执行结果:

MyFilter1#doFilter() before
MyFilter2#doFilter() before
MyServlet#service()
MyFilter2#doFilter() after
MyFilter1#doFilter() after

 

 



感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮。本文欢迎各位转载,但是转载文章之后必须在文章页面中给出作者和原文连接
posted @   cctext  阅读(447)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示