您好,登錄后才能下訂單哦!
Iron之職責鏈
需求:
"Iron"的建造一直沒有停止,現在單個部件是有的,但是在部件從工廠里出來的時候,在組裝到一起之前,我們還是非常有必要對部件進行質量檢測,或者是其它個方面的檢測,又或者是設置部件標識信息等等,這些操作可以是有序的(也可以是無序的)。
現在為了實現上面的所講的功能來進行演示,然過程中會發現問題,然后解決問題。這里不多說了直接進入主題。
問題的發現:
首先我定義了一個ComponentModel類,它是要被檢驗的對象
1 /// <summary> 2 /// 部件 3 /// </summary> 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 }
這里先定義了一個請求處理類型的枚舉,下面要用到,這樣比用什么字符串或者是數字來作條件判斷要好很多。
1 /// <summary> 2 /// 請求的處理類型 3 /// </summary> 4 public enum RequestState 5 { 6 /// <summary> 7 /// 檢測 8 /// </summary> 9 Check, 10 /// <summary> 11 /// 設置基礎值 12 /// </summary> 13 SetDefValue 14 15 }
再然后,我們再來定義檢驗ComponentModel類的類型:
1 /// <summary> 2 /// 處理請求類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 //執行處理 19 } 20 break; 21 case RequestState.SetDefValue: 22 _comModel.Name = "默認部件"; 23 //執行處理 24 break; 25 default: 26 27 break; 28 } 30 } 31 } 32 /// <summary> 33 /// 處理請求類2 34 /// </summary> 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 //執行處理 50 } 51 break; 52 case RequestState.SetDefValue: 53 _comModel.Name = "默認部件"; 54 //執行處理 55 break; 56 default: 57 58 break; 59 60 } 61 } 62 }
定義了兩個類型,ConcreteHandlerCaseOne和ConcreteHandlerCaseTwo兩個類型,都是用來處理檢測ComponentModel類型的,現在這些類型都齊全了我們來檢測一下吧。
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);
對的,就是這樣,一次次的檢測下去,如果要檢測20次,并且都是不同的實現,那將非常可怕,代碼冗余,而且請求調用方和處理方的耦合度也很大,那要怎么樣讓代碼更精簡,并且還能有效的解耦,這里就要用到職責鏈模式。
為了避免請求的發送者和接收者之間的耦合關系,使多個接受對象都有機會處理請求。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。
——Gof
這里要強調一下的是本篇的示例中并沒有完全遵從設計模式的定義,還是按照本文開始的功能需求來做的設計,當然了模式的核心不變。
設計模式的思想:
現在先對處理方進行抽象:
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 }
既然有了抽象,那就得有具體的實現:
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 //執行處理 12 13 break; 14 case RequestState.SetDefValue: 15 //執行處理 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 : Handle 28 { 29 public override void HandleRequest(RequestState reqState, ComponentModel comModel) 30 { 31 switch (reqState) 32 { 33 case RequestState.Check: 34 //執行處理 35 break; 36 case RequestState.SetDefValue: 37 //執行處理 38 break; 39 default: 40 this.Successor.HandleRequest(reqState, comModel); 41 break; 42 43 } 44 } 45 }
這里的類型應該只定義一個的是為了讓大家看的更明白。
在這里看抽象處理者Handle類型,它里面有個protected級別的變量Successor,Successor呢就代表著鏈表中每一環的指針,指向誰呢?當然是指向下一個處理者。
現在來看一下調用的代碼:
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);
看上去已經不錯了,耦合度還是很大的,對于handlerA的調用,還是再調用方直接調用的,這時需要一個中間層,
看一下中間層的定義:
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);//指向 處理鏈中的下一個 處理模塊 25 } 26 else 27 { 28 _Handle = handle; 29 } 30 } 31 public void HandleRequest(RequestState reqState) 32 { 33 _Handle.HandleRequest(reqState, _ComModel); 34 } 35 }
通過加了一層,再來看一下調用方的代碼:
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 //執行處理 7 //comModel的一些處理
是不是感覺調用方,跟實際的處理方之間的關系變得很弱了,這樣目的也就達到了。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。