第四章 两人合作

4.1 代码规范

  代码规范可以分成两部分:

    1.代码风格规范。主要是文字上的规定,看似表面文章,实际上非常重要。

    2.代码设计规范。牵涉到程序设计、模块之间的关系、设计模式等方方面面的通则。

4.2 代码风格规范

  代码风格的原则:简明,易读,无二义性

  代码风格规范:1.缩进:最好用四个空格;

           2.行宽:行宽必须限制,可以限定为100字符;

         3.括号:在复杂的条件表达式中,用括号清除地表示逻辑优先级;

         4.断行与空白的{}行;

         5.分行:不要把多条语句放在一行上。并且不要把多个变量定义在一行上;

         6.命名;

         7.下划线;

         8.大小写:Pascal —— 所有单词的第一个字母都大写。

                               Camel —— 第一个单词全部小写,随后单词随Pascal形式。

                               所有的类型/类/函数名都用Pascal形式,所有的变量都用Camel形式。

                               函数中get/set中例外。

         9.注释:不要注释程序是怎么工作的(How),程序本身就应该能说明这一问题。

                            注释是为了解释程序做什么(What),为什么这样做(Why),以及要特别注意的地方。

                            复杂的注释应该放在函数头,很多函数头的注释都用来解释参数的类型等,如果程序正文已经能够说明参数的类型in/out,就不要重复。

                            注释要随着程序的修改而不断更新,一个误导(Misleading)注释往往比没有注释更糟糕。

                            注释(包括所有源代码)应该只用ASCII字符。

4.3 代码设计风范

  代码设计规范不光是程序书写的格式问题,而且牵涉到程序设计、模块之间的关系、设计模式等方方面面。

  代码设计风范:1.函数:现代程序设计语言中的绝大部分功能,都在程序的函数(Function、Method)中实现。关于函数最重要的原则是:只做一件事,并且要做好。

         2.goto:函数最好有单一的出口,为了达到这一目的,可以使用goto。只要有助于程序逻辑的清晰体现,什么方法都可以使用,包括goto。

         3.错误处理:参数处理和断言。

         4.如何处理C++中的类:如何处理C++中的类:如果只是数据的封装,用struct即可、公共/保护/私有成员、数据成员、虚函数、构造函数、析构函数new 和delete、运算符、异常、类型继承。

4.4 代码复审

  代码复审形式:

    1.自我复审:自己vs.自己,用同伴复审的标准来要求自己。不一定最有效,因为开发者对自己总是过于自信。如果能持之以恒,则对个人有很大好处。

    2.同伴复审:复审者vs.开发者,简便易行。

    3.团队复审:团队vs.开发者,有比较严格的规定和流程,适用于关键代码,以及复审后不再更新的代码。覆盖率高——有很多双眼睛盯着程序,但效率可能不高(全体人员都要到会)。

  代码复审的目的:1.找出代码的错误,比如:a.编码错误,比如一些碰巧骗过了编译器的错误;b.不符合团队代码规范的地方

          2.发现逻辑错误,程序可以编译通过,但是代码的逻辑是错的

          3.发现算法错误,比如使用的算法不够优化,边界条件没有处理好等

          4.发现潜在的错误和回归性错误——当前的修改导致以前修复的缺陷又重新出现

          5.发现可能需要改进的地方

          6.教育(互相教育)开发人员,传授经验,让更多的成员熟悉项目各部分的代码,同时熟悉和应用领域相关的实际知识

  为什么要做代码复审:人不可能不犯错误;让新工能更快的熟悉代码,快速融入到团队当中。

  代码复审的步骤:1.代码必须成功地编译,在所有要求的平台上,同时要编译Debug|Retail版本。编译要用团队规定的最严格的编译警告等级(例如C/C++中的W4)

          2.程序员必须测试过代码。

          3.程序员必须提供新的代码,以及文件差异分析工具。

          4.复审者可以选择面对面的复审、独立复审或其他方式。

          5.在面对面的复审中,一般是开发者控制流程,讲述修改的前因后果。但是复审者有权在任何时候打断叙述,提出自己的意见。

          6.复审者必须逐一提供反馈意见。注意,复审者有权提出很多看似吹毛求疵的问题,复审者不必亲自调查每一件事,开发者有义务给出详尽的回答。

          7.开发者必须负责让所有的问题都得到满意的解释或解答,或者在TFS中创建新的工作项以确保这些问题会得到处理。

          8.对于复审的结果,双方必须达成一致的意见。

           (1)打回去——复审发现致命问题,这些问题在解决之前不能签入代码。

           (2)有条件地同意——发现了一些小问题,在这些问题得到解决或记录之后,代码可以签入,不需要再次审核。

           (3)放行——代码可以不加新的改动,签入源码控制服务器。

  程序员不能两次犯同样的错误。在代码审核后,开发者应该把复审过程中的记录整理出来:

    1.更正明显的错误。

    2.对于无法很快更正的错误,要在项目管理软件中创建Bug把它们记录下来。

    3.把所有的错误记录在自己的一个“我常犯的错误”表中,作为以后自我复审的第一步。

  代码复审的核查表:

    1. 概要部分

      (1)代码符合需求和规格说明吗?

      (2)代码设计是否考虑周全?

      (3)代码可读性如何?

      (4)代码容易维护么?

      (5)代码的每一行都执行并检查过了吗?

    2. 设计规范部分

      (1)设计是否遵从已知的设计模式或项目中常用的模式?

      (2)有没有硬编码或字符串/数字等存在?

      (3)代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到Win64)

      (4)开发者新写的代码能否用已有的Library/SDK/Framework中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现?

      (5)有没有无用的代码可以清楚?

     3. 代码规范部分

       修改的部分符合代码标准和风格吗?

    4. 具体代码部分

      (1)有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常?

      (2)参数传递有无错误,字符串的长度是字节的长度还是字符的长度,是以0开始计数还是以1开始计数?

      (3)边界条件是如何处理的?switch语句的default分支是如何处理的?循环有没有可能出现死循环?

      (4)有没有使用断言(Assert)来保证我们认为不变的条件真的得到满足?

      (5)对资源的利用,是在哪里申请,在哪里释放的?有无可能存在资源泄露?有没有优化的空间?

      (6)数据结构中有没有用不到的元素?

    5. 效能

      (1)代码的效能(Performance)如何?最坏的情况是怎样的?

      (2)代码中,特别是循环中是否有明显可优化的部分?

       (3)对于系统和网络的调用是否会超时?如何处理?

     6. 可读性

       代码可读性如何?有没有足够的注释?

     7. 可测试性

       代码是否需要更新或创建新的单元测试?

  如何正确的给予反馈:

    1. 最外层:行为和后果

    2. 中间层:习惯和动机

    3. 最内层:本质和固有属性

 

 

      

 

 

 

 

 

 

 

posted @ 2017-05-14 11:36  时过境迁zZ  阅读(93)  评论(0编辑  收藏  举报