設(shè)計模式 - 責(zé)任鏈模式

模式定義

責(zé)任鏈模式(Chain of Responsibility Pattern) 使多個對象都有機會處理請求伴澄,從而避免請求的發(fā)送者和接受者直接的耦合關(guān)系。將這些對象連成一條鏈袋马,沿著這條鏈傳遞該請求,直到有一個對象處理它為止秸应。

責(zé)任鏈模式強調(diào)的是每一個對象及其對下家的引用來組成一條鏈虑凛,利用這種方式將發(fā)送者和接收者解耦

模式結(jié)構(gòu)

主要角色:

  • 抽象處理者(Handler)角色 :定義一個請求的接口。如果需要可以定義個一個方法用來設(shè)定和返回下家對象的引用软啼。
  • 具體處理者(ConcreteHandler)角色 :如果可以處理就處理請求桑谍,如果不能處理,就把請求傳給下家祸挪,讓下家處理霉囚。也就是說它處理自己能處理的請求且可以訪問它的下家。

示例

熟悉JavaWeb開發(fā)的同學(xué)匕积,一定對Servlet規(guī)范 中的Filter 使用非常熟悉,其實它內(nèi)部就是使用責(zé)任鏈模式(FilterChain)實現(xiàn)的榜跌,本文將揭曉Filter的實現(xiàn)原理闪唆。

Filter 接口定義如下:

public interface Filter {

    void doFilter(ServletRequest request, ServletResponse response,
                  FilterChain chain) throws Exception;
}

DemoFilter 代碼如下:

public class DemoFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {
        System.out.println("filter execute...");
        chain.doFilter(request, response);
    }
}

當(dāng)我們在Filter 的 doFilter方法處理完自己的業(yè)務(wù)邏輯后,老司機都會告訴你需要調(diào)用chain.doFilter(request, response);將請求轉(zhuǎn)到下一個Filter中钓葫,那FilterChain.doFilter(request, response)到底是怎么實現(xiàn)的呢悄蕾?

FilterChain

public interface FilterChain {

    void doFilter(ServletRequest request, ServletResponse response) throws Exception;
}

FilterChain 接口定義很簡單,接下來看看它的實現(xiàn)類FilterChainImpl 础浮,代碼如下:

import java.util.List;

/**
 * ${DESCRIPTION}
 *
 * @author Ricky Fung
 * @date 2017-02-18 14:02
 */
public class FilterChainImpl implements FilterChain {
    private int pos;    //當(dāng)前位置
    private List<Filter> filters;
    private HttpHandler next;

    public FilterChainImpl(List<Filter> filters, HttpHandler next) {
        this.filters = filters;
        this.next = next;
        this.pos = 0;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response) throws Exception {
        if (pos >= filters.size()) {
            this.next.handleRequest(request, response);
        } else {
            Filter filter =  filters.get(pos++);
            filter.doFilter(request, response, this);
        }
    }
}

最后帆调,我們可以模擬一下Filter調(diào)用:

import java.util.ArrayList;
import java.util.List;

/**
 * ${DESCRIPTION}
 *
 * @author Ricky Fung
 * @date 2017-02-18 14:14
 */
public class FilterChainDemo {

    public static void main(String[] args) {

        List<Filter> filters = new ArrayList<>();
        for(int i=1; i<=5;i++){
            filters.add(new DemoFilter("Filter_"+i));
        }

        ServletRequest request = new ServletRequest();
        ServletResponse response = new ServletResponse();
        HttpHandler httpHandler = new HttpHandler();    //http請求處理器
        FilterChain filterChain = new FilterChainImpl(filters, httpHandler);
        try {
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

源代碼

https://github.com/TiFG/design-patterns/tree/master/chain

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市豆同,隨后出現(xiàn)的幾起案子番刊,更是在濱河造成了極大的恐慌,老刑警劉巖影锈,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芹务,死亡現(xiàn)場離奇詭異,居然都是意外死亡鸭廷,警方通過查閱死者的電腦和手機枣抱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辆床,“玉大人佳晶,你說我怎么就攤上這事∷显兀” “怎么了轿秧?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵中跌,是天一觀的道長。 經(jīng)常有香客問我淤刃,道長晒他,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任逸贾,我火速辦了婚禮陨仅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘铝侵。我一直安慰自己灼伤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布咪鲜。 她就那樣靜靜地躺著狐赡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疟丙。 梳的紋絲不亂的頭發(fā)上颖侄,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天,我揣著相機與錄音享郊,去河邊找鬼览祖。 笑死,一個胖子當(dāng)著我的面吹牛炊琉,可吹牛的內(nèi)容都是我干的展蒂。 我是一名探鬼主播,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼苔咪,長吁一口氣:“原來是場噩夢啊……” “哼锰悼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起团赏,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤箕般,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后舔清,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體隘世,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年鸠踪,在試婚紗的時候發(fā)現(xiàn)自己被綠了丙者。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡营密,死狀恐怖械媒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤纷捞,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布痢虹,位于F島的核電站,受9級特大地震影響主儡,放射性物質(zhì)發(fā)生泄漏奖唯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一糜值、第九天 我趴在偏房一處隱蔽的房頂上張望丰捷。 院中可真熱鬧歧寺,春花似錦匣砖、人聲如沸湃番。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鳖昌。三九已至胖眷,卻和暖如春恕酸,著一層夾襖步出監(jiān)牢的瞬間榕栏,已是汗流浹背畔勤。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扒磁,地道東北人庆揪。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像渗磅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子检访,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容