本文是對(duì)設(shè)計(jì)模式之禪一書中責(zé)任鏈模式一章的總結(jié)與整理茄蚯。
1.定義
啥叫責(zé)任鏈呢团赏?意思就是鏈上的每一個(gè)節(jié)點(diǎn)都有責(zé)任去判斷是不是自己的責(zé)任虑鼎,如果是自己的責(zé)任就處理這件事情瘤泪,不是就傳遞到下一個(gè)節(jié)點(diǎn)谋右,夠簡(jiǎn)單吧硬猫。書中給出的定義如下:使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送和接收者之間的耦合關(guān)系改执。將這些對(duì)象連成一條鏈啸蜜,并沿著這條鏈傳遞該請(qǐng)求,直到有對(duì)象處理它為止辈挂。衬横,其通用類圖如下:
2. 解析
大過(guò)年的,每個(gè)人都想回家终蒂,假設(shè)你的老家是廣州蜂林,現(xiàn)在要坐001次車從北京回家遥诉,這輛車要經(jīng)過(guò)的站假設(shè)有以下的一些:北京-》上海-》廣州。先定義父類:
public abstract class Station {
// 下一個(gè)要處理的是誰(shuí)
private Station nextStation;
//具體要做什么(責(zé)任鏈上的某一節(jié)點(diǎn)具體要做的事情)
public abstract void execute();
// 獲取當(dāng)前責(zé)任鏈上該節(jié)點(diǎn)的目的地
public abstract String getMyDestination();
public void setNextStation(Station _station){
this.nextStation=_station;
}
//處理用戶請(qǐng)求
//userDestination為用戶的目的的
public void handleStation(String userDestination){
//判斷用戶的目的地是否當(dāng)前目的地一致,一致則處理,不一定則獲取下一個(gè)目的地
if(userDestination.equals(this.getMyDestination())){
this.execute();
}
else if(null!=this.nextStation){ //不一致則由下一個(gè)目的地(節(jié)點(diǎn))處理
this.nextStation.handleStation(userDestination);
}
else{ //如果下一站為空,則結(jié)束
System.out.println("您應(yīng)該到家了吧,責(zé)任鏈到頭了");
}
}
}
這個(gè)類比較簡(jiǎn)單噪叙,有幾點(diǎn)需要注意下:
需要定義“下一個(gè)”變量(體現(xiàn)出鏈的味道)
-
需要定義處理請(qǐng)求的方法:
2.1 定義依次處理請(qǐng)求的方法矮锈,這里指的是handleStation (它負(fù)責(zé)判斷是否為當(dāng)前節(jié)點(diǎn),是則調(diào)用相應(yīng)的方法睁蕾,不是則進(jìn)入下一個(gè)節(jié)點(diǎn))
2.2 定義方法苞笨,指定下一個(gè)節(jié)點(diǎn)是誰(shuí)
2.3 定義抽象方法,由子類實(shí)現(xiàn)具體的處理工作
再看子類子眶,北京站:
public class Beijing extends Station {
@Override
public void execute() {
System.out.println("您已到達(dá)北京站");
}
@Override
public String getMyDestination() {
return "北京";
}
}
上海站:
public class ShangHai extends Station {
@Override
public void execute() {
System.out.println("您已到達(dá)上海站");
}
@Override
public String getMyDestination() {
return "上海";
}
}
廣州站:
public class GuangZhou extends Station {
@Override
public void execute() {
System.out.println("您已到達(dá)廣州站");
}
@Override
public String getMyDestination() {
return "廣州";
}
}
再看現(xiàn)實(shí)中的你:
public class Client {
public static void main(String[] strings){
//定義責(zé)任鏈上的節(jié)點(diǎn)
Beijing beijing=new Beijing();
ShangHai shanghai=new ShangHai();
GuangZhou guangZhou=new GuangZhou();
//設(shè)定節(jié)點(diǎn)順序
beijing.setNextStation(shanghai);
shanghai.setNextStation(guangZhou);
//責(zé)任鏈從頭處理
beijing.handleStation("廣州");
}
}
運(yùn)行后結(jié)果正常輸出瀑凝,符合我們的預(yù)期。
3.總結(jié)
我認(rèn)為責(zé)任鏈還是很簡(jiǎn)單的一個(gè)模式臭杰,如果要使用它粤咪,我們只需要做幾個(gè)事情就可以:
1. 定義鏈上的節(jié)點(diǎn)
2. 定義節(jié)點(diǎn)之間的順序
4.擴(kuò)展
在以上的示例中,父類里判斷是不是當(dāng)前節(jié)點(diǎn)硅卢,不是當(dāng)間節(jié)點(diǎn)就進(jìn)入下一個(gè)節(jié)點(diǎn)射窒,在此處我們可以做一些擴(kuò)展,比如:如果當(dāng)前節(jié)點(diǎn)不是目的節(jié)點(diǎn)将塑,則做一些什么樣的操作脉顿,比如送個(gè)飯之類的。
還可以做的擴(kuò)展比如:不判斷比較當(dāng)前節(jié)點(diǎn)是不是目的節(jié)點(diǎn)点寥,只要不是目的節(jié)點(diǎn)就做什么事情艾疟,比如到每個(gè)站,我去一次WC敢辩,是吧蔽莱。
切記:鏈、戚长、盗冷、、同廉、仪糖、鏈、迫肖、锅劝、、蟆湖、故爵、鏈、隅津、诬垂、劲室、、剥纷、痹籍,務(wù)請(qǐng)把鏈的概念搞明白,抓到這個(gè)本質(zhì)晦鞋。