三、行为型模式【职责链模式】

职责链模式

将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。

一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。

职责链模式还有一种变体,那就是请求会被所有的处理器都处理一遍,不存在中途终止的情况。

实现方式

职责链模式的实现包含处理器接口(IHandler)或抽象类(Handler),以及处理器链(HandlerChain)

//Handler 是所有处理器类的抽象父类,handle() 是抽象方法
public abstract class Handler {
    
    
    protected Handler successor = null;

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

    public final void handle() {
    
    
        boolean handled = doHandle();
        if (successor != null && !handled) {
    
    
            successor.handle();
        }
    }

    protected abstract boolean doHandle();
}

//具体的处理器类 HandlerA
public class HandlerA extends Handler {
    
    
    @Override
    protected boolean doHandle() {
    
    
        boolean handled = false;
//...
        return handled;
    }
}

//具体的处理器类 HandlerB
public class HandlerB extends Handler {
    
    
    @Override
    protected boolean doHandle() {
    
    
        boolean handled = false;
//...
        return handled;
    }
}

//HandlerChain 是处理器链,从数据结构的角度来看,它就是一个记录了链头、链尾的链表。其中,记录链尾是为了方便添加处理器
public class HandlerChain {
    
    
    private List<IHandler> handlers = new ArrayList<>();

    public void addHandler(IHandler handler) {
    
    
        this.handlers.add(handler);
    }

    public void handle() {
    
    
        for (IHandler handler : handlers) {
    
    
            boolean handled = handler.handle();
            if (handled) {
    
    
                break;
            }
        }
    }
}


// 使用举例
public class Application {
    
    
    public static void main(String[] args) {
    
    
        HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA());
        chain.addHandler(new HandlerB());
        chain.handle();
    }
}

应用场景

  • 敏感词过滤框架: 包含敏感词的内容,直接禁止发布
public interface SensitiveWordFilter {
    
    
    boolean doFilter(Content content);
}

public class SexyWordFilter implements SensitiveWordFilter {
    
    
    @Override
    public boolean doFilter(Content content) {
    
    
        boolean legal = true;
//...
        return legal;
    }
}

// PoliticalWordFilter、AdsWordFilter类代码结构与SexyWordFilter类似
public class SensitiveWordFilterChain {
    
    
    private List<SensitiveWordFilter> filters = new ArrayList<>();

    public void addFilter(SensitiveWordFilter filter) {
    
    
        this.filters.add(filter);
    }

    // return true if content doesn't contain sensitive words.
    public boolean filter(Content content) {
    
    
        for (SensitiveWordFilter filter : filters) {
    
    
            if (!filter.doFilter(content)) {
    
    
                return false;
            }
        }
        return true;
    }
}

public class ApplicationDemo {
    
    
    public static void main(String[] args) {
    
    
        SensitiveWordFilterChain filterChain = new SensitiveWordFilterChain();
        filterChain.addFilter(new AdsWordFilter());
        filterChain.addFilter(new SexyWordFilter());
        filterChain.addFilter(new PoliticalWordFilter());
        boolean legal = filterChain.filter(new Content());
        if (!legal) {
    
    
// 不发表
        } else {
    
    
// 发表
        }
    }
}
  • Servlet Filter
    javax.servlet.Filter 就是处理器接口
    FilterChain 就是处理器链
    doFilter() 是一个递归调用,主要是为了在一个 doFilter() 方法中,支持双向拦截,既能拦截客户端发送来的请求,也能拦截发送给客户端的响应
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-77hXbsuN-1663489842682)(…/src/main/resources/pic/Filter.png)]

  • Spring Interceptor
    是一个递归调用,主要是为了在一个 doFilter() 方法中,支持双向拦截,既能拦截客户端发送来的请求,也能拦截发送给客户端的响应
    在这里插入图片描述

  • Spring Interceptor
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46488959/article/details/126919356
今日推荐