责任链模式

定义:为请求创建一个接收此次请求对象的链,对该请求对象执行一系列的操作。
类型:行为型;
使用场景:一个请求的处理需要多个对象当中的一个或几个协作处理;

优点:
  1. 请求的发送者和接收者(请求的处理)解耦;
  2. 责任链可以动态组合;
缺点:
  1. 责任链太长或者处理时间过长,影响性能;
  2. 责任链有可能过多;
示例:

  本文通过博客(Blog)发布流程中的title、author、type、content验证来模拟责任链,其中任何一个验证失败都会导致博客发布失败,UML类图如下所示:
责任链模式UML类图

类对应代码如下:
// Filter接口
public interface Filter {
    boolean doFilter(Blog blog);
}

// Title校验
public class TitleFilter implements Filter {
    public boolean doFilter(Blog blog) {
        String title = blog.getTitle();
        if (StringUtils.isEmpty(title)){
            System.out.println("作者验证不通过,不允许发布!");
            return false;
        }else {
            System.out.println("作者验证通过!");
            return true;
        }
    }
}

// Author校验
public class AuthorFilter implements Filter{
    public boolean doFilter(Blog blog) {
        String author = blog.getAuthor();
        if (StringUtils.isNotEmpty(author)){
            System.out.println("标题验证通过!");
            return true;
        }else {
            System.out.println("标题验证不通过,不允许发布!");
            return false;
        }
    }
}

// Type校验
public class TypeFilter implements Filter{
    public boolean doFilter(Blog blog) {
        String type = blog.getType();
        if (StringUtils.isEmpty(type)){
            System.out.println("文章类别验证不通过,不允许发布");
            return false;
        }else {
            System.out.println("文章类别验证通过");
            return true;
        }
    }
}

// Content校验
public class ContentFilter implements Filter {
    public boolean doFilter(Blog blog) {
        String content = blog.getContent();
        if (StringUtils.isEmpty(content)){
            System.out.println("文章内容验证不通过,不允许发布!");
            return false;
        }else {
            System.out.println("文章内容验证通过!");
            return true;
        }
    }
}

// FilterChain
public class FilterChain implements Filter {
    private List<Filter> filters = new LinkedList<Filter>();

    public void add(Filter filter){
        filters.add(filter);
    }

    public void delete(Filter filter){
        filters.remove(filter);
    }

    public boolean doFilter(Blog blog) {
        for (Filter filter : filters) {
            if (!filter.doFilter(blog)){
                return false;
            }
        }
        return true;
    }
}

// 测试类
public class Test {
    public static void main(String[] args) {
        Blog blog = new Blog("责任链模式","teihin","","责任链模式是设计模式之一");
        FilterChain fc1 = new FilterChain();
        fc1.add(new TitleFilter());
        fc1.add(new AuthorFilter());

        FilterChain fc2 = new FilterChain();
        fc2.add(new TypeFilter());
        fc2.add(new ContentFilter());

        fc1.add(fc2);
        fc1.doFilter(blog);
    }
}

// 输出:
作者验证通过!
标题验证通过!
文章类别验证不通过,不允许发布!
JDK源码:

  javax.servlet包下Filter和FilterChain接口以及相应的实现类,以CharacterEncodingFilter为例:

public interface Filter {
    void init(FilterConfig var1) throws ServletException;

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    void destroy();
}

public interface FilterChain {
    void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}

public class CharacterEncodingFilter extends OncePerRequestFilter {
    private String encoding;
    private boolean forceEncoding;

    public CharacterEncodingFilter() {
        this.forceEncoding = false;
    }

    public CharacterEncodingFilter(String encoding) {
        this(encoding, false);
    }

    public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
        this.forceEncoding = false;
        Assert.hasLength(encoding, "Encoding must not be empty");
        this.encoding = encoding;
        this.forceEncoding = forceEncoding;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public void setForceEncoding(boolean forceEncoding) {
        this.forceEncoding = forceEncoding;
    }

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
            request.setCharacterEncoding(this.encoding);
            if (this.forceEncoding) {
                response.setCharacterEncoding(this.encoding);
            }
        }

        filterChain.doFilter(request, response);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值