BT

专栏:代码之丑(七)——你的语言

| 作者 郑晔 发布于 2010年12月7日. 估计阅读时间: 不到一分钟 | 欲知区块链、VR、TensorFlow等潮流技术和框架,请锁定QCon北京站!

这是一段用C++编写的数据库访问代码:

int Comm::setIDBySevNum(const XString& servnumber) { 
   DB db; 
   db.setSQL("select id from users where servnumber=:servnumber"); 
   db.bind(":servnumber", servnumber.c_str()); 
   db.open(); 

   if  (!db.next()) {
      return -1; 
   } 
   setID(db.getString(”id")); 
   return 0; 
}
 

它告诉我们,如果找不到需要的值,那么操作失败,返回-1,否则,返回0,成功了。

显然,写下这段代码的人有着C语言的背景,因为在C语言里面,我们常常会用整数表示成功失败。我说过,这是一段C++代码,而C++里面有一种类型叫做bool。

整数之所以能够占有本该属于布尔类型的舞台,很大程度上是受到C语言本身的限制。当然,C99之后,C程序员们终于有了属于自己的体面的布尔类型。

只是还有为数不少的C程序员依然生活在那个蛮荒年代。于是,很多人通过各种不尽如人意的方式模拟着布尔类型。不过,我们也看到了,偏偏就有这些生在福中不知福的程序员努力的重现着旧日时光。在我的职业生涯中,我见过许多用不同语法编写的C程序。

就个人学习语言经验而言,了解了基本的语法之后,如果有可能,我希望找到一本 Effective,寻求这门语言的编程之道。很多语言都有着自己的Effective,比如《Effective C++》、《Effective Java》、《Effective C#》,等等。

不了解语言,也会给丑陋代码可乘之机。比如,下面这段C++代码;

void CommCode::notifyCRM(XString* retparam) { 
   if (NULL == retparam) { 
     throw  IllegalArgumentsException(GetErrorMsg(" CommCode ::notifyCRM")); 
   } 
   ... 
}
 

如果把指针换成引用,就可以省去参数为空的判断,因为在C++里,引用不为空。这里选择了一个简单的例子,而在真实的代码里,这种检查漫天遍野,其丑陋可想而知。某些函数里面,检查甚至超过了真正的执行部分。

工欲善其事,必先利其器。有了铲子,就别再用手挖地了。

作者简介:

郑晔,ThoughtWorks公司咨询师,拥有多年企业级软件开发经验,热衷于探索各种程序设计语言在真实软件开发中所能发挥的威力,致力于探寻合理的软件开发方式,加入ThoughtWorks公司后,投入到敏捷开发方法的实践之中,为其他公司提供敏捷开发方法方面的咨询服务。他的blog是梦想风暴

查看原文:代码之丑(七)

评价本文

专业度
风格

您好,朋友!

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

获得来自InfoQ的更多体验。

告诉我们您的想法

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

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

最新更新有点慢了,而且这个题目是不是应该写成(七)? by jinjun fu

最新更新有点慢了,而且这个题目是不是应该写成(七)?

Re: 最新更新有点慢了,而且这个题目是不是应该写成(七)? by 胡 伟红

sorry,已经更正了!

方法名说明无需返回任何值,如果是 C#,void 即可! by 高 翌翔

确实,语言的差异性不可避免。

在任何使用一门语言前,最好快速阅读一下该语言的语法说明文档,
就如同买了家里添置了新电器,首先要阅读用户使用说明书一样!

setIDBySevNum 方法名说明该方法是一个操作性的动作,
如果使用的是 C# 通常无需返回任何值,一旦处理过程中违反了业务规则,
直接抛出指定的异常即可。

至于作者说“在真实的代码里,这种检查漫天遍野,其丑陋可想而知。”,
有些业务规则检查是不可避免的,关键是把业务规则检查放在哪个层中来做。

有时代码的丑陋源于代码组织的不合理,或职责不够清晰,不要惧怕改写丑陋的代码,
因为它们是今天美丽代码的昨天。

lz没有明白c语言中有的函数为什么用int做判断 by sun ssx

如果说是因为c没有bool,那正常应该返回1,错误才返回0,再用个#define TRUE 1
#define FALSE 0就可以了

.这样比较的返回值的时候,只要用if (func())就可以判断是否成功。

而C语言这个习惯,是因为函数可以用返回0表示正确返回,而其他值可以分别表示不同的错误原因,比如说-1是分配内存失败,-2是打开文件失败。

一个bool类型只能表示两种情况。

Re: lz没有明白c语言中有的函数为什么用int做判断 by Byers Roger

没有异常机制的环境下似乎也就这样做了

引用和指针区别 by Kraft Bai

感觉就是一种约定,caller一定要保证是有效的引用;如果不保证,比用指针还危险。
如果约定好了,其实不用check null也行;但不check null实在是一种反习惯,大家肯定都不适应。

Re: 最难做到的就是遵守约定! by 高 翌翔

其实问题是大家难以保证遵守约定,check null 只是迟早的问题,
既然无法保证在外边做 check null,那么还是在里面做 check null,这是做后的防线!

Re: lz没有明白c语言中有的函数为什么用int做判断 by 王威 Andy

用返回值表示错误原因?好吧,10年前我在大学时代是这么做的……

顶楼主 by zihan Lee

个人觉得, 这样的处理其实并没有错误, 但作者的意思也是很正确的,

现在个人依然在使用0表示正确, 别的数表示错误, 这样会有一个很好的状态码维护

允许的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通知我

9 讨论
BT