溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C#設(shè)計模式之職責(zé)鏈

發(fā)布時間:2020-07-16 15:00:00 來源:網(wǎng)絡(luò) 閱讀:792 作者:jinyuan0829 欄目:編程語言

Iron之職責(zé)鏈

需求:

"Iron"的建造一直沒有停止,現(xiàn)在單個部件是有的,但是在部件從工廠里出來的時候,在組裝到一起之前,我們還是非常有必要對部件進(jìn)行質(zhì)量檢測,或者是其它個方面的檢測,又或者是設(shè)置部件標(biāo)識信息等等,這些操作可以是有序的(也可以是無序的)。

現(xiàn)在為了實現(xiàn)上面的所講的功能來進(jìn)行演示,然過程中會發(fā)現(xiàn)問題,然后解決問題。這里不多說了直接進(jìn)入主題。

問題的發(fā)現(xiàn):

首先我定義了一個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     }

這里先定義了一個請求處理類型的枚舉,下面要用到,這樣比用什么字符串或者是數(shù)字來作條件判斷要好很多。

1     /// <summary>
2     /// 請求的處理類型
3    /// </summary>
4     public enum RequestState
5     {
6         /// <summary>
7         /// 檢測
8         /// </summary>
9         Check,
10         /// <summary>
11         /// 設(shè)置基礎(chǔ)值
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                     //執(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     /// 處理請求類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                         //執(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     }

定義了兩個類型,ConcreteHandlerCaseOne和ConcreteHandlerCaseTwo兩個類型,都是用來處理檢測ComponentModel類型的,現(xiàn)在這些類型都齊全了我們來檢測一下吧。

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次,并且都是不同的實現(xiàn),那將非常可怕,代碼冗余,而且請求調(diào)用方和處理方的耦合度也很大,那要怎么樣讓代碼更精簡,并且還能有效的解耦,這里就要用到職責(zé)鏈模式。

 

為了避免請求的發(fā)送者和接收者之間的耦合關(guān)系,使多個接受對象都有機(jī)會處理請求。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。
                                                                          ——Gof

這里要強(qiáng)調(diào)一下的是本篇的示例中并沒有完全遵從設(shè)計模式的定義,還是按照本文開始的功能需求來做的設(shè)計,當(dāng)然了模式的核心不變。

設(shè)計模式的思想:

現(xiàn)在先對處理方進(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     }

既然有了抽象,那就得有具體的實現(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 : 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)該只定義一個的是為了讓大家看的更明白。

在這里看抽象處理者Handle類型,它里面有個protected級別的變量Successor,Successor呢就代表著鏈表中每一環(huán)的指針,指向誰呢?當(dāng)然是指向下一個處理者。
現(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)不錯了,耦合度還是很大的,對于handlerA的調(diào)用,還是再調(diào)用方直接調(diào)用的,這時需要一個中間層,

看一下中間層的定義:

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     }

通過加了一層,再來看一下調(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)用方,跟實際的處理方之間的關(guān)系變得很弱了,這樣目的也就達(dá)到了。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI