实效的软件开发——谈些常见的错误观点

上周六,公司进行了一次技术培训,培训的内容无外乎就是常见的一些重构,敏捷开发的观点,当时因为有些事没有去听,但之后听同事说了一些关于培训内容的情况,也看了看培训的大致讲义,其实就是将重构等一些经典书籍的简单汇总,谈了些常识,原则性的东西。

那么在这里,我不是反对他的观点,当然,我也没有这样的权利反对,只是语言是最容易产生误会的,我只是纠正同样一句话给人带来的错误认识。

1. 代码和注释的关系

在培训上,应该是说了这样的话,好的代码是不需要注释的。

这里我就谈谈我对注释的看法。注释的产生有三个目的:

A. 对方法名不能过长的妥协

B. 对阅读者英文能力的妥协

C. 对复杂业务逻辑的标注

一般来说,为了可读性和规矩,我们不会把方法名写成一句完整的话,那么就只能用一些简单的词汇来代替,这样就出现,如果某个方法是一个相对复杂的业务逻辑方法时,你的方法名是没有办法完全准确地表达出整个方法的意思,这时,就只能依靠注释了。所以我说,注释首先是对方法名不能过长的妥协。

程序员水平参差不齐,尤其是英文水平,有的人过了GRE,有的人可能刚能勉勉强强读懂初中单词(在此无任何贬低他人的意思,我的英语就烂的出奇),因此为了提高工作效率,为了满足大多数企业的需求,为了照顾当今国内的现状,不能让每个程序员都为了不认识的单词去Google,因此我说,注释是对阅读者英文能力的妥协。

第三应该是注释最大用场的地方,无论我们把方法的职责拆分得多细,都不可能避免在某一个方法里面出现for,while,递归等复杂的业务逻辑或算法,那么当代码需要被维护时,这段业务逻辑被人看懂也许是比较浪费时间的,因此最简单的办法就是添加注释。

我说了很多注释的存在价值,那么注释是不是一定存在,我是不是在对这个著名的软件理论作挑战呢?不是。

注释应该是能少就少。不去写不必要的注释。当你对你的方法每一行都加注释的时候,就说明你的方法本身是失败的。

这就要求我们做到如下几点:

A. 方法,类名,见名知义。

B. 不使用无意义的变量名,说个我们最简单的,也是我们最常写的代码。

for(int i =0;i<arr.length;i++); i就是一个无意义的变量名,如果我们把i换成loop,是不是意义更明显了呢。(补充说明:鉴于大家都在针对这句话来说,那我就改改吧,其实我只是想表达不要使用无意义的变量名,例子举的不恰当,大家可以无视之。我只是想说明在程序会看到的某些变态的xxx,yyy,gddb之类的变量名字 

C. 把垃圾代码消灭在萌芽。垃圾代码必然导致恨多错乱的逻辑,很可能这里引入一个逻辑变量,那里引入一个辅助参数,这样的代码,怎么可能没注释呢。

最后总结下,注释,需要有,记得以前看过一句话叫:完美的人生不需要解释,完美的代码不需要注释。这个就有些太极端了,一个完美的代码,又没有注释,那只能说明这个项目的业务逻辑太简单了。

2. 什么是良好的软件设计

完美的设计,不是不能增加,而是不能减少,这个是定义设计过度最恰当的一句话了,在我看来,补上一句:“并且不能修改”。这个是最恰当的,否则会被陷入无设计的错觉当中。完整的一句话也就是:“完美的设计,不是不能增加,而是不能减少;不是不能扩展,而是不能修改。”

随着越来越多的人说,设计模式(我说的是设计模式,而不是GOF的23种设计模式)是个没有用的东西,我感觉特别无助。也许是从asp到asp.net这一代的转换,很多人都习惯了在一个方法里堆砌很多数据库的操作。每次当修改一个Bug时,你做的是:首先找到这个按钮,然后把方法从头读到尾,看到底哪句话出了问题。

如果对于一个小系统来说,这无可厚非,代码逻辑简单,随便拿出一个程序员都可以做出这样一整套的系统,最多是时间长短而已。可是这真的是开发一个软件该有的方法么?

我们首先来说两个原则:OCP(开闭原则)和 DRY(Don’t Repeat yourself)。如果你连这两个原则都在否认,那么好,你怀疑的是整个软件史,连史上所有的软件大师都不能说服你,我自然也无能为力了。

说最简单的DRY确保了你封装的必要性,而OCP则确保了你设计和分包的重要性。

很多人见到封装就怕了,就总希望你把所有东西都写到页面上,一切逻辑都是一句最简单的SQL,说封装的东西看不懂,SQL是最容易懂的。那好,我来简单地说下封装。

封装有两个好处:

A. 你在外界可以重用被封装好的方法,而无需关心内部的业务逻辑,这是方便使用者。职责分离不仅仅体现在软件设计上,同样应该体现在软件工程,项目管理中,闻道有先后,术业有专攻,很少有人既是SQL专家又是CSS专家,同样,很少有人既是技术专家又是业务专家。三层架构的划分,其中很重要的一个目的就是职责分离。那么说最简单的,我把复杂的业务逻辑全都封装到BLL里,做用户界面层的是不是就可以专注于界面的展示了呢?逻辑有了错误我来担着,你只管按规则调用,那还怕什么呢?

B. 封装是安全的。封装隐藏了一些对外不应公开的方法,使得外界无法访问和调用,从而防止使用者因为误操作而毁坏系统(或数据)。

再说个更实际的,我把方法封装好,可以让调用的方法更加精简简短,使得代码看起来逻辑更清晰。如此这样,你还讨厌封装么?

在接下来说分包和设计的问题,我们在这里说OCP的原则是:对扩展开放,对修改关闭。那么我们怎么去最简单地理解这句话呢?当我们要向原系统中增加需求时,无须变更原有代码,无须更改原有代码的dll,而只需要增加就可以了。设计模式发展到今天,终极目标已经是打造一个完全可配置的软件项目,那么这样也就可以实现我们的完美OCP。

你真的了解分层架构吗?——写给被PetShop"毒害"的朋友们 这篇文章中,T2噬菌体 指出了我们很多人对三层架构就是BLL+DAL+WebSite的误解,其实当我们一步一步打造可配置的软件项目时,当我们提出“面向组件编程“时,甚至说当我们提出“SOA”时,我们应该要想到,一个软件应该是由无数个组件(.dll)来组成的,我们在配置文件中,针对这些组件进行自由选择,每个.dll都应该是一个单独的变化点,当我们在设计模式中,看到“每个类不应该超过一个使其变化的原因”时,我们应该想到,对于当今软件来说,这个观点应该改为:“每个DLL不应该存在超过一个使其变化的原因”。

我这样说,您还会说,一个项目中存在很多.dll是个很恐怖的事情么?

3. 总结

迷迷糊糊写了这么多,我只是想说明,其实,每个程序员可以怀疑理论,但是首先,我们要看清楚这个软件理论,吃透这个理论的本质内涵。

winter-cn 和我说过一句话,对我影响很大,“尽信书不如无书,可是当你尽疑书又何必有书”。有时我只是奉劝身边的朋友,相信大多数的程序员还都是普通人,我们大多数还没有达到国外那些软件大师的水平,我们又凭什么去怀疑人家几十年的观点,几十年的软件理论是错误的,是没用的呢?

当你说RUP无用的时候,当你说设计模式无用的时候,当你说软件工程流程没用的时候,当你说分层没用的时候,当你说某种软件理论没用的时候,当你说某个技术垃圾到不行的时候,先闭上眼睛,静心想一想,和提出该理论的人比,我比他强么?

孤身和整个软件学术界抗衡,你,还够格么?

posted @ 2010-01-12 01:00  飞林沙  阅读(2696)  评论(31编辑  收藏  举报