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         /// 19         /// 对不同国家的人说hello,每个国家的表达方式不一样20         /// 21         /// 22         /// 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         /// 19         /// 对中国人说你好20         /// 21         /// 22         public void SayHelloChinese(string name)23         {24             Console.WriteLine($"{this.StuName }开始打招呼");25             Console.WriteLine($"{name},你好!");26         }27 28         /// 29         /// 对美国人说你好30         /// 31         /// 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 方式213         /// 14         /// 对中国人说你好15         /// 16         /// 17         public void SayHelloChinese(string name)18         {19             Console.WriteLine($"{name},你好!");20         }21         /// 22         /// 对美国人说你好23         /// 24         /// 25         public void SayHelloAmerican(string name)26         {27             Console.WriteLine($"{name},hello");28         }29         #endregion30     }
 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 }开始打招呼");)方便,实现了代码重用,对不同的逻辑分离维护简单,实现逻辑解耦,鱼和熊掌兼得,方便维护升级。相同的东西用一个方法实现,不同的各自去写,然后通过委托组合,加方法满足不同的场景,如果业务逻辑或者说方法特别复杂,就推荐用这种方式去处理。这就是委托对程序设计带来的价值。