一个函数中源代码不超过30行
这个建议的原始意义在于使一个函数能够在显示器上完全显示。而多数的显示器大约就只能显示30行源码。
遵循这一建议后,我们将会发现一个问题,虽然单个函数的可读性提高了,但是代价是为了分散源码而不得不产生大量的一次性的函数。这些一次性的函数不光使程序整体变得凌乱,在IDE中还会占用掉大纲空间。总体上看,提高单个函数的可读性而使工程更混乱并不可取。最初提出此建议的人,在当时的历史背景下,他所看到的工程是结构简单、功能单一的程序,甚至于一个进程只是为了进行一个数学运算。然而软件技术发展至今,一个工程往往带有非常多功能、大量的线程、详细的层次关系、各种第三方程序包。这一建议显然不能适用于所有的情况。
一个工程中可见的代码可以分为工具、平台、架构、业务四个层次。
工具层提供基础的驱动、算法、容器、资源管理,只要所用的编程语言不过时,工具层可以永久使用,另外,相关编程语言的第三方组件和API都属于工具层。
平台层提供前后端引擎,支撑起一个事件空间,提供原始的人机接口支持,将网络计算机进行关联。Tomcat、MFC、Qt都属于平台层。MFC本身也有提供几种原始架构。
架构层用于定义业务流程和人机接口的形态,定义一个软件所支持的业务方向。架构层与业务方向有较强的关联,细节上常常需要定制,这也就是为什么已经有了MCV的思路还是需要大量的架构师去参加工程的原因。因为MCV只是一种理论,每一套业务都需要对应的实例。这就导致了架构师有做不完的工作。
业务层用于定义业务流程中每一个环节的功能、与其他环节的关系。对于商务办公方向的业务层,代码常常是非常相近,但又有少量变更,商务办公的主要难点在于大量的画面需要定制和大数据响应性太慢。对于工业自动化方向的业务层,定制程度较高,需要结合声/光/热/电/气/液/刚/柔联合传动进行定制,工业自动化的主要难点在于抵御系统外的干扰和零部件损耗补偿。
其中的工具、平台两个层次需要长期整体维护,对于这些需要长期整体维护的代码,整体结构的清晰度要比局部结构的清晰度更重要。工具和平台层的细节往往不需要持久的维护,一套局部代码通常在两年内可以达到最终版本。因此,在工具和平台两个层次上,建议尽可能减少文件、类、函数的个数。尽可能地使用内部类、匿名类、匿名函数、代码块、局部宏以减少可见标签的数量和作用域。
架构层是为了某些业务定制流程规范的代码、生命周期相对较短,整体尺度不大,为了良好地支持业务层的发展,可以考虑对局部进行优化。业务层本身不具有整体性,也就不需要考虑减小可见标签的问题,只需要做好细节的处理就够了。在架构层和业务层上,可以考虑用函数名来代替注释的可能性,以减小工作量。因此,建议使架构层和业务层的粒度稍小一点,大约30行是一个不错的选择。
注释尽可能详细 vs 尽量减少注释
关于注释应该详细还是简约是一个无理取闹的问题。事实上,不论注释得多么详细,别人也一样看不懂你的代码。注释主要还是为了自己。
一个推荐的方法是当你觉得需要有注释的时候才去写注释。这样可以避免大量的无用注释。当你发现曾经的代码开始看不懂了的时候,就可以去加注释了。
注释是一个笔记,你可以记录一个算法的理论依据、参考文献、要感谢的人、操作步骤分解等你觉得有用的东西。就算是一个不起眼的感谢注释,也许在将来的某一天,你需要求助的时候也会派上大用场。而操作步骤也许并不重要,因为就算看了操作步骤也同样有可能无法理解为什么非得要按这个步骤。
代码缩进和命名格式要统一
这一规定通常是用于一个文件有多人修改的情况下,如果没有统一的格式,文件就会看起来很混乱。
进一步地,它的目的在于对不合理的事件合理化。不知道是谁引发的多人修改同一个文件的思想。试想,某一天软件出现问题的时候,这个部分是谁负责的?这一天操作过这一部分代码的人有三个,操作过这一文件但没有操作过这部分代码的人有六个,但他们同样有嫌疑。于是就要清查修改记录来定罪。清查后发现是同步服务器的同步过程发生冲突造成的,谁都没有错。
安全的做法是责任要明确,你在工厂里面绝对看不到一个零件会有两套班组进行安装的。这是谁的工单就由谁去完成,不然工资的分配就会失去依据。同理,软件开发的过程中,一个块只能有一个负责人。他只需要按调用者的规范定义接口,被接口封装过的内部构造完全没有必要统一。另外,每个类型都应该有单一的文件、每个类型中的成员都应该有唯一的维护人员进行管理,以避免代码同步冲突。
更进一步地,层次、业务的职责应该分离,避免由于一个业务模块变更导致另一个业务模块的程序员也要配合做调整。底层的接口应避免在工程中变更。技术开发与业务开发应是异步进行的。新接口不可以用到已在进行中的项目上,也要避免对底层进行更新,否则由于技术开发导致的变更会使整个工程都要大规模地调整。