沙场秋点兵 阅读(106) 评论(0)
  程序设计技术发展至今,对象的概念始终贯穿与设计过程的始终,广义的对象包括了参与设计的所有编程元素,比如变量,函数,类,组件,服务等。在程序设计理论中,对象的设计基本上就等同于设计的全部。在对象设计的进化过程中,渐渐的就有了一些通用的规则。人们常说美食要色香味俱全,代码也不例外,这里首先总结了设计中最重要,也最容易为人所忽略的几个原则,这几个点都是描述代码的外观特点,我称之为"代码之形",我认为它们是一切设计的起点和基础。
 
代码之"形"
 
  我记得一位牛叉的程序员说过:任何程序员都能写出机器能懂的代码,只有最优秀的程序员才能写出人能懂的代码。人能懂的代码最基本的要满足下面的几个条件。
 
1. 简单
  这一原则非常简单,又非常重用,任何难以维护和扩展的代码基本都不是简单的代码,敏捷开发提倡简单设计,我个人觉得还是非常有道理的,越是简单的设计,越是简单的代码,越是容易维护,越是容易重构,问题也相对越少。
  当然了,简单并不等同于代码越少越好,功能越少越好,这里的简单通常指的是逻辑处理上应用简单直接的设计来满足目前的需求。
  在重构理论中,也非常强调逻辑简单,比如少用复杂的运算符和复杂的逻辑条件,每个循环争取只干一件事等等。
  在编程理论中有一个很重要的概念叫做圈复杂度,它是用来衡量函数的复杂性的。
  函数圈复杂度计算的方法很简单:
 
每个函数圈复杂度起始值为1,代表有一个路径执行完函数,每遇到一个if/case/for/while/and(逻辑与运算,如&&)/or(逻辑或运算,如||)就增加1,这样计算的最终结果就是函数的圈复杂度。

  圈复杂度越大,说明函数越复杂,越有存在缺陷的可能,也越有重构的必要。

  个人认为把函数的圈复杂度控制在10以内是比较好的做法。
  对于对象的设计,有一种观点我觉得很对,那就是:如非必要,请远离各种设计模式。这个观点的就如同另外一个观点一样智慧:如非必要,请不要试图优化代码,提高效率。
  我记得曾有位仁兄使用了23中设计模式实现了不同的"Hello World",从学习角度,我还是很佩服其想象力的;但是从实用角度,我只能表示"呵呵"了。
 
2. 大小合适
  代码逻辑简单的一个很重要的衍生规则就是代码数量要大小适中。我很难想像任何人看见内容有1000行代码的函数和内容只有10行代码的函数感觉会是一样!小通常意味着简单。反之也成立。个人认为把函数的行数限制在50行以内,类的方法限制在30以内是很好的做法。超过这个数目,就有了重构的必要。
  有一种很有市场的观点就是:如果小函数很多的话,调用堆栈就会很长,这样执行的效率就不会高。
  针对这种观点,我的想法是:且不说现在硬件的性能每年都在进行着翻天覆地的变化,就说现在的编译器已经足够智能了,小函数大多数情况下都在编译时内联了,执行的效率损失几乎是微乎其微。而且从我的感觉来看,大部分项目失败的原因中,除了对效率要求特别高的项目(我们大部分项目都不属于这一类),因为效率原因失败的是少之又少。
  另一种观点是:控制函数行数的话,意味着要拆分很多的小函数,小函数很多了也不好管理,于是不要拆分了。
  确实,这个问题是真实存在的问题,每个人可能都会遇到,但是我觉得通过使用注释标记(特别是C#中有region)还是可以很好管理的。而且相对于小函数带来的可读性和易维护,这点损失还是值得的。
  所以,我的观点是尽情通过重构去控制函数的大小吧,无需多虑(我还真怕有人跟我抬杠说:"那你怎么不一句话一个函数呢?")。
 
3. 命名易懂
  这条原则无论如何强调都不为过,原因你懂的。对象命名的好坏程度直接反应了一个码农编程水平的高低程度,对我来说,命名是任何一个人的基本功,可不仅仅是程序员的基本功。
  我记的一个牛叉的程序员曾经说过,好的程序,每个变量,函数,类的名字都非常讲究,整体搭配的也都非常合适,阅读这样的程序,就像阅读一篇优美的散文一样,让人赏心悦目
  我想任何人都到下面两种代码的感觉都不一样:
// Bad
var s = "Frank";
 
// Good
var usr_name = "Frank";
// or
var usrName = "Frank";

  上面不推荐的那种写法对于for循环中的循环变量int i来说问题还好,大家已经约定俗成了。如果放到一般的变量上,这种做法就不是太好了。

  当然了这种代码通常不是一次写就的,优秀的程序员开始写的程序也都可能像狗屎一样,不过他们高人一筹的地方就在于代码能工作之后,他们不会停下来,而是不断的打磨自己的代码,让它们简单,易懂,灵活