前两天跟同事做代码走查,看到代码里面很多这样的写法。
enum {OK, ERROR};
WORD32 calledFunc();
{
if(cond)
{
return ERROR;
}
return OK;
}
void func()
{
if(!calledFunc())
{
//do something
}
}
看到if(!calledFunc())
时,我很疑惑,calledFunc()
的返回值类型不是bool
,为什么在判断条件中要用!
。他说,他想在函数calledFunc()
返回成功时做些事情。他继续说到,你看,成功时返回OK
,OK == 0
,(!OK) == 1
。听起来倒也挺有道理。但是这其实是一种典型的巧合编程。
首先,为什么要跟我做这么多解释?解释类似于注释,是代码没有表达作者意图的体现。而事实上,这段代码也是存在隐患的。假如有一天,某个后来人心血来潮,想增加一种错误类型,枚举的定义变成这样enum {FATAL_ERROR, OK, ERROR};
,再看看if(!calledFunc())
,还是之前的逻辑吗?但是如果代码明确地写成if(OK == calledFunc())
,无论枚举值如何变化,代码逻辑永远不会出问题,这就是代码的可扩展性。看似在某种巧合下两种实现的结果相同,但是不良的编程习惯产生的代码是脆弱的。我们不能仅仅局限于代码的语法,眼光应该放的更远,应该穿透到它背后的价值观去认识它,这样的得到的知识才是牢靠的,经得起考验的。
不幸的是,我并没有机会在代码走查现场说明我的这些想法。因为,我的同事表现出了极大的排斥情绪,他觉得我是在吹毛求疵,他认为不应该在这种不影响当前代码正确性的问题上斤斤计较。在我看来,这些细节恰恰体现了一个程序员的习惯问题,这些看似微不足道的习惯,每一个背后都有一个价值观支撑,正是这种日积月累的持续思考和习惯养成,体现出一个优秀程序员和一个普通程序员的本质区别。不断刻意练习去夯实好的习惯,让它变的像水和空气一样平常,才能生产出行云流水般的软件作品。连Kent beck 这样的大师都说自己算不上一个伟大的程序员,仅仅是一个拥有良好编程习惯的程序员,这让我越发坚信习惯的力量,并且将在自己的职业生涯中孜孜追求。