設計模式學習(十六):責任鏈模式

設計模式學習(十六):責任鏈模式

作者:Grey

原文地址:

部落格園:設計模式學習(十六):責任鏈模式

CSDN:設計模式學習(十六):責任鏈模式

責任鏈模式

責任鏈模式是一種行為型模式。

舉例說明:有一段文本需要過濾一系列敏感字,我們可以通過責任鏈模式來設計這個功能,假設文本是

scripts Hell World! 996

我們有多個過濾規則,比如第一個規則是:過濾 scripts 這個關鍵字(實際的規則可能很複雜,目前只是舉這個簡單例子來說明情況)
第二個規則是:過濾 996 這個關鍵字

首先,將這個文本封裝成一個 Msg 類,文本內容存在 content 變數中

public class Msg {
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

然後,可以抽象一個 Filter 介面,各種過濾規則無非就是實現這個介面即可

public interface Filter {
    boolean doFilter(Msg msg);
}

過濾掉 996 這個關鍵字的規則:

public class SensitiveFilter implements Filter {
    @Override
    public boolean doFilter(Msg msg) {
        msg.setContent(msg.getContent().replace("996", ""));
        return true;
    }
}

過濾 scripts 的規則:

public class HTMLFilter implements Filter {
    @Override
    public boolean doFilter(Msg msg) {
        msg.setContent(msg.getContent().replace("scripts", ""));
        return true;
    }
}

主方法調用的時候,就直接 New 相應的 Filter 來處理即可:

Msg msg=new Msg();
msg.setContent("scripts Hell World! 996");
System.out.println("before filter , the content is : "+msg.getContent());
Filter html=new HTMLFilter();
Filter sensitive=new SensitiveFilter();
html.doFilter(msg);
sensitive.doFilter(msg);
System.out.println("after filter , the content is : "+msg.getContent());

不過,更為優雅的一種方式是設計一個 FilterChain ,把所有的 Filter 都加入到這個 FilterChain 裡面,對於 Msg 直接去調用 FilterChain 的過濾方法即可把 FilterChain 中的所有 Filter 都執行,而且還可以很靈活指定 Filter 順序。

import java.util.*;
public class FilterChain implements Filter {
    private List<Filter> filters = new ArrayList<>();

    public FilterChain addFilter(Filter filter) {
        filters.add(filter);
        return this;
    }

    @Override
    public boolean doFilter(Msg msg) {
        for (Filter filter : filters) {
            if (!filter.doFilter(msg)) {
                return false;
            }
        }
        return true;
    }
}

那麼主方法在調用的時候,可以直接通過如下的方式:

public class Main {
    public static void main(String[] args) {
        FilterChain filterChain = new FilterChain();
        filterChain.addFilter(new HTMLFilter()).addFilter(new SensitiveFilter());
        Msg msg = new Msg();
        msg.setContent("scripts Hell World! 996");
        System.out.println("before filter , the content is : " + msg.getContent());
        filterChain.doFilter(msg);
        System.out.println("after filter , the content is : " + msg.getContent());
    }
}

上述示例的 UML 圖如下

image

責任鏈模式應用

  • Java 中的 Servlet filter;

  • Structs,Spring MVC 中的 interceptor;

  • Dubbo 中的 Filter;

  • Netty 中的 ChannelPipeline。

UML 和 程式碼

UML 圖

程式碼

更多

設計模式學習專欄

參考資料