C#委托的價值,結合業務場景分析


1、業務背景

技術為業務而生,技術為解決業務問題而存在,技術脫離業務就變得沒有價值,我們在探討某一個技術帶來的價值時,都需要有一定的業務背景作為前提。我們先來看如下需求背景:

定義一個學生類,屬性包含學生姓名、學號、年齡、創建時間,行為包含學生可以使用正確的方式對不同國家的人打招呼,如對中國人打招呼為:張三,你好!對美國人打招呼為Jack  hello!

2、解決方式1,使用傳統的分支邏輯判斷

示例代碼及調用方式:

 1     public class Student
 2     { 
10         public string StuName { get; set; }
11 
12         public string StuNum { get; set; }
13 
14         public int Age { get; set; }
15 
16         public DateTime CreateTime { get; set; }
17 
18         /// <summary>
19         /// 對不同國家的人說hello,每個國家的表達方式不一樣
20         /// </summary>
21         /// <param name="name"></param>
22         /// <param name="peopleType"></param>
23         public void SayHello(string name, PeopleType peopleType) {
25             Console.WriteLine($"{this.StuName }開始打招呼");
27             switch (peopleType)
28             {
29                 case PeopleType.Chinese:
30                     Console.WriteLine($"{name},你好!");
31                     break;
32                 case PeopleType.American:
33                     Console.WriteLine($"{name},hello");
34                     break;
35                 default:
36                     throw new Exception("enum  PeopleType exception");
37             }
38         }
39     }
       public enum PeopleType
   { Chinese = 1, American = 2  }
 1     {
 2         Student student = new Student() {
 3             StuName = "wjl",
 4             StuNum = "14216600010",
 5             Age = 18,
 6             CreateTime = DateTime.Now
 7         };
 8         student.SayHello("張三", PeopleType.Chinese);
 9         student.SayHello("jack", PeopleType.American);
10     }

該種方式的優缺點:

假如業務有變動,需要增加一個對馬來西亞國家的人打招呼的功能,就得在枚舉中增加馬來西亞的枚舉類型,在SayHello方法中增加一個對馬來西亞類型的分支邏輯判斷,這種方式導致的問題就是任意分支變化都得修改方法,代碼很不穩定,如果業務邏輯更復雜變得難以維護。但這種方式增加公共邏輯方便,如:Console.WriteLine($"{this.StuName }開始打招呼");

3、解決方式2,針對對不同類型國家的人,定義不同的方法

示例代碼及調用方式:

 1     public class Student
 2     {
 4         public enum PeopleType
 5         {
 6             Chinese = 1,
 7             American = 2
 8         }
 9 
10         public string StuName { get; set; }
11 
12         public string StuNum { get; set; }
13 
14         public int Age { get; set; }
15 
16         public DateTime CreateTime { get; set; }
17 
18         /// <summary>
19         /// 對中國人說你好
20         /// </summary>
21         /// <param name="name"></param>
22         public void SayHelloChinese(string name)
23         {
24             Console.WriteLine($"{this.StuName }開始打招呼");
25             Console.WriteLine($"{name},你好!");
26         }
27 
28         /// <summary>
29         /// 對美國人說你好
30         /// </summary>
31         /// <param name="name"></param>
32         public void SayHelloAmerican(string name)
33         {
34             Console.WriteLine($"{this.StuName }開始打招呼");
35             Console.WriteLine($"{name},hello");
36         }
37     }
 1     {
 2          Console.WriteLine("調用說你好的功能,方式2");
 3          Student student = new Student()
 4          {
 5              StuName = "wjl",
 6              StuNum = "14216600010",
 7              Age = 18,
 8              CreateTime = DateTime.Now
 9          };
10          student.SayHelloChinese("張三");
11          student.SayHelloAmerican("jack");
12     }

該種方式的優缺點:

假如業務變動,需要增加一個對馬來西亞國家的人打招呼的功能,就要增加一個方法,不影響別的方法。但這種方式增加公共邏輯會導致多個方法有很多重復代碼,如上述代碼中的Console.WriteLine($"{this.StuName }開始打招呼");,這種方式不利於代碼復用,如果要修改這些公共邏輯或者增加更多的公共邏輯,需要修改的地方較多,不利於維護。

4、解決方式3,利用委托,將不同的業務邏輯分離出去,相同的業務邏輯提取出來

示例代碼及調用方式:

 1     public class Student
 2     {
 3         public delegate void SayHelloDelegate(string name);
 4         public string StuName { get; set; }
 5         public string StuNum { get; set; }
 6         public int Age { get; set; }
 7         public DateTime CreateTime { get; set; }
 8         public void SayHelloPerfect(string name, SayHelloDelegate sayHello ) {
 9             Console.WriteLine($"{this.StuName }開始打招呼");
10             sayHello.Invoke(name);
11         }
12         #region 方式2
13         /// <summary>
14         /// 對中國人說你好
15         /// </summary>
16         /// <param name="name"></param>
17         public void SayHelloChinese(string name)
18         {
19             Console.WriteLine($"{name},你好!");
20         }
21         /// <summary>
22         /// 對美國人說你好
23         /// </summary>
24         /// <param name="name"></param>
25         public void SayHelloAmerican(string name)
26         {
27             Console.WriteLine($"{name},hello");
28         }
29         #endregion
30     }
 1     {
 2         Student student = new Student()
 3         {
 4            StuName = "wjl",
 5            StuNum = "14216600010",
 6            Age = 18,
 7            CreateTime = DateTime.Now
 8         };
9 SayHelloDelegate method1 = student.SayHelloChinese; 10 student.SayHelloPerfect("張三", method1); 13 SayHelloDelegate method2 = student.SayHelloAmerican; 14 student.SayHelloPerfect("Jack", method2); 15 }

該種方式的優缺點:

這種處理方式將邏輯作為參數傳遞,將不同的業務邏輯分離出去,交給調用者傳遞,保證了現有方法的穩定,增加公共邏輯(Console.WriteLine($"{this.StuName }開始打招呼");)方便,實現了代碼重用,對不同的邏輯分離維護簡單,實現邏輯解耦,魚和熊掌兼得,方便維護升級。相同的東西用一個方法實現,不同的各自去寫,然后通過委托組合,加方法滿足不同的場景,如果業務邏輯或者說方法特別復雜,就推薦用這種方式去處理。這就是委托對程序設計帶來的價值。

推薦閱讀:C#委托進階,事件和委托,一次就看明白


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM