责任链设计模式(过滤器、拦截器)
責任鏈設計模式(Chain of Responsibility)的應用有:Java Web中的過濾器鏈、Struts2中的攔截器棧。
先看一個問題:
給定一個字符串“被就業了:),敏感信息,<script>”,對其中的HTML標記和敏感詞進行過濾或替換。
本文主要以該問題設計方法的演變來講解責任鏈設計模式。
第一種設計:沒有任何設計模式
設計了一個MsgProcessor類,完成字符串處理的主要工作。MainClass類是本設計中的測試類。
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class MainClass { ????public static void main(String[] args) { ????????//需要被過濾的語句 ????????String msg = "被就業了:),敏感信息,<script>"; ? ????????//實例化處理類 ????????MsgProcessor mp = new MsgProcessor(msg); ????????String r = mp.process(); ? ????????System.out.println(r); ????} ? } ? public class MsgProcessor { ????private String msg; ????public MsgProcessor(String msg){ ????????this.msg = msg; ????} ? ????public String process(){ ????????String r = msg; ????????//過濾msg中的HTML標記 ????????r = r.replace("<", "<").replace(">", ">"); ????????//過濾敏感詞 ????????r = r.replace("敏感", "").replace("被就業", "就業"); ? ????????return r; ????} } |
第二種設計:增加一個Filter接口
在第一種設計中,對字符串的所有處理都放在MsgProcessor類中,擴展性極差。如果要過濾字符串中的笑臉(將”:)”替換成”^_^”),則需要改動MSgProcessor中的process方法。
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | public interface Filter { ????String doFilter(String str); } ? public class HtmlFilter implements Filter { ????public String doFilter(String msg) { ????????String r = msg; ????????//過濾msg中的HTML標記 ????????r = r.replace("<", "<").replace(">", ">"); ? ????????return r; ????} } ? public class SensitiveFilter implements Filter { ????public String doFilter(String msg) { ????????String r = msg; ????????//過濾敏感詞 ????????r = r.replace("敏感", "").replace("被就業", "就業"); ? ????????return r; ????} } ? public class MsgProcessor { ????private String msg; ????private Filter[] filters = {new HtmlFilter(),new SensitiveFilter()}; ? ????public MsgProcessor(String msg){ ????????this.msg = msg; ????} ? ????public String process(){ ????????String r = msg; ????????for(Filter f : filters){ ????????????r = f.doFilter(r); ????????} ????????return r; ????} } |
此時,如果需要過濾字符串中的笑臉,只需要創建一個類FaceFilter實現Filter接口,并在MsgProcessor類中的filters字段中登記即可。
第三種設計:責任鏈模式(FilterChain)
定義:將一個事件處理流程分派到一組執行對象上去,這一組執行對象形成一個鏈式結構,事件處理請求在這一組執行對象上進行傳遞。責任鏈模式的主要參與角色:
① 事件處理請求對象(Request)
② 執行對象(Handler)
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public class FilterChain implements Filter { ? ????public List<Filter> filters= new ArrayList<Filter>(); ? ????public FilterChain addFilter(Filter f){ ????????filters.add(f); ????????return this; ????} ? ????public String doFilter(String msg) {//執行filters中的doFilter方法即可 ????????String r = msg; ????????for(Filter f : filters){ ????????????r = f.doFilter(r); ????????} ????????return r; ????} } ? public class MsgProcessor { ????private String msg; ????private FilterChain chain = new FilterChain(); ? ????public MsgProcessor(String msg,Filter Chain){ ????????this.msg = msg; ????????this.chain = chain; ????} ? ????public String process(){ ????????return chain.doFilter(msg); ????} } ? public class MainClass { ????public static void main(String[] args) { ????????//需要被過濾的語句 ????????String msg = "被就業了:),敏感信息,<script>"; ? ????????//搞一個過過濾鏈 ????????FilterChain chain = new FilterChain(); ????????chain.addFilter(new HtmlFilter()).addFilter(new SensitiveFilter()); ????????//實例化處理類 ????????MsgProcessor mp = new MsgProcessor(msg,chain); ????????String r = mp.process(); ? ????????System.out.println(r); ????} } |
責任鏈模式加強版
上面的實現的過濾鏈可以用下圖a)表示出來,整個過程只對msg過濾了一次。而JavaWeb中的過濾器鏈和Struts2中的攔截器棧執行的過程可以形象的表示為圖b,☆很重要)。
下面用程序模擬JavaWeb中的過濾器,實現類似于對Request和Response的過濾。主要涉及的類如下所示:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | public interface Filter { ????void doFilter(Request req,Response resp,FilterChain chain); } ? public class HtmlFilter implements Filter { ????public void doFilter(Request req, Response resp, FilterChain chain) { ????????//過濾req.reqStr中的HTML標記 ????????req.reqStr = req.reqStr.replace("<", "<").replace(">", ">"); ????????req.reqStr += "---HtmlFilter()---"; ????????chain.doFilter(req, resp); ????????resp.respStr += "---HtmlFilter()---"; ????} } ? public class SensitiveFilter implements Filter { ????public void doFilter(Request req, Response resp, FilterChain chain) { ????????// 過濾req.reqStr中的敏感詞 ????????req.reqStr = req.reqStr.replace("敏感", "").replace("被就業", "就業"); ????????req.reqStr += "===SensitiveFilter"; ????????chain.doFilter(req, resp); ????????resp.respStr += "===SensitiveFilter"; ????} } ? public class FilterChain{ ????private List<Filter> filters = new ArrayList<Filter>(); ????//調用鏈上的過濾器時,記錄過濾器的位置用 ????private int index = 0; ? ????public FilterChain addFilter(Filter f){ ????????filters.add(f); ????????return this; ????} ? ????public void doFilter(Request req, Response resp) { ????????if(index == filters.size()) return; ????????//得到當前過濾器 ????????Filter f = filters.get(index); ????????index++; ? ????????f.doFilter(req, resp, this); ????} } ? public class Request { ????//在Request中只保持了一個reqStr字段記錄對Request的操作 ????//為了方便模擬,沒有將reqStr設置為private ????String reqStr; } ? public class Response { ????//在Response中只保持了一個respStr字段記錄對Response的操作 ????//為了方便模擬,沒有將respStr設置為private ????String respStr; } package org.flyne.fiter; ? public class MainClass { ????public static void main(String[] args) { ????????// 需要被過濾的語句 ????????String msg = "被就業了:),敏感信息,<script>"; ? ????????//創建Request、Response對象 ????????Request req = new Request(); ????????Response resp = new Response(); ????????req.reqStr = msg; ????????resp.respStr = "response"; ? ????????//搞一個過濾鏈,鏈上有兩個過濾器 ????????FilterChain chain = new FilterChain(); ????????chain.addFilter(new HtmlFilter()) ????????????.addFilter(new SensitiveFilter()); ? ????????//開始過濾 ????????chain.doFilter(req, resp); ? ????????System.out.println(req.reqStr); ????????System.out.println(resp.respStr); ????} } |
轉載于:https://www.cnblogs.com/Free-Thinker/p/4139306.html
總結
以上是生活随笔為你收集整理的责任链设计模式(过滤器、拦截器)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 评价一个人,就是要看他把时间都花在哪了
- 下一篇: 【java/C# 服务器】IOS 配置推