1. 程式人生 > >Java設計模式---ChainOfResponsibility責任鏈模式

Java設計模式---ChainOfResponsibility責任鏈模式

參考於 :

  大話設計模式

  馬士兵設計模式視訊

  程式碼參考於馬士兵設計模式視訊

  寫在開頭:職責鏈模式:使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係

  圖來自大話設計模式,下面我的程式碼中,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());
    }
}