java switch优化_用反射或委托优化switch太长的方法

在代码进行优化的时候,发现了switch case太长,有的竟然长达30个远远超过一屏这样在代码的可读性来说很差。特别在我们看代码的时候要拉下拉框我个人觉得这是不合理的。但是我不建议有switch就进行反射或委托来解决。看实际的情况比喻10个以为还是可以接受的。因为switch看起来更加的直接而且效率相对来说是最好的。那下面就用代码来一点点进行解释

1:传统的用法

1.1:现在我们有一个需求通过传递参数来获取相关的信息。首先我们先看方法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classSwitchMethod {2 public string GetSerialNumber(stringserialNumber)3 {4 returnserialNumber;5 }6

7 public string GetName(stringname)8 {9 returnname;10 }11

12 public string GetAge(stringage)13 {14 returnage;15 }16

17 public string GetBirthday(stringbirthday)18 {19 returnbirthday;20 }21

22 }

调用的方法

1.2:客户端的调用

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 string action =Console.ReadLine() ;2 var switchMethod=newSwitchMethod();3 switch(action)4 {5 case "serialNumber":6 Console.WriteLine(switchMethod.GetSerialNumber("1234"));7 break;8 case "name":9 Console.WriteLine(switchMethod.GetName("zhangsan"));10 break;11 case "age":12 Console.WriteLine(switchMethod.GetAge("21"));13 break;14 case "birthday":15 Console.WriteLine(switchMethod.GetBirthday("19960201"));16 break;17 }

客户端调用

1.3:效果

85c9eaf6732bcbcc23218e1f765b8cef.png

以上是我们最常规的用法看起来最直观但是你想过没有如果有30个方法呢你还这样进行switch case吗 50,100个呢所以下面我用委托来代码

2:委托替代switch

上面我又发现一个问题action凌乱,如果太多了就搞不清什么是什么了所以我们加入枚举

2.1:建立枚举

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public enumActionEnum2 {3 ///

4 ///编号5 ///

6 SerialNumber = 0,7 ///

8 ///姓名9 ///

10 Name = 1,11 ///

12 ///年龄13 ///

14 Age = 2,15 ///

16 ///生日17 ///

18 Birthday = 3

19 }

action枚举

2.2:我采取字典把需要switch的都存起来

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 private static voidLoadDictionary()2 {3 if (AllDictionary.Count<=0)4 {5 var switchMethod = newSwitchMethod();6 AllDictionary.Add(ActionEnum.SerialNumber, switchMethod.GetSerialNumber);7 AllDictionary.Add(ActionEnum.Age, switchMethod.GetAge);8 AllDictionary.Add(ActionEnum.Birthday, switchMethod.GetBirthday);9 AllDictionary.Add(ActionEnum.Name, switchMethod.GetName);10 }11 }

字典保存

2.3:建立委托(这是比较简单的其实在方法中还可以提取相似的操作放在委托执行)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public static string Exec(string str,Funcmethod) {2 returnmethod(str);3 }

委托

2.4:客户端调用

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 Console.WriteLine(Exec("21", AllDictionary[ActionEnum.Age]));

客户端调用

2.5:效果

c9fe5337e637c8759c8e7fec0a5c33e6.png

3:反射替代switch

3.1建立一个自定义Attribute类(目的是为了附带方法中的信息)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classMethodAttribute : Attribute2 {3 publicActionEnum MethodName;4

5 publicMethodAttribute(ActionEnum methodName)6 {7 this.MethodName =methodName;8 }9 }

特性类

3.2:定义一个基类

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classBaseMethod2 {3 public Hashtable GetMethodAttribute(T t)4 {5 var hashtable = newHashtable();6 Type type =t.GetType();7 foreach (MethodInfo method intype.GetMethods())8 {9 var methodArray = (MethodAttribute[]) method.GetCustomAttributes(typeof (MethodAttribute), false);10 foreach (MethodAttribute actionMethodAttribute inmethodArray)11 {12 ActionEnum actionName =actionMethodAttribute.MethodName;13 hashtable.Add(actionName, method);14 }15 }16 returnhashtable;17 }18

19

20 public string DoAction(ActionEnum actionName,stringstr) {21 Hashtable ht = GetMethodAttribute(this);22 string message =ht.Contains(actionName)23 ? ((MethodInfo) ht[actionName]).Invoke(this, new object[] {str}).ToString()24 : string.Format("{0} 超过范围", actionName);25 returnmessage;26 }27 }

基类

3.3:修改SwitchMethod类并给方法加上特性

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classSwitchMethod : BaseMethod2 {3 [Method(ActionEnum.SerialNumber)]4 public string GetSerialNumber(stringserialNumber)5 {6 returnserialNumber;7 }8

9 [Method(ActionEnum.Name)]10 public string GetName(stringname)11 {12 returnname;13 }14

15 [Method(ActionEnum.Age)]16 public string GetAge(stringage)17 {18 returnage;19 }20

21 [Method(ActionEnum.Birthday)]22 public string GetBirthday(stringbirthday)23 {24 returnbirthday;25 }26 }

SwitchMethod 类

3.4:客户端调用

string result = new SwitchMethod().DoAction(ActionEnum.SerialNumber,"1332");

3.5:注释

3.5.1:type.GetMethods():获取这个类中所有的方法包括基类的方法

3.5.2:method.GetCustomAttributes(typeof (MethodAttribute), false):获取这个方法所有关于MethodAttribute类型的自定义特性

3.5.3:MethodInfo:表示对类中方法的访问

3.6:运行效果

da3ef696e9c11c45554f625954dee1bb.png

三种方式总结

1:传统的用法

优点:简单易读,效率高

缺点:当量很多的时候会造成方法很长,不易维护,可能修改其中某一个case会引起未知的错误

2:委托

优点:使用委托将公有的进行提取,减少代码量

缺点:加入字典后每次添加都需要在字典后手动添加一个子项。总是觉得别扭,效率稍微差点

3:反射

优点:代码量减少,不在考虑内部如何实现,而且符合开闭原则,只需要添加新的方法,其他地方不作修改。维护性强

缺点:很明显这个效率最差(此处并未加入缓存)

第三种方式参考:http://www.cnblogs.com/vipsoft/archive/2012/10/19/2731126.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值