代码整洁之道
1. 整洁的代码
-
整洁的代码只做一件事(单一职责原则)
-
没有改进的余地:尽量不要让别人抓住把柄,如果一段代码自己都不满意那就修改它,直到满意为止! 不要找不知道如何修改的借口
-
不要有重复的代码(提高分析和表达能力,消除重复)
2. 有意义的命名
-
名副其实:通过一个命名使得代码含义明确
-
避免二义性误导 :如
-
accountList 除非该变量是List类型
-
Map类型的变量命名为 xxxMapper (容易误解为mybatis中的mapper)
-
避免使用差别很小的名称,容易造成混淆
-
-
做有意义的区别,避免a1,a2 ,orderDTO , orderInfoDTO,不要为了区别而写一下废话
-
使用可以读出来的名称(方便识别记忆),比如缩写只使用通用的缩写
-
类名是名词或名词短语,方法名为动词或动词短语
-
避免同一个单词用于不同意义(数据库中命名也是如此)
3. 函数
-
短小
-
只做一件事:标准如下
-
不能再拆分
-
不能再被切分为多个区段
-
-
为函数取个有描述性的名称(可考虑将参数写入函数名:byxxx)
-
尽量少的参数 ,拒绝输出参数,如果需要转换参数请将其返回 如
-
String transform (String in);
-
如果需要的参数过多,封装参数
-
-
抽离
try/catch
代码,使得错误处理和正常流程分离(同理也可以将参数校验和逻辑代码抽离) -
消除重复,提高复用
4. 注释(解释代码不能自行解释的代码)
-
尽量可以用代码表达注释的内容(如果代码足够简洁易懂,也就没有写注释的必要了)
-
好的注释
-
解释意图而不去解释实现(代码即实现)
-
警示性注释
-
-
当你需要使用注释时多半是你需要修改打磨你的代码了
5. 格式
-
变量的声明,尽可能的靠近其使用的位置
-
调用则尽可以的放在别调用者上面
-
空格可达到强调和分隔的目的
6. 对象(操作方法)和数据结构(实体类)
-
不要将对象和数据结构混杂在一起,实体类中不要有业务方法
-
对象暴露行为,隐藏数据,便于新增新的数据类型(实体) 而无需修改现有行为。数据结构暴露数据,而无实际行为,这便于数据结构(实体)增加新行为
7.错误处理
-
不要让错误处理搞乱隐藏代码逻辑(业务逻辑)
-
使用异常:抛出异常时,提供足够的错误说明信息(堆栈跟踪,失败操作以及类型)
-
不要返回null(可尽量避免判空操作,和npe)
-
避免传递null
-
代码整洁既是可读也是坚固
8.边界(第三方框架)
-
学习性测试,编写测试来学习和理解第三方代码
9. 单元测试
-
快速运行
-
独立运行
-
可重复(在任何环境都可以运行)
-
自主验证
-
及时
-
步骤(方法)
-
构建参数
-
操作
-
得出什么样的结论
-
10. 类
-
尽量短小(权责尽量小),类名应该指出该类的权责
-
单一权责
-
内聚:如果一个类中每个变量都被每个方法使用到,当勒种出现只与类的一小部分有关的私有方法时,意味着改进空间(拆)
-
11. 系统
-
将构造逻辑(关注模块的划分)与运行(对象的创建与方法的操作)过程分离
-
依赖注入(由特定的容器来管理对象的生命周期)
-
将全部的构造过程抽取到特定的模块中,用于创建所需要的对象
-
工厂
-
-
恰当的切分关注面(合理的模块划分)方便后续的扩展
-
aop
-
-
代理
-
aspectJ
-
先有框架,再有实现,避免预先设计好一切实现,测试驱动架构
12. 跌进
-
消除重复
-
抽取相似代码
-
模板方法模式(小模块的重用)
-
-
测试至关重要
-
提升表达能力(清晰表达意图)
-
合适的命名
-
保持函数和类的短小
-
编写良好的单元测试
-
不断尝试修改和优化
-
13. 并发编程
-
防御并发代码问题的原则和技巧
-
单一权责(分离并发代码与其他代码)
-
限制数据作用域,限制对可能被共享的数据的访问
-
使用数据副本(可避免数据共享)
-
避免同步方法之间的依赖
-
保持同步区域微小(减少性能影响)
-
正确关闭代码(确保资源的释放)
-
-
线程代码的测试
-
不要把失败归因于偶发事件
-
先确保代码在单线程状态下是可用的(拆分任务,一步一步来)
-
运行多于处理器数量的线程(压力测试)
-
在不同平台上运行(不同操作系统有不同线程策略)
-
调整线程池大小,多次测试线程的创建,测试线程是否正常释放,是否会导致OOM
-
-
多线程造成代码指令的可执行路径增多,从而增加结构的不确定性(多线程的难点)
-
尽量了解内存模型:
-
什么地方有共享资源
-
哪些代码会导致并发读写问题
-
如何防止并发问题
-
-
了解java提供的并发编程库:如Executor
-
了解java中的非线程安全类
-
Servlet
-
集合类(非线程安全的集合类)
-
数据库连接类
-
-
死锁
-
死锁发生的条件
-
互斥:资源有限,且同一时间只能被一个线程所用
-
上锁以及等待:对以获取的资源上锁,对尚未获取的资源等待
-
无抢先机制:只能等待其他线程释放资源
-
循环等待:线程1 拥有 资源1 , 线程2 拥有 资源2,线程1 需要 资源2 , 线程2 需要 资源1
-
-
避免死锁
-
不互斥(不现实)
-
允许同时使用
-
增加资源数,使其大于竞争数
-
获取资源前,检验是否可用
-
-
不上锁及等待:如果获取不到某个被锁资源,是否所有资源,重新抢占
-
使用抢占机制:允许线程从其他线程上抢夺资源
-
-
这里只是总结性的概括了做到代码整洁,需要有的思想和技能,很多技能都是需要去学习补充,并且运用实践的。