解决多个if-else的方案

发布时间 2023-11-03 17:36:32作者: 海岸线summer

参考链接:

遇到大量if记住下面的口诀:

互斥条件表驱动

嵌套条件校验链

短路条件早return

零散条件可组合

解释:

  1. 互斥条件,表示几个条件之间是冲突的,不可能同时达成的。比如说一个数字,它不可能同时是4和2。在这种情况下用表驱动就非常合适,表驱动的核心是key-handler,拿某个key去对应某个handler,只要条件符合key,那么就执行对应的handler。
  2. 嵌套条件,表示几个条件是必须同时达成的,比如,只有在手机号码格式正确的情况下才执行某个操作,格式正确就包括必须是字符串、长度为11位、所有位都是数字这些条件,那么就可以使用校验链,比如通过描述的校验链:"string&size:11&numchar:0,*"。能用的形式很多,你可以直接使用&&逻辑运算符拼接条件,也可以把规则写成Validator。
  3. 短路条件,表示只要某个条件满足了,那么就不用再继续下面的任何操作了。比如传进来的参数是null、参数如果为0,就不会有其他操作等情况,都可以聚合这些条件,在一开始的时候就判断并且直接返回,或者程序在中间会产生一些可以直接判断为不需要继续往下操作的条件,那么同样是直接在当场就return。
  4. 零散条件,是指存在以上三种任意组合的条件形式,那么就可以通过组合这些解决方案。例如,遇到null,直接短路返回,然后之后的代码使用表驱动来区分互斥条件,在达成某个互斥条件的时候,通过校验链来验证嵌套条件等。

(99+ 封私信 / 84 条消息) 优化代码中大量的 if/else ,你有什么方案? - 知乎 (zhihu.com)

彻底消灭if-else,你需要这8种方案! - 知乎 (zhihu.com)

表驱动方法学习:

《编写高质量代码改善C程序的157个建议》表驱动

《责任链模式学习》

C#设计模式(21)——责任链模式 - Learning hard - 博客园 (cnblogs.com)

表驱动法——核心就是条件要是互斥的,一种条件对应一种方法,然后通过键值的方式去通过条件(key)查到对应的方法(value)并执行。

static void Main(string[]args)
{
Console.WriteLine(GetChineseWeekInTable(Week.Friday));
}

static string GetChineseWeekInTable(Week week)
{
string[]chineseWeek={"星期一","星期二","星期三","星期四","星期五",
"星期六","星期日"};
return chineseWeek[(int)week];
}


复杂一点的,这是一种按照索引值驱动的表驱动法。枚举元素所代表的整型值,很容易和字符串数组索引组合起来了,用两行语句就可以完美地替代原先的GetChineseWeek方法。但是,这种方法有局限性,完成的功能也很有效,如果将需求换成:星期一Mike打扫卫生、星期二Rose清理衣柜、星期三Mike和Rose没事可以吵吵架、星期四Rose要去Shopping……也就是说需求由静态属性变成了动态行为,那么事情就变得复杂了。
遇上这种情况,我们可能会想到使用多态,在这里仍然使用表驱动法并加上一点反射来实现这类动态的行为,代码如下所示:

static void Main(string[]args)
{
	SampleClass sample=new SampleClass();
        var addMethod=typeof(SampleClass).GetMethod(ActionInTable(Week.Monday));
        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("购物");
}
}