Java設計模式---ChainOfResponsibility責任鏈模式
阿新 • • 發佈:2018-11-28
參考於 :
大話設計模式
馬士兵設計模式視訊
程式碼參考於馬士兵設計模式視訊
寫在開頭:職責鏈模式:使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係
圖來自大話設計模式,下面我的程式碼中,Clien是t依賴於Handler1和Handler2的,不過可以使用配置檔案或者直接給Filter集合初始化來解決這種依賴。
1.場景
在網上評論一句話,往往會經過一系列的處理,有沒有敏感詞之類,現在我們來模擬一下。
把<html>,o.o,和諧
換成 [html],^v^,/*河蟹*/
2.不使用職責鏈模式
package com.dingyu.ChainOfResponsibility; /** * 重點在於模式,故邏輯暫時不考慮 * * @author dingyu * */ public class Client01 { public static void main(String[] args) { String s = "<html>,o.o,和諧"; s = s.replace("<", "[").replace(">", "]").replace("和諧", "/*河蟹*/").replace("o.o", "^v^"); System.out.println(s); } }
缺點:過濾無法複用,無法記錄過濾順序。
3.使用職責鏈模式
package com.dingyu.ChainOfResponsibility; /** * 過濾器,doFilter處理msg字串 * @author dingyu * */ public interface Filter { public String doFilter(String msg); }
package com.dingyu.ChainOfResponsibility; /** * 處理html符號 * 測試用的,邏輯不是很嚴謹 * @author dingyu **/ public class HTMLFilter implements Filter { @Override public String doFilter(String msg) { return msg.replace("<", "[").replace(">", "]"); } }
package com.dingyu.ChainOfResponsibility; /** * 過濾敏感詞彙 * @author dingyu * */ public class SensitiveWordFilter implements Filter { @Override public String doFilter(String msg) { return msg.replace("和諧", "/*河蟹*/"); } }
package com.dingyu.ChainOfResponsibility; /** * 處理符號 * @author dingyu * */ public class SymbolFilter implements Filter { @Override public String doFilter(String msg) { return msg.replace("o.o", "^v^"); } }
package com.dingyu.ChainOfResponsibility; import java.util.ArrayList; import java.util.List; public class Client { private static List<Filter> filters = new ArrayList<Filter>(); private static int index = 0; public static void main(String[] args) { String s = "<html>,o.o,和諧"; filters.add(new HTMLFilter()); filters.add(new SymbolFilter()); filters.add(new SensitiveWordFilter()); for (Filter filter : filters) { s = filter.doFilter(s); } System.out.println(s); } }
雖然使用職責鏈模式,但仍然有缺點,上面的順序是先HTML,然後Symbol,最後SensitiveWord,這三個構成一個過濾鏈條,如果有一天我需要把另一個過濾鏈條插入到這根鏈條中間,實現起來很麻煩。
4.改進職責鏈模式
package com.dingyu.ChainOfResponsibility; import java.util.ArrayList; import java.util.List; /** * * @author dingyu * */ public class FilterChain implements Filter { private List<Filter> filters = new ArrayList<Filter>(); public void add(Filter filter) { filters.add(filter); } public List<Filter> getFilters() { return filters; } @Override public String doFilter(String msg) { for (Filter filter : filters) { msg = filter.doFilter(msg); } return msg; } }
package com.dingyu.ChainOfResponsibility; import java.util.ArrayList; import java.util.List; public class Client { // private static List<Filter> filters = new ArrayList<Filter>(); public static void main(String[] args) { String s = "<html>,o.o,和諧"; // 鏈條1 FilterChain chain1 = new FilterChain(); chain1.add(new HTMLFilter()); // 鏈條2 FilterChain chain2 = new FilterChain(); chain2.add(new HTMLFilter()); chain2.add(new SensitiveWordFilter()); // 鏈條2插到鏈條1後 chain1.add(chain2); chain1.add(new SymbolFilter()); s = chain1.doFilter(s); System.out.println(s); // filters.add(new HTMLFilter()); // filters.add(new SymbolFilter()); // filters.add(new SensitiveWordFilter()); // for (Filter filter : filters) { // s = filter.doFilter(s); // } // System.out.println(s); } }
建議debug , eclipse快捷鍵
5. 職責鏈實現雙向過濾
思路類似於遞迴,建議使用debug一步步除錯。
package com.dingyu.ChainOfResponsibility; /** * 過濾器,doFilter處理msg字串 * * @author dingyu * */ public interface Filter { // public String doFilter(String msg); public void doFilter(Request request, Reponse reponse, FilterChain filterChain); }
package com.dingyu.ChainOfResponsibility; /** * 處理html符號 測試用的,邏輯不是很嚴謹 * * @author dingyu * */ public class HTMLFilter implements Filter { @Override public void doFilter(Request request, Reponse reponse, FilterChain filterChain) { request.getRequestMsg().replace("<", "[").replace(">", "]"); filterChain.doFilter(request, reponse, filterChain); reponse.setReponseMsg(reponse.getReponseMsg() + "-----HTMLFilter"); } // @Override // public String doFilter(String msg) { // return msg.replace("<", "[").replace(">", "]"); // } }
package com.dingyu.ChainOfResponsibility; /** * 過濾敏感詞彙 * * @author dingyu * */ public class SensitiveWordFilter implements Filter { @Override public void doFilter(Request request, Reponse reponse, FilterChain filterChain) { request.getRequestMsg().replace("和諧", "/*河蟹*/"); filterChain.doFilter(request, reponse, filterChain); reponse.setReponseMsg(reponse.getReponseMsg() + "-----SensitiveWordFilter"); } // @Override // public String doFilter(String msg) { // return msg.replace("和諧", "/*河蟹*/"); // } }
package com.dingyu.ChainOfResponsibility; /** * 處理符號 * * @author dingyu * */ public class SymbolFilter implements Filter { @Override public void doFilter(Request request, Reponse reponse, FilterChain filterChain) { request.getRequestMsg().replace("o.o", "^v^"); filterChain.doFilter(request, reponse, filterChain); reponse.setReponseMsg(reponse.getReponseMsg() + "-----SymbolFilter"); } // @Override // public String doFilter(String msg) { // return msg.replace("o.o", "^v^"); // } }
package com.dingyu.ChainOfResponsibility; import java.util.ArrayList; import java.util.List; /** * * @author dingyu * */ public class FilterChain implements Filter { private List<Filter> filters = new ArrayList<Filter>(); private int index=-1; public void add(Filter filter) { filters.add(filter); } public List<Filter> getFilters() { return filters; } // @Override // public String doFilter(String msg) { // for (Filter filter : filters) { // msg = filter.doFilter(msg); // } // return msg; // } @Override public void doFilter(Request request, Reponse reponse, FilterChain filterChain) { if (index == filters.size()-1) return; index++; filters.get(index).doFilter(request, reponse, filterChain); } }
package com.dingyu.ChainOfResponsibility; public class Client03 { public static void main(String[] args) { Request request = new Request(); Reponse reponse = new Reponse(); request.setRequestMsg("<html>,o.o,和諧"); reponse.setReponseMsg("hahahahaha"); FilterChain chain = new FilterChain(); chain.add(new HTMLFilter()); chain.add(new SensitiveWordFilter()); chain.add(new SymbolFilter()); chain.doFilter(request, reponse, chain); System.out.println(request.getRequestMsg()); System.out.println(reponse.getReponseMsg()); } }