代码质量评价标准
如何评价代码质量的高低?
标准多,带有主观性,无法用单一标准来评判,需要总合各个维度
如何才能写出高质量的代码?
设计思想
设计原则
设计模式
编码规范
重构技巧
重构概述
为什么重构?
保持代码质量持续处于一个可控状态,不至于腐化到无可救药的地步
重构什么?
大规模高层次的重构
内容:对代码分层、模块化、解耦、梳理类之间的交互关系、抽象复用组件
理论基础:设计思想、原则、模式
小规模低层次的重构
内容:规范命名、注释、修正函数参数过多、消除大类、提取重复代码等编程细节问题,主要是针对类、函数级别的重构
理论基础:编码规范
什么时候重构?
建立持续重构意识,把重构作为开发必不可少的部分融入到开发中
如何重构?
大规模高层次的重构
难度比较大,需要组织、有计划地进行,分阶段地小步快跑
小规模低层次的重构
影响范围小,改动耗时短,随时随地可以做
单元测试
什么是单元测试?
概念:代码层面的测试,用于测试“自己”编写的代码的逻辑的正确性
“单元”:一般是类或函数,而不是模块或者系统
为什么要写单元测试?
能有效地发现代码中的Bug、大妈设计上的问题
写单元测试的过程本身就是代码重构的过程
大暖测试是针对集成测试的有力补充,有利于快速熟悉代码,是TDD可落地执行的这种方案
如何编写单元测试?
概念:针对代码设计覆盖各种输入、异常、边界条件的测试用例,并将其翻译成代码的过程
方法:可以利用一些测试框架来简化测试代码的编写
5个正确的编写认知
1、编写单元测试尽管繁琐,但并不是太耗时
2、可以稍微放低单元测试的质量要求
3、覆盖率作为衡量单元测试好坏的唯一标准是不合理的
4、写单元测试一般不需要了解代码的实现逻辑
5、单元测试框架无法测试多半是代码的可测试性不好
单元测试为何难落地执行?
写单元测试本身比较繁琐,技术挑战不大,很多程序员不愿意去写
国内研发比较偏向快猛糙,容易因为开发进度紧,导致单元测试的执行虎头蛇尾
没有建立对单元测试正确的认识,觉得可与可无,单靠督促很难执行得很好
代码的可测试性
什么是代码的可测试性
针对代码编写单元测试的难易程度
依赖注入是编写可测试性代码的最有效手段
依赖注入可通过mock的方法将不可控的依赖变得可控
除了mock方式,还可以利用二次封装来解决某些代码行为不可控的情况
常见的5种Ant-Patterns
1、代码中包含未决行为逻辑
2、滥用可变全局变量
3、滥用静态方法
4、使用复杂的继承关系
5、高度耦合的代码
大型重构:解耦
“解耦”为何如此重要?
保证代码松耦合、高内聚,是控制代码复杂度的有效手段
代码高内聚、松耦合,也就是代码结构清晰、分层、模块化合理、依赖关系简单、模块或类之间的耦合小,代码整体的质量就不会差
代码是是否需要“解耦”
间接的衡量标准
改动一个模块或者类的代码受影响的模块或者类的是否由很多
改动一个模块或者类的代码,依赖的模块或者类是否需要改动
代码的可测试性是否好
直接的衡量标准
把模块与模块之间及其类之间的依赖关系画出来,根据依赖关系图的复杂性来判断
如何给代码“解耦”?
封装与抽象
中间层
其他设计思想与原则
单一职责原则
基于接口而非实现编程
依赖注入
多用组合少用继承
迪米特法则
设计模式
小型重构:编码规范(20条)
命名注释
1、命名的关键是能准确达意
2、借助类的信息来简化属性、函数的命名,利用函数的信息来简化函数参数的命名
3、命名要可读、可搜索,不要使用生僻的、不好读的英文单词
4、接口的2中命名方式:在接口中带前缀“I”;在接口的实现类中代后缀“Impl”。抽象类的2种命名方式:带上“Abstract”;不带前缀
5、注释的内容:做什么、为什么、怎么做。复杂的类和接口,还要写明“如何用”
6、类和函数一定要写注释,而且要写得尽可能全面详细
代码风格
7、函数的代码行数不要超过一屏幕的大小,比如50行
8、一行代码最好不要超过IDE的显示宽度
9、善用空行分割代码快
10、推荐两格缩进,节省空间。一定不要用tab缩进
11、将大括号跟上一语句同一行,可以节省代码行数。另起一行,结构清晰
12、在Googel java编程规范中,依赖类按照字母序从小到大排列。类中先写成员变量后写函数。成员变量之间或函数之间,先写静态成员变量或函数,后写普通变量或函数,并且按照作用域的大小依次排列。
编程技巧
13、将复杂的逻辑提炼拆分成函数或类
14、通过拆分成多个函数或将参数封装为对象的方式,来处理参数过多
15、函数中不要使用参数来做代码执行逻辑的控制
16、函数设计要职责单一
17、移除过深的嵌套层次
18、用字面常量取代魔法数
19、用解释性变量来解释复杂表达式
20、团队或项目要制定统一的编码规范,code review督促执行