本文主要内容来自 SpriCoder的博客,更换了更清晰的图片并对原文的疏漏做了补充和修正。
设计易读的代码
- 维护的需要(维护的工作量已经超过了开发的工作量)
- 50%-90% 的维护时间在于阅读代码
- 团队协作的需要
代码规范
布局格式
- 用缩进与对齐表达逻辑结构(Python)
- 统一缩进格式一或者缩进格式二,主要符合团队编程的习惯即可
- IDEA 统一格式化:Ctrl + Alt + L

- 将相关逻辑组织在一起
- 成员变量声明
- 构造方法和析构方法
- public 方法
- protected 方法
- private 方法

逻辑组织清晰的代码

- 将空行分隔逻辑(将大规模的逻辑划分的片段进行分隔)

- 将语句进行分隔(将过长的语句分隔到几行中进行显示)

命名

注释


- 怎么写:去 Github 学习

- JavaDoc 可以生成 API 文档

- 例子:

- 类内部注释

- 例子

设计易维护的代码
小型任务

复杂决策
- 使用新的布尔变量,代替复杂决策

- 使用有意义的名称封装复杂决策

- 表驱动


数据使用

明确依赖关系
- 类之间模糊的依赖关系会影响到代码的理解与修改,非常容易导致修改时产生未预期的连锁反应。
设计可靠的代码重要
契约式设计
异常方式
- 代码会很臃肿

断言方式
- Java 提供的断言语句:
assert Expression1(: Expression2); - Expression1 是一个布尔表达式,在契约式设计中可以将其设置为前置条件或后置条件
- Expression2 是一个值,如果存在,则会在排除异常的时候作为参数沟改造 AssertionError


防御式编程

- 防御式编程往往会带来比较冗余和复杂的代码,但是会有效地提高程序的抗干扰能力和回复能力,有利于人机交互。
表驱动编程
- 复杂逻辑到决策表再到表驱动
使用模型辅助设计复杂的代码
- 决策表:多个 if/else
- 伪代码:在纸或者白板上
- 程序流程图
决策表
| 条件和行动 | 规则 |
|---|---|
| 条件声明 | 条件选项 |
| 行为声明 | 行为选项 |

- 决策表有效地保证了决策分析的完备性,可以和表驱动编程结合使用。
伪代码

- 结合课本详细的描述
- 使用了 IF、THEN、ELSE、DO、DO WHILE、DO UNTIL 等关键字来表示程序的逻辑组织。
- 通过类似编程语言的缩进方式来表明程序逻辑
- 使用尽可能短的语句,只是用名词和动词,避免使用容易产生歧义的形容词的使用
- 实例详见课本 P312 页
程序流程图

- 圆角:开始或者结束
- 平行四边形:输入或输出
- 直角:处理步骤
- 菱形:控制结构
为代码开发单元测试用例
为方法开发测试用例

- 测试驱动的编程
- 方便集成和开发
- 等价类进行划分和区别
- 覆盖方式:
- 路径覆盖
- 分支覆盖
- 语句覆盖
Sales 方法

- 使用桩程序代替没有写的方法
使用 Mock Object 测试类的方法


为类开发测试用例

- 我们使用状态图来辅助我们分析,通过状态图生成测试用例线索表,最后生成一个测试用例



代码复杂度度量

- 重要:这里涉及到两种计算方法


度量的意义

$类的加权方法 = \sum_{i-1}^{n}C_{i}$
代码大全(书)
变量
变量定义

变量初始化

- 使用内存访问工具来检查所有的指针的有效性。
作用域

- 生命周期越长越容易出现问题
减少作用域的一般原则

持续性


为变量制定单一用途

- 哪怕是临时变量也尽量避免重复使用。
两个变量用于两种用途

避免让代码具有隐含意义

变量的命名
- 一定要用规范的方式命名变量
数值理论

- 整数:
- 检查整数除法
- 检查整数溢出
- 检查中间结果溢出(浮点运算)

创建子程序的正当理由

子程序的命名

算法的设计

- 了解编译器的优化

一般控制问题



空语句

更加清晰的非空循环体

处理危险的深层嵌套

问题代码与建议
[Green 1997] How to Write Unmaintable Code








