反对if行动

作者 赵劼 发布于 2009年7月6日 下午9时16分

社区
.NET,
Agile
主题
质量交付

意大利XP倡导者Francesco Cirillo为他著名的“反对if行动”创建了一个网站,一时吸引了不少支持者Francesco认为

if所带来的问题主要在于建立了模块(方法、对象、组件等)之间的依赖,也增加了代码路径的分支(这会降低代码的可读性)。

Francesco举了一个示例,认为如下的代码:

// Bond class
double calculateValue() {
       if(_type == BTP)  { 
        return calculateBTPValue();
       } else if(_type == BOT) { 
                 return calculateBOTValue();    
              } else {
                 return calculateEUBValue();
              }
}

应该使用多态将显式的if或switch语句消除:

// Bond class
double calculateValue() {
    _bondProfile.calculate();
}
// AbstractBondProfile class
abstract double calculate();

// classe BTPBondProfile >> AbstractBondProfile
double calculate() {
    ...
}
// classe BOTBondProfile >> AbstractBondProfile
double calculate() {
    ...
}
// classe EUBondProfile >> AbstractBondProfile
double calculate() {
    ...
}

Francesco认为这样做的好处在于

当我们需要增加新的bond类型时,只需创建一个新的类型来保存这部分独立逻辑即可。

创建抽象类或接口并非是改进的唯一方式,我们的目的是将程序变得更灵活、更易于交流、更容易测试、并且随时拥抱变化。

对于“反对if行动”,Matteo Vaccari补充了几点做法

  修改前 修改后
直接使用布尔运算结果
if (foo) {
  if (bar) {
    return true;
  }
}
if (baz) {
  return true;
} else {
  return false;
}
return (foo && bar || baz); 
使用辅助函数
if (x > y)
  return x;
return y;
return max(x, y);
灵活使用0的作用
int arraySum(int[] array) {
  if (array.length == 0) {
    return 0;
  }
  int sum = array[0];
  for (int i=1; i < array.length; i++) {
    sum += array[i];
  }
  return sum;
}
int arraySum(int[] array) {
  int sum = 0;
  for (int i=0; i < array.length; i++) {
    sum += array[i];
  }
  return sum;
}

不过社区中对此也有不同看法,有人讽刺道:

哦,这里我发现了一个问题。尊敬的客户,您前一个顾问使用了“if”语句,让我把这个函数替换为80个新类,这样显得更加敏捷一些。

Don't Repeat Yourself看上去更敏捷一些。更好的做法是:等到出现第3遍重复代码的时候才去重构(不过也别等太久了)。这样可以避免很多无所谓的代码,也可以让程序员有更灵活的选择余地。

也有人为“反对if行动”进行了补充:

我想这个行动并不是说“删除所有的if代码”,而是将类型判断逻辑使用多态进行替换。如果把它称为“反对类型字段行动”会更合适一些。

“反对if行动”也在征集“if-free”的代码示例,您也可以在那里提交代码片断。事实上,国内社区也提出了不少消除繁琐if语句的案例,如:

您在这方面是否也有独特的经验呢?不妨也一起分享出来吧。

同意这句话 发表人 pi1ot liu 发表于 2009年7月6日 下午9时34分
if 没有if 发表人 Bean Yang 发表于 2009年7月7日 上午1时13分
适度为佳 发表人 Bob Yang 发表于 2009年7月7日 上午3时3分
Re: 适度为佳 发表人 Kevin Yang 发表于 2009年7月7日 上午6时19分
Re: 适度为佳 发表人 伟 宋 发表于 2009年7月8日 下午10时31分
Re: 适度为佳 发表人 Jet Geng 发表于 2009年7月9日 上午12时21分
Re: 适度为佳 发表人 sole ghost 发表于 2009年9月17日 上午2时29分
其实反对else更靠谱一些 发表人 Jeff Xiong 发表于 2009年7月7日 上午5时8分
各司其职 发表人 Liu Shichao 发表于 2009年7月7日 上午6时33分
if 是逻辑的最小单元 发表人 YuanHui He 发表于 2009年7月7日 上午9时10分
讨论一下 发表人 Tong Zhao 发表于 2009年7月7日 下午6时40分
Re: 讨论一下 发表人 Lice Sun 发表于 2009年7月7日 下午7时33分
Re: 讨论一下 发表人 伟 宋 发表于 2009年7月8日 下午10时33分
Re: 讨论一下 发表人 zorwi 车 发表于 2009年7月9日 上午5时58分
Re: 讨论一下 发表人 Jeffrey Zhao 发表于 2009年7月12日 上午3时35分
适度问题 发表人 jeccy ww 发表于 2009年7月7日 下午8时18分
无聊的观点 发表人 建荣 刘 发表于 2009年7月7日 下午9时53分
编程语言是对自然语言的一种折射 发表人 long zhang 发表于 2009年7月8日 上午2时32分
多态污染 发表人 Rojer zhang 发表于 2009年7月8日 下午9时16分
如果我们还是做软件的人,就不能只看代码。 发表人 wake jong 发表于 2009年7月8日 下午10时19分
基本不用else,大多用if-return 发表人 tom z 发表于 2009年7月12日 上午9时37分
本质上不是if的问题 发表人 yicone wang 发表于 2009年11月22日 上午12时36分
  1. 返回顶部

    同意这句话

    2009年7月6日 下午9时34分 发表人 pi1ot liu

    “哦,这里我发现了一个问题。尊敬的客户,您前一个顾问使用了“if”语句,让我把这个函数替换为80个新类,这样显得更加敏捷一些。”

  2. 返回顶部

    if 没有if

    2009年7月7日 上午1时13分 发表人 Bean Yang

    多态污染?!

  3. 返回顶部

    适度为佳

    2009年7月7日 上午3时3分 发表人 Bob Yang

    好和不好要看使用的场合,全部去掉if是过渡设计,全部使用if是混乱的根源,如果不需要无限制的扩展那么用if又有何不对呢?把握尺度才是关键.

  4. 返回顶部

    其实反对else更靠谱一些

    2009年7月7日 上午5时8分 发表人 Jeff Xiong

    因为if可以用来实现early return(《重构》里说的guard clause)。虽说guard clause太多也不是什么好事,不过,如果结合其他规则(比如每个方法不超过5行),if构成bad smell的机会并不大。



    而else就不一样:几乎每个else都一定是一种信号,表示一个方法承担了两种责任。如果要玩严格编程的话,取消else是个不错的练习。



    gigix.agilechina.net/2009/7/7/program-without-else

  5. 返回顶部

    Re: 适度为佳

    2009年7月7日 上午6时19分 发表人 Kevin Yang

    re
    感觉XP的人都是极端编程主义者。。。。

  6. 返回顶部

    各司其职

    2009年7月7日 上午6时33分 发表人 Liu Shichao

    关键是要分清什么工具适合什么情景, 什么问题用什么途径去解决.
    没什么技术能成为银弹, 多态也是一样.

    干什么事用什么家伙.

  7. 返回顶部

    if 是逻辑的最小单元

    2009年7月7日 上午9时10分 发表人 YuanHui He

    if 是逻辑的最小单元,消除了if,怎么实现逻辑?
    做任何事情都应该看到事物的本质,而不是看到表面的东西乱打一气

  8. 返回顶部

    讨论一下

    2009年7月7日 下午6时40分 发表人 Tong Zhao

    打个比方啊,您这里
    if (x > y)
    return x;
    return y;
    用这个代替

    return max(x, y);


    那我想问下您max这个函数里该怎么写。

  9. 返回顶部

    Re: 讨论一下

    2009年7月7日 下午7时33分 发表人 Lice Sun

    这个函数是系统自己内置的,当然这样的说法有点极端,因为你在写程序的时候不去实现,不代表你所用的类库不去实现。针对自己开发的系统来说,这样省去if,无非在强调多态,如果真的为了去掉一个if,写80个函数,目的又是什么?

  10. 返回顶部

    适度问题

    2009年7月7日 下午8时18分 发表人 jeccy ww

    应该不能说全部消除,否则我们的逻辑从哪里来?
    尽可能在一定程度上来简化是有必要的

  11. 返回顶部

    无聊的观点

    2009年7月7日 下午9时53分 发表人 建荣 刘

    这是一种极端偏执和没有任何可行性的观点,if...else...是比较自然的逻辑语言,这是多态体现不出来的

  12. 返回顶部

    编程语言是对自然语言的一种折射

    2009年7月8日 上午2时32分 发表人 long zhang

    编程语言的不断发展正是反映了其与自然语言及现实世界的关系,它的目标应该是更加真实的反映自然语言与现实世界。现实世界当中存在如果...那么,而且用的又是那么频繁,为何编程语言就不能出现呢。话又说回来了,自然语言的如果...那么不会出现过多的判断,因此限制好编程语言的if...else的数量是首要任务,当然这需要靠程序员自己去做出聪明的判断了。

  13. 返回顶部

    多态污染

    2009年7月8日 下午9时16分 发表人 Rojer zhang

    喜欢这个词“多态污染”!设计过度!

  14. 返回顶部

    如果我们还是做软件的人,就不能只看代码。

    2009年7月8日 下午10时19分 发表人 wake jong

    rt。

    代码本身没有问题,反对"if"未免有一些片面。

  15. 返回顶部

    Re: 适度为佳

    2009年7月8日 下午10时31分 发表人 伟 宋

    赞成... ...

  16. 返回顶部

    Re: 讨论一下

    2009年7月8日 下午10时33分 发表人 伟 宋

    就是啊,我也想知道

  17. 返回顶部

    Re: 适度为佳

    2009年7月9日 上午12时21分 发表人 Jet Geng

    赞成这个观点。

    大量使用if的确有很多弊端。在2005年左右,我曾经在公司内部群发过一封题为“和if说再见”的邮件。当时主要是针对代码中存在大量的if嵌套,以及if分支中包括大量代码而写的。经过这么多年,回头又看到这个问题。觉得凡事需要把握分寸。个人觉得,当时的代码中存在很多分支并且分支中包括大量的代码。这个是不是就暗示,每有分支的业务差别很大。对于这个业务是否可以通过封装等等方式进行处理。

    如果业务简单或很清晰的情况下,用if本生并没有什么不多。

    个人觉得好代码并不在于你用不用“if”,“goto” 或其他的关键字。关键在于代码是不是清晰,易读,健壮和可扩展。
    个人看法,欢迎各位拍砖

  18. 返回顶部

    Re: 讨论一下

    2009年7月9日 上午5时58分 发表人 zorwi 车

    int max(int x,int y)
    {
    return x>y?x:y;
    }

  19. 返回顶部

    Re: 讨论一下

    2009年7月12日 上午3时35分 发表人 Jeffrey Zhao

    其实就是下面两种东西的区别。
    1、n个if
    2、1个if和n个max

  20. 返回顶部

    基本不用else,大多用if-return

    2009年7月12日 上午9时37分 发表人 tom z

    用Statement可以完全替代if分支
    记得很早在jdon有过这种讨论,不过是OO的
    但是有点得不偿失了
    极端了

  21. 返回顶部

    Re: 适度为佳

    2009年9月17日 上午2时29分 发表人 sole ghost

    好和不好要看使用的场合,全部去掉if是过渡设计,全部使用if是混乱的根源,如果不需要无限制的扩展那么用if又有何不对呢?把握尺度才是关键.

    顶,非常有道理
    没有最好的,只有最合适的

  22. 返回顶部

    本质上不是if的问题

    2009年11月22日 上午12时36分 发表人 yicone wang

    本质上不是if的问题, 是代码复杂度的问题, VS里有一个功能, 用它自己的一套算法, 来判断项目中类/方法的代码复杂度. 当复杂度到达一定程度后, 及时重构是必要的.
    我们设计上考虑用多态/设计模式的时候, 想必出发点不是看到If以后才萌生杀机吧; 编码的时候倒是可以考虑, 运用小方法的好习惯和一些其他的小技巧来提高代码可读性. 当然闻到坏味道的时候返回设计, 进行重构是好的实践.

::...
免责声明:
当前网页内容, 由 大妈 ZoomQuiet 使用工具: ScrapBook :: Firefox Extension 人工从互联网中收集并分享;
内容版权归原作者所有;
本人对内容的有效性/合法性不承担任何强制性责任.
若有不妥, 欢迎评注提醒:

或是邮件反馈可也:
askdama[AT]googlegroups.com


订阅 substack 体验古早写作:


点击注册~> 获得 100$ 体验券: DigitalOcean Referral Badge

关注公众号, 持续获得相关各种嗯哼:
zoomquiet


自怼圈/年度番新

DU22.4
关于 ~ DebugUself with DAMA ;-)
粤ICP备18025058号-1
公安备案号: 44049002000656 ...::