責任鏈模式 純與不純

2021-09-28 20:45:29 字數 4307 閱讀 2095

《設計模式》一書中是這樣定義責任鏈模式的:

在責任鏈模式中,很多物件由每乙個物件對其下家的引用而接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某乙個物件決定處理此請求。客戶並不知道鏈上的哪乙個物件最終處理這個請求,系統可以在不影響客戶端的情況下動態的重新組織鏈和分配責任。處理者有兩個選擇:承擔責任或者把責任推給下家。乙個請求可以最終不被任何接收端物件所接受。

即當乙個請求需要被多個處理者處理時,可以讓每個處理者持有下乙個處理者的引用,從而可以按照一定的順序將這些處理者鏈結起來,形成一條責任鏈,請求在這個責任鏈上傳遞時,每個處理者可以選擇處理這個請求或者交給下乙個處理者,這就是責任鏈模式。責任鏈模式對客戶遮蔽了處理順序和過程,客戶並不知道最終是哪個處理者處理了自己的請求,從而可以在客戶無感知的情況下動態的修改處理順序與過程。其簡單圖示如下:

責任鏈模式可以分為純責任鏈模式與不純的責任鏈模式,其區別在於每個處理者的行為定義。對於純責任鏈模式而言,每個處理者要麼處理請求,要麼把請求傳遞給下乙個處理者,二者只能選其一。對於不純的責任鏈模式而言,每個處理者可以既處理請求,又把請求傳遞給下乙個處理者。下面將分別對純責任鏈模式與不純的責任鏈模式進行說明。

考慮以下場景:某個公司員工請假需要提交乙個申請,這個申請需要一系列負責人審批,小組長可以審批請假小於等於1天的、部門領導可以審批請假小於等於3天的、大於3天的就只能給大boss審批。

這個場景裡,每個領導只能處理自己許可權之內的,超出許可權之外的就只能交給上級審批,很適合使用純責任鏈模式。下面我們來實現它:

定義request和response:

@data

@allargsconstructor

@noargsconstructor

public

class

request

@data

@allargsconstructor

@noargsconstructor

@builder

public

class

response

定義責任鏈的抽象類:

/**

* 純責任鏈模式,乙個處理者要麼處理請求,要麼交給下乙個處理者

* 比如請假審批流,請假小於1天,組領導可批,小於3天,部門領導可批,大於3天的需要大boss批

*/@data

public

abstract

class

filter

定義各個處理者

/**

* 組領導審批鏈

*/@data

public

class

groupleaderfilter

extends

filter

else

}}

/**

* 部門領導審批

*/@data

public

class

deptleaderfilter

extends

filter

else

}}

/**

* 最終的boss審批

*/@data

public

class

finalbossfilter

extends

filter

response.

setresult

(false);

response.

setmsg

("你不是張三,不准你請這麼長假=.=");

system.out.

printf

("最終boss不同意");

return;}

}

開始測試:

public

class

main

}

執行結果:

開始審批張三的請求

group_leader無權審批,交給下一級

dept_leader無權審批,交給下一級

最終boss同意了

在這個例子中,我們定義了乙個抽象類filter,它包含乙個屬性nextfilter,指向下乙個處理者,乙個抽象方法dofilter(request request, response response),用來處理請求。所有處理者都繼承filter,實現自己的dofilter方法,並自由指定下乙個處理者。使用時,我們初始化需要的處理者,並按照需要的順序指定各個處理者的nextfilter,形成一條鏈,把請求傳遞給鏈的起始端,即可開始按照我們預想的順序處理請求。下面是這個例子的uml圖:

在不純的責任鏈模式中,每個處理者可以既處理請求,又把請求交給下一級。考慮以下場景:

假設某公司申請報銷需要組內領導、部門領導、大boss依次審批通過,並給出通過原因,這時每個處理者就需要既處理請求又把請求交給下乙個處理者了。另外再增加一種場景,假設審批通過後,需要大boss、部門領導、組內領導依次簽字,即以與處理請求相反的順序處理響應。這時候該怎麼設計責任鏈呢,下面給出實現:

定義request和response:

@data

@allargsconstructor

@noargsconstructor

public

class

request

@data

@allargsconstructor

@noargsconstructor

public

class

response

定義責任鏈的介面與filterchain:

@data

public

inte***ce

filter

/**

* 不純的責任鏈模式,乙個處理者既處理請求,又把請求傳遞給下乙個處理者

*/@data

@allargsconstructor

@noargsconstructor

public

class

filterchain

implements

filter

public

void

dofilter

(request request, response response, filterchain filterchain)

}

定義各個處理者

/**

* 組領導審批鏈

*/public

class

groupleaderfilter

implements

filter

}

/**

* 部門領導審批

*/public

class

deptleaderfilter

implements

filter

}

/**

* 最終的boss審批

*/public

class

finalbossfilter

implements

filter

}

開始測試:

public

class

main

執行結果:

request(name=張三, gold=100, opinions=

[group_leader 同意, dept_leader 同意, final_boss 同意]

)response(sign=

[final_boss 簽名, dept_leader 簽名, group_leader 簽名]

)

在這個例子中,在filterchain裡定義了乙個index,記錄每次執行的filter,每個處理者都先處理請求,然後把請求傳遞給下乙個處理者,最後處理響應,從而能以與處理請求相反的順序處理響應。在實際應用中,使用純責任鏈模式的場景很少見,往往都是混雜的不純責任鏈模式,尤其這種請求與響應處理順序相反的場景更為常見。

責任鏈模式

責任鏈模式 chain of responsibility 的目標是使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞請求,直到有乙個物件處理它為止。舉個例子。你到銀行去辦理業務,只是簡單的存個錢,也許atm就解決你的問題。如果你是為了交費...

責任鏈模式

有3個request與3個handler,每個request由相應的handler來處理,當乙個handler與request不匹配時則傳遞給下乙個handler來處理 inte ce request class request1 implements request class request2 ...

責任鏈模式

了解了一下責任鏈模式,簡單的說下自己的理解吧 責任鏈就是說待處理的資料在request的時候,先經過filter1的處理,再經過filter2的處理,然後response時,先經過filter2的處理,在經過filter1的處理。實現思路是filterchain包括filter1和filter2,同...