设计模式之责任链模式

概念

职责链模式(Chain of Responsibility)

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

设计模式之责任链模式_第1张图片

 

责任链设计模式中的角色

Handler

抽象处理者(定义一个处理请求的接口,接口可以定义出一个方法,以设定和返回对下家的引用。通常由一个抽象类或接口实现

Concrete Handler

具体处理者(具体请求者在接受到请求后,如果满足条件则自己处理请求,否则将请求传到下家。具体处理者持有下家对象的引用)

Client

客户端(调用者)

 

实战案例

现在我们模拟一个场景:论坛用户发表帖子,但是常常会有用户发一些不良的信息,如广告信息、涉黄信息、涉及政治的敏感词等。这时我们就可以使用责任链模式来过滤用户发表的信息。

先定义所有责任链对象的父类:

package com.wx.wxjob.designPatterns.zerenlian;

/**
 * FileName: PostHandler
 * Author: pengyd
 * Date: 2020/5/19
 * function: 帖子处理器
 */
public abstract class PostHandler {

    protected PostHandler postHandler;

    public void setPostHandler(PostHandler postHandler){
        this.postHandler = postHandler;
    }

    public abstract void hangdlerRequest(Post post);

    protected final void next(Post post){
        if(this.postHandler != null){
            this.postHandler.hangdlerRequest(post);
        }
    }

}

父类 Handler 主要封装了传递请求等方法,其中要注意的有以下几点:

  • successor ( 后继者 ),这个属性很重要,它保存了责任链中下一个处理器。

  • 在 next() 方法中( 方法名自己随便取 ),当请求传递到最后一个责任对象时,已经没有后继者继续处理请求了,因此要对 successor 做判空处理,避免抛出空指针异常。

  • 处理请求的 handlerRequest 的入参和返回类型可以根据实际情况修改,可以在该方法中抛出异常来中断请求。

广告处理器:

package com.wx.wxjob.designPatterns.zerenlian;

/**
 * FileName: ADHandler
 * Author: pengyd
 * Date: 2020/5/19
 * function: 广告处理器
 */
public class ADHandler extends PostHandler{

    @Override
    public void hangdlerRequest(Post post) {
        // 需要处理的消息
        String content = post.getContent();

        content = content.replaceAll("广告", "****");
        post.setContent(content);

        next(post);
    }

}

涉黄处理器:

package com.wx.wxjob.designPatterns.zerenlian;

/**
 * FileName: YellowHandler
 * Author: pengyd
 * Date: 2020/5/19
 * function: 黄色内容过滤器
 */
public class YellowHandler extends PostHandler {
    @Override
    public void hangdlerRequest(Post post) {
        // 需要处理的消息
        String content = post.getContent();

        content = content.replaceAll("黄色", "****");
        post.setContent(content);

        // 传递给下一个处理器
        next(post);
    }
}

调用:

package com.wx.wxjob.designPatterns.zerenlian;

/**
 * FileName: Handler
 * Author: pengyd
 * Date: 2020/5/19
 * function: 调用
 */
public class Handler {

    public static void main(String[] args) {
        PostHandler adHandler = new ADHandler();

        PostHandler yellowHandler = new YellowHandler();

        adHandler.setPostHandler(yellowHandler);

        Post post = new Post();
        post.setContent("我是正常内容 我是广告  我是黄色 ");

        adHandler.hangdlerRequest(post);

        System.out.println(post);

    }
}

总结

责任链模式经常用于过滤器,拦截器,事件( 鼠标键盘事件,冒泡事件等 )等场景。

优点

  • 请求者和接收者解耦;

  • 可以动态地增加或减少责任链上的对象,或者修改顺序。

缺点

  • 调用者不知道请求可能被哪些责任链对象处理,不利于排错;

  • 用户请求可能被责任链中途拦截,最终未必被真正执行,这点既是优点也是缺点,我们可以利用它做权限控制拦截器。

你可能感兴趣的:(Java)