编写高质量代码改善C#程序的157个建议——建议149:使用表驱动法避免过长的if和switch分支
建议149:使用表驱动法避免过长的if和switch分支
随着代码变得复杂,我们很容易被过长的if和switch分支困扰。
一个类枚举类型Week如下:
enum Week
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
如果要把Week的元素值用中文输出,简单而丑陋的方法也许是封装一个GetChineseWeek方法:
static string GetChineseWeek(Week week)
{
switch (week)
{
case Week.Monday:
return "星期一";
case Week.Tuesday:
return "星期二";
case Week.Wednesday:
return "星期三";
case Week.Thursday:
return "星期四";
case Week.Friday:
return "星期五";
case Week.Saturday:
return "星期六";
case Week.Sunday:
return "星期日";
default:
throw new ArgumentOutOfRangeException("week","星期值超出范围");
}
}
之所以说这种方法太丑陋,是因为:
1)分支太长了,而且出现了重复代码。
2)不利于扩展。如果出现星期八、星期九怎么办?当然,星期制已经是固定的了,应该不会出现扩展情况。但是,换种情景来考虑,假设我们正在渲染动画怎么办?谁知道下一秒美工会提交我多少个动画呢?
一种解决方案是使用多态,它很好的符合了“开闭”原则。如果增加条件分支,不必修改源代码,直接增加子类就可以了。利用多态避免分支,这里暂且不表,本建议要采用的是“表驱动法”。
可以把表驱动简单理解为查字典。代码如下表示:
static string GetChineseWeek(Week week)
{
string[] chineseWeek = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
return chineseWeek[(int) week];
} static void Main(string[] args)
{
Console.WriteLine(GetChineseWeek(Week.Friday));
}
这是一种按照索引值驱动的表驱动法。枚举元素代表的整型值,很容易和字符串数组索引结合起来,用两行语句就解决了GetChineseWeek方法。但是,这种方法有局限性,如果需要换成:星期一Mike打扫卫生、星期二Rose清理衣柜、星期三Mike和Rose没事可以吵吵架、星期四Rose要去Shopping,也就是说需求由静态属性变成了动态行为,那么事情就变得复杂了。
遇上这种情况,我们可能会想到使用多态,在这里依然使用表驱动法加上一点反射来实现这类动态的行为,代码如下:
class Program
{
static string ActionInTable(Week week)
{
string[] methods = { "Cleaning", "CleanCloset", "Quarrel", "Shopping", "Temp", "Temp", "Temp" };
return methods[(int)week];
} static void Main(string[] args)
{
SampleClass sample=new SampleClass();
var addMethod = typeof (SampleClass).GetMethod(ActionInTable(Week.Monday));
addMethod.Invoke(sample, null);
}
} class SampleClass
{
public void Cleaning()
{
Console.WriteLine("打扫");
}
public void CleanCloset()
{
Console.WriteLine("整理衣橱");
}
public void Quarrel()
{
Console.WriteLine("吵架");
}
public void Shopping()
{
Console.WriteLine("购物");
}
public void Temp()
{
Console.WriteLine("临时安排");
}
}
表驱动法是一种设计思路,也可以称为模式。在实际编码中,不应局限于用索引去驱动行为,而应当根据实际情况灵活运用。
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
编写高质量代码改善C#程序的157个建议——建议149:使用表驱动法避免过长的if和switch分支的更多相关文章
- 编写高质量代码改善C#程序的157个建议[1-3]
		
原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理 ...
 - 读书--编写高质量代码  改善C#程序的157个建议
		
最近读了陆敏技写的一本书<<编写高质量代码 改善C#程序的157个建议>>书写的很好.我还看了他的博客http://www.cnblogs.com/luminji . 前面部 ...
 - 编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试
		
建议157:从写第一个界面开始,就进行自动化测试 如果说单元测试是白盒测试,那么自动化测试就是黑盒测试.黑盒测试要求捕捉界面上的控件句柄,并对其进行编码,以达到模拟人工操作的目的.具体的自动化测试请学 ...
 - 编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本
		
建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能: ...
 - 编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码
		
建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的 ...
 - 编写高质量代码改善C#程序的157个建议——建议154:不要过度设计,在敏捷中体会重构的乐趣
		
建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个 ...
 - 编写高质量代码改善C#程序的157个建议——建议153:若抛出异常,则必须要注释
		
建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会 ...
 - 编写高质量代码改善C#程序的157个建议——建议152:最少,甚至是不要注释
		
建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. ...
 - 编写高质量代码改善C#程序的157个建议——建议151:使用事件访问器替换公开的事件成员变量
		
建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass ...
 - 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法
		
建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...
 
随机推荐
- mac环境下IDEA无法下载plugin或者自动下载Library
			
卧槽,原谅我这么晚还在写blog,明天早上还要上班. 问题,idea 新建springmvc无法自动下载lib,报这个: you have JVM property "https.proxy ...
 - 用户从手机的浏览器访问www.baidu.com,看到的可能跟桌面PC电脑,是不太一样的网页效果,会更适合移动设备使用。请简要分析一下,实现这种网页区分显示的原因及技术原理。
			
手机的网速问题.屏幕大小.内存.CPU等.通过不同设备的特征,实现不同的网页展现或输出效果.根据useragent.屏幕大小信息.IP.网速.css media Query等原理,实现前端或后端的特征 ...
 - 2.docker学习之linux安装
			
Docker CE is supported on CentOS 7.3 64-bit. 说明docker只能安装在centOS7以上 [root@hadoop-bigdata01 ~]# yum i ...
 - Eclipse免reload设置
			
在使用eclipse开发web项目的时候,有的时候需要通过运行看结果,但是如果项目很大,你改一句代码,也许就要重启一次,或者eclipse自动帮你reload,这样严重的影响开发的效率,这里只要修改一 ...
 - Oracle 创建表空间借鉴 保留,占版权留言告知
			
/*分为四步 */ /*第1步:创建临时表空间 */ create temporarytablespace user_temp tempfile 'D:\oracle\oradata\Oracle9i ...
 - Installation failed with message Failed to finalize session : INSTALL_FAILED_INVALID_APK: Split lib_slice_8_apk was defined multiple times. It is possible that this issue is resolved by uninstalling a
			
取消:Instant Run就行
 - from 动态显示select数据
			
一. ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField ...
 - 7. H.264的句法和语义
			
1.句法 在编码器输出的码流中,数据的基本单位是句法元素,每个句法元素由若干比特组成,它表示某个特定的物理意义,例如:宏块类型.量化参数等. 句法表征句法元素的组织结构,语义阐述句法元素的具体含义. ...
 - ubuntu 安装 rtpengine
			
摘要 RtpEngine推荐使用Debian系统,可以看出Debian系统的安装是最简单的.我是基于ubuntu18.04安装的.需要注意的是如果你的Ubuntu系统版本太低,安装时会遇到各种的版本太 ...
 - java 内存溢出
			
不健壮代码的特征及解决办法 1.尽早释放无用对象的引用.好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露. 对于仍然有指针指向的 ...