把if-else的代码风格改成表格驱动法的意义在哪里?

表格驱动的意义在于:逻辑和数据分离。


在程序中,添加数据和逻辑的方式是不一样的,成本也是不一样的。简单的说,数据的添加是非常简单低成本和低风险的;而逻辑的添加是复杂高成本高风险的。


用PHP举个例子吧,比如说,国家简写转换,给一个国家全名,转换成国家简写,用if-else法就写成:
<?php
function contry_initial($country){
    if ($country==="China" ){
       return "CHN";
    }else if($country==="America"){
       return "USA";
    }else if($country==="Japan"){
      return "JPN";
    }else{
       return "OTHER";
    }
}

如果我要增加一个国家,那么我要多加一个else if语句,那么我就是增加了一条逻辑


如果改成表驱动法就是:
<?php
function contry_initial($country){
  $countryList=[
      "China"=> "CHN",
      "America"=> "USA",
      "Japan"=> "JPN",
    ];

    if(in_array($country, array_keys($countryList))) {
        return $countryList[$country];
    }
    return "Other";

}

如果我增加一个国家,我需要在数组里面加个数据


那么接下来,我就可以剥离这个数据与逻辑的关系了。
<?php
function contry_initial($country, array $countryList){
    if(in_array($country, array_keys($countryList))) {
        return $countryList[$country];
    }
    return "Other";
}

重构到此为止,这样的好处在哪里?

1) 代码本身的优势
  • 逻辑和数据区分一目了然
  • 关系表可以更换,比如国家表格可以是多语言的,中文版表格,英文版表格,日语版表格,以及单元测试中,可以注入测试表格。
  • 在单元测试中,逻辑必须测试,而数据无需测试。

可以想象如果没有表格法,弄个多语言,要写多少语句。

2)数据来源的灵活性
接下来我们再来看看这个国家表格数据来源,如果是数据表格:
  • 来自代码
  • 来自配置
  • 来自INI
  • 来自数据库
  • 来自WEB API

等等,只要数据能转化成数组即可。

而逻辑,必须写死在代码中,无法灵活地重新定义。

3)数据输入修改的成本与风险
我们想想,聘用一个不懂编程,但培训一下就会用后台的客服便宜,还是会一个懂系统开发人员便宜?

如果这个是数据,是来自于数据库的,那么基本上公司的任何有权限的人在后台把这个映射表填一下,就能正常工作了。这个耗费与风险几乎可以忽略不计。 如果数据来自第三方API,如果第三方添加修改了数据,你也是基本放心的。

但是如果这个是逻辑本身,那么只能是这个系统开发人员进行修改,构建,然后经过一系列的测试,进行专业部署流程,使得这个功能在产品上运行,是个耗费与风险是不言而喻的。另外考虑到多人开发,开发风格不统一的话,那么开发成本和代码审查就不可避免了

4) 数据格式的强制性和代码风格的随意性
在现实工程中,多人开发一个功能很常见。这里就有一个多人代码风格的问题了。你如何确保别人的代码中的逻辑一定对呢?

对于数据来说,一但数据格式被代码确定后,数据格式就是强制性的了。
比如这个例子,无论是谁,加几个美国的数据也只能这样加:
<?php
 $countryList=[
      "China"=> "CHN",
      "America"=> "USA",
      "Japan"=> "JPN",
      "US"=> "USA",
      "United States of America"=> "USA",
      "美国"=> "USA",
    ];

就算原始数据结构的花样丰富,最终数据必须格式化成如此。

然而如果是逻辑的话,开发人员一多,逻辑方法就可能发生变化。你可能指望对方这样写代码:
<?php
    if ($country==="China" ){
       return "CHN";
    }else if($country==="America"){
       return "USA";
    }else if($country==="Japan"){
      return "JPN";
    }else if($country==="US"){
       return "USA";
    }else if($country==="United States of America"){
      return "USA";
    }else if($country==="美国"){
       return "USA";
    }else{
       return "OTHER";
    }

然而,对方可能会这样写:
<?php
 if ($country === "China") {
     return "CHN";
 } else if (in_array($country, ["America", "US", "United States of America", "美国"])) {
     return "USA";
 } else if ($country === "Japan") {
     return "JPN";
 } else {
     return ""
}

后来多了一个日本的需求,又交给另外不同的人去写,说不定最后如此:
<?php
 if ($country === "China") {
     return "CHN";
 } else if (in_array($country, ["America", "US", "United States of America", "美国"])) {
     return "USA";
 } else if ($country === "Japan"||$country === "日本") {
     return "JPN";
 } else {
     return ""
}

这样写,都没有错,然而风格却大相径庭。就是在多人合作编程过程中,无法控制所有人的风格,如果需要统一风格,必须依靠代码审查和大量修改,这需要大量资源和成本。

另外,就是因为如此,所有和if else相关的逻辑在单元测试中必须进行一次测试,才能确保逻辑代码的正确性,保证逻辑区域会正确运行;而如果是数据,由于数据格式的可控性,无需对数据进行测试。

由此可见:
  • 在多人开发的项目中,逻辑无序而不可控;数据格式有序而极易控制
  • 在单元测试中,逻辑区块必须进行测试,否则无法确保其正确性;而数据本身无需测试
  • 逻辑代码越少,逻辑复杂度就越少;逻辑代码越多,逻辑复杂度就越高


总结:
所有编程书籍上面都是从语言本身来解释重构的;我在这里是通过项目实践过程中现实意义来解释这个重构。重构if-else成表驱动的在一个项目现实意义总结一下就是:
  • 逻辑与数据分离
  • 逻辑修改成本巨大,数据修改成本极小
  • 逻辑修改风险巨大,数据修改风险极小
  • 数据来源灵活,数据改变灵活


--------------分割线-----
在回头用我上面的观点看看问题的代码:那朋友的重构也是 有意义的,因为这个表格可以进一步分离出去的。就算一个评分算法的个数不变了,但评分中参照数据的在未来是要修改的,那么修改数值 数据比修改数值 逻辑要便宜的多。


作者:caoglish
来自知乎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值