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 }開始打招呼");)方便,實現了代碼重用,對不同的邏輯分離維護簡單,實現邏輯解耦,魚和熊掌兼得,方便維護升級。相同的東西用一個方法實現,不同的各自去寫,然后通過委托組合,加方法滿足不同的場景,如果業務邏輯或者說方法特別復雜,就推薦用這種方式去處理。這就是委托對程序設計帶來的價值。
