Everybody wants go to heaven, but nobody wants to die.

重构 标签

整理自《编写高质量代码:改善Java程序的151条建议》

一、Java开发中通用的方法和准则

  • 不要在常量和变量中出现易混淆的字母;
  • 莫让常量蜕变成变量;
  • 三元操作符的类型务必一致;
  • 避免带有变长参数的方法重载;
  • 别让null值和空值威胁到变长方法;
  • 覆写变长方法也要循规蹈矩;
  • 警惕自增的陷阱;
  • 不要让旧语法困扰你;
  • 少用静态导入;
  • 不要在本类中覆盖静态导入的变量和方法;
  • 养成良好习惯,显式声明UID;
  • 避免用序列化类在构造函数中为不变量赋值
  • 避免为final变量复杂赋值;
  • 使用序列化类的私有方法巧妙解决部分属性持久化问题;
  • break万万不可忘;
  • 易变业务使用脚本语言编写;
  • 慎用动态编译;
  • 避免instantceof非预期结果;
  • 断言对决不是鸡肋;
  • 不要只替换一个类;

二、基本类型

  • 使用偶判断,不用奇判断;
  • 用整数类型处理货币;
  • 不要让类型默默转换;
  • 边界,边界,还是边界;
  • 不要让四舍五入亏了一方;
  • 提防包装类型的null值;
  • 谨慎包装类型的大小比较;
  • 优先使用整型池;
  • 优先选择基本类型;
  • 不要随便设置随机种子;

三、类、对象及方法

  • 在接口中不要存在实现代码;
  • 静态变量一定要先声明后赋值;
  • 不要覆写静态方法;
  • 构造函数尽量简化;
  • 避免在构造函数中初始化其他类;
  • 使用构造代码块精炼程序;
  • 使用静态内部类提供封装性;
  • 使用匿名类的构造函数;
  • 匿名类的构造函数很特殊;
  • 让多重继承成为现实;
  • 让工具类不可实例化;
  • 避免对象的浅拷贝;
  • 推荐使用序列化实现对象的拷贝;
  • 覆写equals方法时不要识别不出自己;
  • equals应该考虑null值情景;
  • 在equals中使用getClass进行类型判断;
  • 覆写equals方法必须覆写hashCode方法;
  • 推荐覆写toString方法;
  • 使用package-info类为包服务;
  • 不要主动进行垃圾回收;

2019-12-31 0 评论 194 浏览
阅读全文

  • 尽可能使用局部基本数据类型变量。
  • 及时关闭流。
  • 尽可能多使用三目运算符,代码看起来会比较清晰
  • 尽量减少对变量的重复计算。
  • 尽量采用懒加载的策略,即在需要的时候才创建。
    如果已知列表的长度,为底层以数组方式实现的集合、工具类指定初始长度。
  • 基于效率和类型检查的考虑,应该尽可能使用Array,无法确定数组大小时才使用ArrayList。
  • 当复制大量数据时,使用System.arraycopy()命令。
  • 乘法和除法可以使用移位操作进行优化。除非所需性能要求高,不然不必用移位来进行优化。例如我们平常的业务开发使用移位进行优化,反而使得代码的可读性降低。
  • 接口中的方法、属性尽量不要加任何访问修饰符。依据Alibaba的java代码规范。
  • 不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。
  • 在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;在一个switch块内,都必须包含一个default语句并且放在最后,即使它什么代码也没有。
  • 尽量使用HashMap、ArrayList、StringBuilder,除非线程安全需要,否则不推荐使用Hashtable、Vector、StringBuffer,后三者由于使用同步机制而导致了性能开销。
  • 不要将数组声明为public static final。否则不管这个数组有没有使用大,JVM都会为这个数组保留内存空间。
  • 尽量在合适的场合使用单例。
  • 尽量避免随意使用静态变量。

2019-12-30 0 评论 47 浏览
阅读全文

之前读完《重构,改善代码既有设计》一书,书中内容虽然简单,但却有效。一些小小的重构积累起来便使得我们的代码开始变得更优雅。印象很深的是作者倡导的事不过三的原则,代码出现三次重复即需要进行重构。我深有体会,经常觉得自己的某些设计不好,但是又跟自己说下次再一起重构吧?结果日复一日需要重构的设计越来越多,导致重构的成本越高,越不敢重构。这篇文章再温习一下重构一书中的内容。

尽信书不如无书。书中只是建议并非标准,有些时候我们需要具体情况具体分析。

代码的坏味道

1. 重复代码

重复代码意味着冗余,当重复的代码需要修改时要修改所有重复的地方,稍微疏忽便会出现bug。

2. 过长函数

当函数过长时,人很难一下掌握太多的细节,使得修改这个函数的成本很高。

3. 过大的类

单个类承担的责任过多,违反单一职责而形成过大的类。

4. 过长的参数列

长的参数列简直是噩梦,因为稍有不慎将类型相同的参数填错顺序就引发Bug了。(好在IDEA编译器能对填入的每个参数提示参数名)

5. 发散式变化

就是类受多个变化的影响,是违反迪米特法则的结果。类应该尽可能少的与其他类打交道,避免非必要的关联。

6. 霰弹式修改

单个变化引发多个类的相应修改。

7. 依恋情节

当一个类的行为严重依赖其他类的时候,我们需要思考这个行为真正的归属。

8. 数据泥团

两个类中相同的字段或者方法签名中相同的参数总是一起出现,可能这些字段可以自成一类。

9. 基本类型偏执

此基本类型并不是指int、long这类,而是指类中出现很多小字段,比如省、市、区、住址可以封装成一个地址对象作为User类中的一个属性。

10. Switch问题

当出现Switch重复时,同样的Switch散布在不同的地方,增加一个新的case,需要找到所有Switch进行增加。

11. 平行继承体系

每当你为某个类增加一个子类,必须也为另一个类相应增加一个子类。

12. 夸夸奇谈的未来性

过度设计。

13. 冗赘类

用处微乎其微以致于不如不作为一个类。或者作为内部类。

14. 令人迷惑的临时字段

类中的某些字段仅为特殊情况而定,或者类中的字段仅为了某个函数的方便声明为成员变量而没有其他用处。

15. 过度耦合的调用链

一个对象向另一个对象发起一个请求,再由另一个对象请求其他对象。

16. 中间人

无用的委托,过多中间层。

17. 狎昵关系

两个类关系过于紧密。一个类过于关注另一个类的成员,使得高耦合。

18. 异曲同工的类

不同的类或者函数,做着相同的事。

19. 不完美的类库

类库不能满足实际开发需求。

20. 纯数据类

类似于DDD中所阐述的贫血模型,仅有数据没有行为的类。

21. 被拒绝的遗赠

子类继承了父类不必要的函数或者数据。

22. 过多的注释

过多的注释说明代码的自解释能力很差。需要重构。


2019-12-30 0 评论 208 浏览
阅读全文