QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

反对 if 行动

  • 2009-07-06
  • 本文字数:1466 字

    阅读完需:约 5 分钟

意大利 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;
}

复制代码
不过社区中对此也有 [不同看法](http://news.ycombinator.com/item?id=673678),有人讽刺道:
> 哦,这里我发现了一个问题。尊敬的客户,您前一个顾问使用了“if”语句,让我把这个函数替换为 80 个新类,这样显得更加敏捷一些。
>
> Don't Repeat Yourself 看上去更敏捷一些。更好的做法是:等到出现第 3 遍重复代码的时候才去重构(不过也别等太久了)。这样可以避免很多无所谓的代码,也可以让程序员有更灵活的选择余地。
也有人为“反对 if 行动”进行了补充:
> 我想这个行动并不是说“删除所有的 if 代码”,而是将类型判断逻辑使用多态进行替换。如果把它称为“反对类型字段行动”会更合适一些。
“反对 if 行动”也在征集“if-free”的代码示例,您也可以在那里 [提交代码片断](http://www.antiifcampaign.com/code-recruitment.html)。事实上,国内社区也提出了不少消除繁琐 if 语句的案例,如:
- [ Jeffrey Zhao 编写了一个简单的类库](http://www.cnblogs.com/JeffreyZhao/archive/2009/01/07/AttachDataExtensions.html),使.NET 中的枚举类型可以携带一些信息,以便统一地获取数据或进行运算。
- [木野狐使用了 State 模式](http://www.cnblogs.com/rchen/archive/2007/04/16/js_state_machine.html),简化了不同状态下,Web 界面中相应组件的样式切换方式。
- [ Tristan G 设计了一组流畅的 API](http://www.cnblogs.com/tristanguo/archive/2009/05/15/1457197.html),使开发人员能够方便地编写实体验证规则。
您在这方面是否也有独特的经验呢?不妨也一起分享出来吧。
2009-07-06 21:165700
用户头像

发布了 157 篇内容, 共 55.7 次阅读, 收获喜欢 6 次。

关注

评论

发布
暂无评论
发现更多内容

架构师训练营 - 作业 - 第五讲

吕浩

week5 作业

雪涛公子

架构师训练营第五周 - 总结

Larry

架构师训练营Week5学习总结

小高

第五周 架构师技术选型总结

netbanner

架构师 0 期 | 缓存--提升性能大杀器

刁架构

极客大学架构师训练营

架构师训练营-第五章-课程总结

而立

极客大学架构师训练营

Week05 学习心得 - 技术选型

极客大学架构师训练营

week5. 总结心得

dj_cd

极客大学架构师训练营

第四周架构课程总结心得

dj_cd

极客大学架构师训练营

第五周总结

Linuxer

极客大学架构师训练营

架构师训练营第 5 周作业

Season

一致性哈希 一致性Hash算法

架构师训练营第五周学习总结

Bruce Xiong

架构师训练营第 5 周学习总结

Season

缓存 反向代理 消息队列

「架构师训练营」第 5 周总结

guoguo 👻

极客大学架构师训练营

第五周学习总结

CP

第五周作业:一致性 hash 算法

Larry

一致性hash的Java代码实现

叶鹏

架构师训练营第五周作业

Geek_2dfa9a

面向对象学习

一叶知秋

免费的GPU,还有全系列的OpenJDK

孙苏勇

Java 学习 gpu Openjdk Colab

架构师训练营第五周作业

fenix

第五周作业

路人

极客大学架构师训练营

第五周总结

叶鹏

架构师训练营-第五章-一致性hash算法

而立

极客大学架构师训练营

第五周总结

nihuihua

week5 总结

雪涛公子

架构师训练营 第五周 作业

极客

第五周作业

CP

第五周作业

nihuihua

架构第四周课程作业

dj_cd

极客大学架构师训练营

反对if行动_研发效能_赵劼_InfoQ精选文章