-
定義:
責(zé)任鏈模式在面向?qū)ο蟪淌皆O(shè)計(jì)里是一種軟件設(shè)計(jì)模式璃吧,它包含了一些命令對象和一系列的處理對象蚓炬。每一個(gè)處理對象決定它能處理哪些命令對象泼菌,它也知道如何將它不能處理的命令對象傳遞給該鏈中的下一個(gè)處理對象闲询。該模式還描述了往該處理鏈的末尾添加新的處理對象的方法。 ---維基百科
開閉原則:對于擴(kuò)展開放,即有新需求過來時(shí)可以擴(kuò)展模塊;對于修改關(guān)閉,即擴(kuò)展模塊行為時(shí)不必修改源代碼.
我理解來說就是在一次事件請求中有一個(gè)請求發(fā)送方和多個(gè)請求接收方,發(fā)送方不需要知道自己的請求到底會被誰接收,他只需要把請求發(fā)給第一個(gè)接收方,接下來就由第一個(gè)接收方抉擇自己能處理的話就自己處理,自己不能處理就返回下一個(gè)接收方接收的結(jié)果,從而降低了發(fā)送方和接收方的耦合程度,但是也有一些要求:比如每個(gè)接收方肯定都要有處理請求的方法,除了最后一個(gè)接收方,其他接收方必須存儲下個(gè)接收方的指針.
先思考一下下面這個(gè)場景,無論在公司或是學(xué)校,肯定都會有審批什么東西或者事情的經(jīng)歷,拿審批請假來說,首先第一步是員工寫好郵件,說明自己的請假原因及時(shí)間,寫好之后發(fā)給小組主管,主管收到郵件之后有兩種處理方式:
1.請假時(shí)間比較短,自己這邊就可以批了,此時(shí)返回審批結(jié)果就結(jié)束了;
2.請假時(shí)間有點(diǎn)長,主管無法決定能不能批
所以這時(shí)小組主管會發(fā)送審批郵件給所在部門的領(lǐng)導(dǎo),領(lǐng)導(dǎo)也有同樣的兩種處理方式,會按照時(shí)間長短來決定自己能不能批,一直到公司的上層領(lǐng)導(dǎo)來做最后的決策.-
這一套流程其實(shí)就是責(zé)任鏈模式的體現(xiàn),展現(xiàn)到代碼層面上
首先有一個(gè)請求發(fā)送方:
class Client{ String name; int days; public Client(String name,int days){ this.days = days; this.name = name; } public boolean sendRequest(Handler handler){ System.out.println(name+"請求請假"+days+"天"); return handler.handlerRequest(days); } }
其次有一個(gè)抽象的請求接收方來設(shè)置幾個(gè)默認(rèn)方法:
abstract class Handler{
Handler nextHandler = null;
int days = 0;
public Handler(int days){
this.days = days;
}
public boolean handlerRequest(int days){
if (days <= this.days){
System.out.println(name()+"同意請假");
return true;
}else {
if (nextHandler == null){
System.out.println("請假時(shí)間過長,所有人無法審批");
return false;
}else {
System.out.println(name()+"無法處理,傳遞給上一級");
return nextHandler.handlerRequest(days);
}
}
}
public void setNextHandler(Handler handler){
nextHandler = handler;
}
public String name(){
return this.getClass().getSimpleName();
}
}
然后有幾個(gè)具體的請求接收方繼承抽象類:
class Handler1 extends Handler{
public Handler1(int days) {
super(days);
}
}
class Handler2 extends Handler{
public Handler2(int days) {
super(days);
}
}
class Handler3 extends Handler{
public Handler3(int days) {
super(days);
}
}
接下來我們測試一下,設(shè)置handler1是第一個(gè)接收方:
public static void main(String[] args) {
Handler1 handler1 = new Handler1(10);
Handler2 handler2 = new Handler2(30);
handler1.setNextHandler(handler2);
Handler3 handler3 = new Handler3(100);
handler2.setNextHandler(handler3);
Client client1 = new Client("請求者1",10);
client1.sendRequest(handler1);
Client client2 = new Client("請求者2",20);
client2.sendRequest(handler1);
Client client3 = new Client("請求者3",50);
client3.sendRequest(handler1);
Client client4 = new Client("請求者4",120);
client4.sendRequest(handler1);
}
結(jié)果:
-
接下來談一下這個(gè)模式的優(yōu)點(diǎn)及缺點(diǎn)
優(yōu)點(diǎn):降低了兩方的耦合程度,使得如果有新的接收方加入或者之前的接收方退出對于發(fā)送方來說并不受到干擾,代碼滿足開閉原則
缺點(diǎn)也比較明顯,因?yàn)榘l(fā)送方在發(fā)出請求之后,請求需要傳遞到能處理它的接收方才會返回結(jié)果,所以導(dǎo)致時(shí)間較長,性能較低