Iron之職責(zé)鏈
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),番禺企業(yè)網(wǎng)站建設(shè),番禺品牌網(wǎng)站建設(shè),網(wǎng)站定制,番禺網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,番禺網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
需求:
"Iron"的建造一直沒有停止,現(xiàn)在單個(gè)部件是有的,但是在部件從工廠里出來的時(shí)候,在組裝到一起之前,我們還是非常有必要對(duì)部件進(jìn)行質(zhì)量檢測(cè),或者是其它個(gè)方面的檢測(cè),又或者是設(shè)置部件標(biāo)識(shí)信息等等,這些操作可以是有序的(也可以是無序的)。
現(xiàn)在為了實(shí)現(xiàn)上面的所講的功能來進(jìn)行演示,然過程中會(huì)發(fā)現(xiàn)問題,然后解決問題。這里不多說了直接進(jìn)入主題。
問題的發(fā)現(xiàn):
首先我定義了一個(gè)ComponentModel類,它是要被檢驗(yàn)的對(duì)象
1 ///2 /// 部件 3 /// 4 public class ComponentModel 5 { 6 public string Name { get; set; } 7 public int Value 8 { 9 get 10 { 11 return 5; 12 } 13 } 14 }
這里先定義了一個(gè)請(qǐng)求處理類型的枚舉,下面要用到,這樣比用什么字符串或者是數(shù)字來作條件判斷要好很多。
1 ///2 /// 請(qǐng)求的處理類型 3 /// 4 public enum RequestState 5 { 6 ///7 /// 檢測(cè) 8 /// 9 Check, 10 ///11 /// 設(shè)置基礎(chǔ)值 12 /// 13 SetDefValue 14 15 }
再然后,我們?cè)賮矶x檢驗(yàn)ComponentModel類的類型:
1 ///2 /// 處理請(qǐng)求類1 3 /// 4 public class ConcreteHandlerCaseOne 5 { 6 private ComponentModel _comModel; 7 public ConcreteHandlerCaseOne(ComponentModel comModel) 8 { 9 _comModel = comModel; 10 } 11 public void HandleRequest(RequestState reqState) 12 { 13 switch (reqState) 14 { 15 case RequestState.Check: 16 if (_comModel.Value > 5) 17 { 18 //執(zhí)行處理 19 } 20 break; 21 case RequestState.SetDefValue: 22 _comModel.Name = "默認(rèn)部件"; 23 //執(zhí)行處理 24 break; 25 default: 26 27 break; 28 } 30 } 31 } 32 ///33 /// 處理請(qǐng)求類2 34 /// 35 public class ConcreteHandlerCaseTwo 36 { 37 private ComponentModel _comModel; 38 public ConcreteHandlerCaseTwo(ComponentModel comModel) 39 { 40 _comModel = comModel; 41 } 42 public void HandleRequest(RequestState reqState) 43 { 44 switch (reqState) 45 { 46 case RequestState.Check: 47 if (_comModel.Value > 5) 48 { 49 //執(zhí)行處理 50 } 51 break; 52 case RequestState.SetDefValue: 53 _comModel.Name = "默認(rèn)部件"; 54 //執(zhí)行處理 55 break; 56 default: 57 58 break; 59 60 } 61 } 62 }
定義了兩個(gè)類型,ConcreteHandlerCaseOne和ConcreteHandlerCaseTwo兩個(gè)類型,都是用來處理檢測(cè)ComponentModel類型的,現(xiàn)在這些類型都齊全了我們來檢測(cè)一下吧。
1 ComponentModel comModel = new ComponentModel(); 2 ConcreteHandlerCaseOne caseone = new ConcreteHandlerCaseOn(comModel); 3 caseone.HandleRequest(RequestState.Check); 4 ConcreteHandlerCaseTwo casetwo = new ConcreteHandlerCaseTw(comModel); 5 casetwo.HandleRequest(RequestState.Check);
對(duì)的,就是這樣,一次次的檢測(cè)下去,如果要檢測(cè)20次,并且都是不同的實(shí)現(xiàn),那將非??膳?,代碼冗余,而且請(qǐng)求調(diào)用方和處理方的耦合度也很大,那要怎么樣讓代碼更精簡(jiǎn),并且還能有效的解耦,這里就要用到職責(zé)鏈模式。
為了避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系,使多個(gè)接受對(duì)象都有機(jī)會(huì)處理請(qǐng)求。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理它為止。
——Gof
這里要強(qiáng)調(diào)一下的是本篇的示例中并沒有完全遵從設(shè)計(jì)模式的定義,還是按照本文開始的功能需求來做的設(shè)計(jì),當(dāng)然了模式的核心不變。
設(shè)計(jì)模式的思想:
現(xiàn)在先對(duì)處理方進(jìn)行抽象:
1 ///2 /// 抽象處理者 3 /// 4 public abstract class Handle 5 { 6 protected Handle Successor; 7 public void SetSuccessor(Handle successor) 8 { 9 this.Successor = successor; 10 } 11 public abstract void HandleRequest(RequestStatereqState,ComponentModel comModel); 12 13 }
既然有了抽象,那就得有具體的實(shí)現(xiàn):
1 ///2 /// 具體處理者 3 /// 4 public class ConcreteHandlerA : Handle 5 { 6 public override void HandleRequest(RequestState reqState, ComponentModel comModel) 7 { 8 switch (reqState) 9 { 10 case RequestState.Check: 11 //執(zhí)行處理 12 13 break; 14 case RequestState.SetDefValue: 15 //執(zhí)行處理 16 break; 17 default: 18 this.Successor.HandleRequest(reqState, comModel); 19 break; 20 21 } 22 } 23 } 24 ///25 /// 具體處理者 26 /// 27 public class ConcreteHandlerB : Handle 28 { 29 public override void HandleRequest(RequestState reqState, ComponentModel comModel) 30 { 31 switch (reqState) 32 { 33 case RequestState.Check: 34 //執(zhí)行處理 35 break; 36 case RequestState.SetDefValue: 37 //執(zhí)行處理 38 break; 39 default: 40 this.Successor.HandleRequest(reqState, comModel); 41 break; 42 43 } 44 } 45 }
這里的類型應(yīng)該只定義一個(gè)的是為了讓大家看的更明白。
在這里看抽象處理者Handle類型,它里面有個(gè)protected級(jí)別的變量Successor,Successor呢就代表著鏈表中每一環(huán)的指針,指向誰呢?當(dāng)然是指向下一個(gè)處理者。
現(xiàn)在來看一下調(diào)用的代碼:
1 ComponentModel comModel = new ComponentModel(); 2 Handle handlerA = new ConcreteHandlerA(); 3 Handle handlerB = new ConcreteHandlerB(); 4 handlerA.SetSuccessor(handlerB); 5 handlerA.HandleRequest(RequestState.Check, comModel);
看上去已經(jīng)不錯(cuò)了,耦合度還是很大的,對(duì)于handlerA的調(diào)用,還是再調(diào)用方直接調(diào)用的,這時(shí)需要一個(gè)中間層,
看一下中間層的定義:
1 ///2 /// ChainOfResponsibility模式幫助類 3 /// 4 public class CORUnit 5 { 6 private Handle _Handle; 7 8 private ComponentModel _ComModel; 9 10 public CORUnit(ComponentModel commodel) 11 : this(null, commodel) 12 { 13 _ComModel = commodel; 14 } 15 public CORUnit(Handle Handle, ComponentModel commodel) 16 { 17 _Handle = Handle; 18 _ComModel = commodel; 19 } 20 public void RegisterHandle(Handle handle) 21 { 22 if (_Handle != null) 23 { 24 _Handle.SetSuccessor(handle);//指向 處理鏈中的下一個(gè) 處理模塊 25 } 26 else 27 { 28 _Handle = handle; 29 } 30 } 31 public void HandleRequest(RequestState reqState) 32 { 33 _Handle.HandleRequest(reqState, _ComModel); 34 } 35 }
通過加了一層,再來看一下調(diào)用方的代碼:
1 ComponentModel comModel = new ComponentModel(); 2 CORUnit corunit = new CORUnit(comModel); 3 corunit.RegisterHandle(new ConcreteHandlerA()); 4 corunit.RegisterHandle(new ConcreteHandlerB()); 5 corunit.HandleRequest(RequestState.Check); 6 //執(zhí)行處理 7 //comModel的一些處理
是不是感覺調(diào)用方,跟實(shí)際的處理方之間的關(guān)系變得很弱了,這樣目的也就達(dá)到了。