"Clean Code(代码整洁之道)"的全书阅读对自己的启发,以及工作过程中编程风格方面一些浅显总结。不包含“并发编程”,“架构设计”这些方面的启发。
1 命名的建议
- ①见名知意,名副其实。
- ②类名,对象名:多用名词,名词短语。
- ③方法名:动词,动词短语。
- ④对命名可添加适当的语境:如:addFirstName();addLastName();中First,Last等语境。
- ⑤不用双关语:如Dao层,不用add()代替insert(),和update()二者的语义。而是建议用两个语义明确的insert(),和update()方法。
- ⑥添加适当的前缀或是后缀,并保持一贯的统一风格。如接口,接口的实现类。有的喜欢对接口做前缀标识,有的喜欢对实现类做后缀标识,保持一贯的统一风格。
- ⑦每个概念对应于一个词语,实质还是保持风格统一。如对方法命名,会遇到一些组装对象的方法,有的喜欢对方法命名build*(),有的喜欢用assemble*(),保持一致语义风格,每个概念对应一个词语,不要二者混用。
2 函数的建议
- ①一个函数应该只做一件事,做好一件事。
- ②函数的名称:长而具有描述性的名称,比短而令人费解的名称好。
- ③函数入参:函数的入参尽可能少,不建议超过3个;如果参数过多,考虑封装成对象作为方法如入参。
- ④避免标识参数:尽量避免向函数传入布尔值,作为标识参数。
- ⑤函数避免副作用:函数的副作用是指函数在调用过程中,除了给出返回值外,还修改了函数外部对象的状态,如调用过程中修改了某一个全局变量的状态。
- ⑥错误处理:建议如果关键字try在某个函数中存在,它就该是函数的第一个单词,而且在catch/finally代码块后面也不该有其它内容。
3 注释的建议
- ①尽量少写注释(注释不能美化糟糕的代码( • ̀ω•́ )✧,颠覆了之前思想),前提是你能确保代码的可阅读性很好。
- ②必要的注释有以下这些:
⑴法律信息,版权及著作声明等
⑵提供信息的注释,如注释一些抽象方法的入参类型,返回值等
⑶阐释,把某些晦涩难明的参数或返回值的意义翻译为某种可读的形式。如StringUtils工具类中的,isBlank(),isEmpty()方法的注释。
⑷警示信息。
⑸TODO注释,TODO是一种认为应该做,但由于某些原因目前还没有做的工作。
4 异常处理
- ①在编写可能抛出异常的代码时,最好先写出try-catch-finally语句。
- ②受检查异常违反了“开/闭原则”,建议在适当情况下,转换为“运行时异常”抛出。
- ③调用者,根据需要,对底层抛出的原始异常进行转换后再抛出。
- ④不建议返回null值。如果打算在方法中返回null值,或是调用第三方API可能返回null值的方法。建议抛出异常,或是返回包装后的特例对象进行替代。
- ⑤不建议传递null值。方法尽量避免传递null值。
5 单元测试建议
- ① 学习性测试是集成使用第三方API的快速方法。
- ②TDD(Test Driven Development)测试驱动开发
- ③ 整洁测试模式。把单元测试的过程拆分为清晰的3步。构造-操作-检查。第一个环节构造测试数据。第二个环节操作测试数据。第三个环节检验操作是否得到期望的结果。
- ④ 每个测试函数中只测试一个概念。
- ⑤ 整洁测试的"F.I.R.S.T原则"。
⑴快速(Fast),测试应该能够快速运行。
⑵独立(Independent)测试应该相互独立。某个测试不应该成为下一个测试设定的条件。
⑶可重复(Repeatable),测试应该在任何环境中重复通过。
⑷自足验证(Selt-Validating),测试的成功失败,最好输出一个布尔值,便于直观看到,而不是通过查看日志文件来判断是否通过。
⑸及时(Timely),及时编写单元测试。单元测试应该在成为生产代码之前编写。
6 其它建议
- ① SOLID原则:
⑴SRP The Single Responsibility Principle 单一责任原则(每个类封装一个权责,并与少数其它类一起协同完成功能。)
⑵OCP The Open Closed Principle 开放封闭原则
⑶LSP The Liskov Substitution Principle 里氏替换原则
⑷ISP The Interface Segregation Principle 接口分离原则
⑸DIP The Dependency Inversion Principle 依赖倒置原则(依赖抽象而不依赖具体,如继承抽象类,实现接口,都是把较高层级的概念放到基类中,把较低层级的概念和实现细节放到派生类中;如依赖注入[DI]把对象的构造是使用进行分离。)
- ② AOP面向切面编程
⑴Java动态代理
⑵Spring AOP
⑶AspectJ
- ③ 代码书写位置,垂直分离的风格。
⑴变量和函数应该在靠近被使用的地方定义。
⑵本地变量(方法中定义的变量),应该正好在其首次被使用的位置上面声明。垂直距离要短。
- ④ 恰当使用限制修饰符。不要为子类创建大量受保护的变量和函数。通过控制限制信息来控制耦合度。
- ⑤ 恰当使用静态方法。通常倾向于选用非静态的方法。如果确定使用静态方法,确保你不打算让它有多态行为。静态方法无法多态。
- ⑥不要规避“时序耦合”。有必要使用时序耦合,而不是规避它。排列函数参数,好让他们被调用的次序显而易见。
eg:
Bad Coding:
public class MoogDiver{
Gradient gradient;
List<Spline> splines;
public void dive(String reason)
{
saturateGradient();
reticulateSplines();
diveForMoog(reason);
}
...
}
Good Coding:
public class MoogDiver{
Gradient gradient;
List<Spline> splines;
public void dive(String reason)
{
Gradient gradient=saturateGradient();
List<Spline> splines=reticulateSplines(gradient);
diveForMoog(splines,reason);
}
...
}