BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

反对if行动

| 作者 赵劼 关注 4 他的粉丝 发布于 2009年7月7日. 估计阅读时间: 6 分钟 | 如何结合区块链技术,帮助企业降本增效?让我们深度了解几个成功的案例。

意大利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语句的案例,如:

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

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

同意这句话 by liu pi1ot

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

if 没有if by Yang Bean

多态污染?!

适度为佳 by Yang Bob

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

其实反对else更靠谱一些 by 熊 节

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



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



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

Re: 适度为佳 by im Kevin

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

各司其职 by Shichao Liu

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

干什么事用什么家伙.

if 是逻辑的最小单元 by He YuanHui

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

讨论一下 by Zhao Tong

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

return max(x, y);


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

Re: 讨论一下 by Sun Lice

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

适度问题 by ww walleve

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

无聊的观点 by 刘 建荣

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

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

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

多态污染 by zhang Rojer

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

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

rt。

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

Re: 适度为佳 by 宋 伟

赞成... ...

Re: 讨论一下 by 宋 伟

就是啊,我也想知道

Re: 适度为佳 by Geng Jet

赞成这个观点。

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

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

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

Re: 讨论一下 by 车 zorwi

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

Re: 讨论一下 by Jeffrey Zhao

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

基本不用else,大多用if-return by 张 中原

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

Re: 适度为佳 by ghost sole

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

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

本质上不是if的问题 by Wang Terrance

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

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

22 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT