posted at 2021.9.5 17:20 by 风信子
表驱动法是一种设计思路,可以称为模式,也可以简单理解为查字典,例如有一个枚举类型Week,
enum Week
{
Monday,
Tuesday,
Wednesday,
Thursday,
Fridey,
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.Fridey:
return "星期五";
case Week.Saturday:
return "星期六";
case Week.Sunday:
return "星期日";
default:
throw new ArgumentOutOfRangeException("week", "星期值超出范围");
}
}
之所以说这种方法是丑陋的,原因在于两点:
1)分支太长了,而且出现了重复代码。
2)不利于扩展。如果出现星期八、星期九怎么办?
当然,星期制已经是固定的了,应该不会出现扩展的情况。但是,换种情景来考虑,假设我们正在渲染动画怎么办?谁知道下一秒美工会提交我多少个动画呢?
一种解决方案是使用多态,它很好地符合了“开闭”原则。如果增加条件分支,不必修改原有代码,直接增加子类就可以了。利用多态来避免多分支,这里暂且不表,采用“表驱动法”的代码如下所示:
Static void Main(string[] args)
{
Console.WriteLine(GetChineseweekInTable(week.Friday))
}
static string GetChineseInTable(Week week)
{
string[] ChineseTable = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
return ChineseTable[(int)week];
}
这是一种按照索引值驱动的表驱动法。枚举元素所代表的整型值,很容易和字符申数组索引组合起来了,用两行语句就可以完美地替代原先的GetChineseWeek方法。
但是,这种方法有局限性,完成的功能也很有效,如果将需求换成:星期一Mike打扫卫生、星期二Rose清理衣柜、星期三Mike和Rose没事可以吵吵架、星期四Rose要去Shopping......也就是说需求由静态属性变成了动态行为,那么事情就变得复杂了。
遇上这种情况,我们可能会想到使用多态,在这里仍然使用表驱动法+反射reflection来实现这类动态的行为,代码如下所示:
static void Main(string[] args)
{
//Console.WriteLine(GetChineseWeek(Week.Monday));
//Console.WriteLine(GetChineseInTable(Week.Thursday));
SampleClass sample = new SampleClass();
Var addMethod = typeof(SampleClass).GetMethod(ActionInTable(Week. Tuesday));
addMethod.Invoke(sample, null);
}
static string ActionInTable(Week week)
{
string[] methods = { "Cleaning", "CleanCloset", "Quarrel", "Shopping", "Temp", "Temp", "Temp" };
return methods[(int)week];
}
class SampleClass
{
public void Cleaning()
{
Console.WriteLine("打扫");
}
public void CleanCloset()
{
Console.WriteLine("清理衣柜");
}
public void Quarrel()
{
Console.WriteLine("吵架");
}
public void Shopping()
{
Console.WriteLine("购物");
}
}
控制台实际效果如下图所示:
7335846a-0800-40d1-93c0-9dd0ebb4bc37|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04
Tags: 代码, 方法, 类, 模
IT技术 | 防控BUG