Iron之職責(zé)鏈
需求:
"Iron"的建造一直沒(méi)有停止,現(xiàn)在單個(gè)部件是有的,但是在部件從工廠里出來(lái)的時(shí)候,在組裝到一起之前,我們還是非常有必要對(duì)部件進(jìn)行質(zhì)量檢測(cè),或者是其它個(gè)方面的檢測(cè),又或者是設(shè)置部件標(biāo)識(shí)信息等等,這些操作可以是有序的(也可以是無(wú)序的)。
現(xiàn)在為了實(shí)現(xiàn)上面的所講的功能來(lái)進(jìn)行演示,然過(guò)程中會(huì)發(fā)現(xiàn)問(wèn)題,然后解決問(wèn)題。這里不多說(shuō)了直接進(jìn)入主題。
問(wèn)題的發(fā)現(xiàn):
首先我定義了一個(gè)ComponentModel類,它是要被檢驗(yàn)的對(duì)象
1 /// <summary> 2 /// 部件 3 /// </summary> 4 public class ComponentModel 5 { 6 public string Name { get; set; } 7 public int Value 8 { 9 get10 {11 return 5;12 }13 }14 }這里先定義了一個(gè)請(qǐng)求處理類型的枚舉,下面要用到,這樣比用什么字符串或者是數(shù)字來(lái)作條件判斷要好很多。
1 /// <summary> 2 /// 請(qǐng)求的處理類型 3 /// </summary> 4 public enum RequestState 5 { 6 /// <summary> 7 /// 檢測(cè) 8 /// </summary> 9 Check,10 /// <summary>11 /// 設(shè)置基礎(chǔ)值12 /// </summary>13 SetDefValue14 15 }再然后,我們?cè)賮?lái)定義檢驗(yàn)ComponentModel類的類型:
1 /// <summary> 2 /// 處理請(qǐng)求類1 3 /// </summary> 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 /// <summary>33 /// 處理請(qǐng)求類234 /// </summary>35 public class ConcreteHandlerCaseTwo36 {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è)類型,都是用來(lái)處理檢測(cè)ComponentModel類型的,現(xiàn)在這些類型都齊全了我們來(lái)檢測(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)一下的是本篇的示例中并沒(méi)有完全遵從設(shè)計(jì)模式的定義,還是按照本文開始的功能需求來(lái)做的設(shè)計(jì),當(dāng)然了模式的核心不變。
設(shè)計(jì)模式的思想:
現(xiàn)在先對(duì)處理方進(jìn)行抽象:
1 /// <summary> 2 /// 抽象處理者 3 /// </summary> 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 /// <summary> 2 /// 具體處理者 3 /// </summary> 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 /// <summary>25 /// 具體處理者26 /// </summary>27 public class ConcreteHandlerB : Handle28 {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)的指針,指向誰(shuí)呢?當(dāng)然是指向下一個(gè)處理者。現(xiàn)在來(lái)看一下調(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 /// <summary> 2 /// ChainOfResponsibility模式幫助類 3 /// </summary> 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 else27 {28 _Handle = handle;29 }30 }31 public void HandleRequest(RequestState reqState)32 {33 _Handle.HandleRequest(reqState, _ComModel);34 }35 }通過(guò)加了一層,再來(lái)看一下調(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的一些處理
是不是感覺(jué)調(diào)用方,跟實(shí)際的處理方之間的關(guān)系變得很弱了,這樣目的也就達(dá)到了。
作者:金源
出處:http://m.survivalescaperooms.com/jin-yuan/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注