目标,编写高质量的代码,本章节只介绍在易读性、易维护性和可靠性方面的最基本的代码设计方法~
一.设计易读的代码
如果编写的代码易读性不好,在维护阶段的多次阅读过程中,将会消耗维护人员大量的精力;研究实验表明,维护时间大部分都花费在了程序阅读和理解上,出于个体和团队两方面的度量,都应该将易读性作为首要质量标准~
1.格式
最基本的要求:代码的布局能够清晰地体现程序的逻辑结构~
- 使用缩进与对齐表达逻辑结构
- 将相关逻辑组织在一起
- 使用空行分割逻辑
- 语句分行
2.命名
- 使用有意义的名称进行命名,比如名称要与实际内容相符、使用动词或者动词+名词命名函数和方法,此外返回值和参数的命名也要合适
- 名称要与实际内容相符
- 如果存在惯例,命名时要遵守惯例
- 临时变量命名要符合常规(比如for循环内的控制参数)
- 不要使用太长的名称
- 不要使用易混字符进行命名,不利于拼写和记忆
- 不要使用易混字符进行命名,如“I”和“1”
- 不要仅仅使用不易区分的多个名称
- 不要使用没有任何逻辑的字母缩写进行命名
3.注释
文档注释:
(1)注释类型:如果组织得当,代码注释本身就是一份非常好的代码文档
- //:语句注释
- /* */:标准注释
- /** */:文档注释
(2)文档注释的内容与格式:包的总结与概述、类和接口的描述、类方法的描述、字段的描述等
(3)javadoc:方便注释文档化代码的工具:
内部注释:
- 注释要有意义,不要简单重复代码的含义
- 重视对数据类型的注释
- 重视对复杂控制结构的注释
二.设计易维护的代码
易读是易维护的必要前提,只有理解了程序代码,才能正确地修改程序代码~
1.小型任务
要让程序代码可修改,就要控制代码复杂度,要求每个函数或者方法的代码应该是内聚的,恰好完成一个功能与目标~
如果内聚的代码比较复杂,典型表现是完成一个功能需要多个步骤、代码比较长,那么就需要将其进一步分解为多个高内聚、低耦合的小型任务~
究其根本,小型任务有更好可维护性的原因是,通过将不同的代码片段抽象为不同的任务接口,可以解决复杂代码的集中不理想但无法回避的内聚——时间内聚、过程内聚and通信内聚~
2.复杂决策
代码中的业务规则是最容易发生修改的地方之一,表现为对代码中复杂决策的修改,所以,在编程中要注意对复杂决策的处理~
- 引入新的布尔变量简化复杂决策:过于复杂的决策可以引入布尔值(本质上可以理解为换元)
- 使用有意义的名称封装复杂决策:避免给不掌握相关信息的维护人员带来困难
- 表驱动编程:将复杂的决策封装为决策表
3.数据使用
- 不要将变量应用于与命名不相符的目的
- 不要将单个变量用于多个目的
- 限制全局变量的使用
- 不要使用突兀的数字与字符
4.明确依赖关系
类之间模糊的依赖关系会影响到代码的理解与修改,非常容易导致修改时产生未预期的连锁反应,对于模糊的依赖关系,需要进行明确的注释~
三.设计可靠的代码
提高代码可靠性的方法往往会降低底阿妈的易读性和性能,也可能牺牲易维护性,所以只有针对那些可靠性比较重要的代码才会采用提高可靠性的方案~
1.契约式设计
一个函数或者方法在前置条件满足的情况下开始执行,完成后又能够满足后置条件,那么这个函数或者方法就是正确的、可靠的~
- 异常方式:在代码执行时,检查前置条件是否满足,如果不满足就抛出异常
- 断言方式:java中的断言语句:assert Expression
(复杂系统中不推荐使用断言方式,异常方式灵活的多)
2.防御式编程
在一个方法与其他方法、操作系统、硬件等外界环境交互时,不能确保外界都是正确的,所以要在外界发生错误时,保证方法内部不受损害~
四.使用模型辅助设计复杂代码
需求开发可以使用分析模型建模复杂业务与需求,软件设计可以使用模型分析与验证复杂设计方案,编程也可以使用一些模型方法帮助设计复杂代码~
1.决策表
一种决策逻辑的表示方法,用于描述复杂决策逻辑~
- 条件声明:进行决策时需要参考的变量列表
- 条件选项:那些变量可能的取值
- 行动声明:决策后可能采取的动作
- 行动选项:动作会在怎样的条件下发生~
2.伪代码
结合了编程语言和自然语言的特点,结合使用程序语言的逻辑结构和自然语言的表达能力描述程序逻辑~
优点在于,不是编程语言因此不会存在语法问题,不需要担心意思表达是否符合语言规范,可以非常容易地反复修改——好处在于程序员可以从编程语言的细节脱离出来,专项考虑程序逻辑,反复推敲代码质量~
3.程序流程图
很在在结构化编程中使用的模型手段,现在也经常被用来表现和分析程序结构~
五.为代码开发单元测试用例
1.为方法开发测试用例
主要使用两种线索:方法的规格+方法代码的逻辑结构~
2.Mock Object测试类放方法
创建桩程序,以将被测试方法独立出来
3.为类开发测试用例
除了测试类的每一个方法之外,还要测试类不同方法之间相互影响的情况~
六.代码复杂度度量
衡量圈复杂度的基本思路是计算程序中独立路径的最大数量:
建立程序的流程图G,假设图的结点数为N,边数为E,则复杂度V(G)=E+N-2