設計模式(十四) 責任鏈模式

weixin_34320159發表於2017-03-29

前面討論了建立型模式、結構型模式,今天我們來討論一下行為型模式。責任鏈模式,就是我們討論的第一種行為型模式。責任鏈模式具體不容易說出來,但是如果看一看責任鏈模式的實際例子就很容易明白了。最典型的例子就是Java EE Servlet中的過濾器,以鏈式方式對請求進行過濾了。當我們遇到類似需求的時候,也可以使用責任鏈模式來解決。

下面我們來模擬一下Java Servlet中的Filter。首先,需要請求和響應的介面和實現。這兩個介面都很簡單。

//請求
public interface Request {
    String getMessage();
}

class RequestImpl implements Request{
private String msg;

    public RequestImpl(String msg) {
        this.msg = msg;
    }

    @Override
    public String getMessage() {
        return msg;
    }
}

//響應
public interface Response {
    String getMessage();
}

class ResponseImpl implements Response {
    private String msg;

    public ResponseImpl(String msg) {
        this.msg = msg;
    }

    @Override
    public String getMessage() {
        return msg;
    }
}


之後是過濾器的介面和實現。過濾器將會對請求和處理進行處理和過濾。過濾器1和2是正常的過濾器,過濾之後還會繼續呼叫鏈上的其它過濾器。而過濾器3則會直接阻斷鏈。

public interface Filter {
    void doFilter(Request request, Response response, FilterChain chain);
}

class FilterImpl1 implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        System.out.println("In filter1: " + request.getMessage() + ":" + response.getMessage());
        chain.doFilter(request, response);
    }
}

class FilterImpl2 implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        System.out.println("In filter2: " + request.getMessage() + ":" + response.getMessage());
        chain.doFilter(request, response);
    }
}

class FilterImpl3 implements Filter {

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        System.out.println("In filter3: " + request.getMessage() + ":" + response.getMessage());
    }
}

下面來實現責任鏈。責任鏈其實和很簡單,開始過濾之後,責任鏈就會不斷的呼叫鏈上的過濾器,直到某個過濾器判斷不需要繼續過濾(例如過濾器3)或者鏈到頭為止。為了讓這個鏈能夠複用,我還新增了當前呼叫鏈的標記current,標記呼叫到哪裡了,再到頭之後重新將current設定為0。

class FilterChain {
    private List<Filter> filters;
    private int current;

    public FilterChain(List<Filter> filters) {
        this.filters = filters;
        current = 0;
    }

    void doFilter(Request request, Response response) {
        if (current <= filters.size() - 1) {
            Filter currentFilter = filters.get(current);
            current++;
            currentFilter.doFilter(request, response, this);
        } else {
            current = 0;
        }
    }
}

這樣一個責任鏈就完成了。我們來呼叫一下。

    public void run() {
        Filter filter1 = new FilterImpl1();
        Filter filter2 = new FilterImpl2();
        List<Filter> filters = new ArrayList<>();
        filters.add(filter1);
        filters.add(filter2);
        FilterChain chain = new FilterChain(filters);

        Request request = new RequestImpl("request1");
        Response response = new ResponseImpl("response1");

        chain.doFilter(request, response);
        System.out.println();

        filters.add(0,new FilterImpl3());
        chain.doFilter(request, response);
    }

結果應該類似這樣。和我們的預期相同。

責任鏈模式
In filter1: request1:response1
In filter2: request1:response1

In filter3: request1:response1

相關文章