Code Smell: Mutation : 突变

问题概述

在Java中,默认情况下很多东西是可变的.

  • 类的字段导致对象状态是可变的
  • 方法的参数/局部变量可以重复赋值
  • 集合容器的内容可变

这些可变性,导致方法的逻辑复杂性很难理解并限制了并发性.

症状

  • 对变量不只一次赋值
  • 修改方法参数的状态(重新赋值,或修改对象内部状态)
  • 为改变参数内容而传递包装类型(例如:StringBuilder,可变的集合等等)
  • 由于代码中有多个原始类型变量被更新,导致很难做方法提取重构
  • 使用计数器或布尔类型变量跟踪分支代码的状态变更

可能的解决方案

  • 如果代码在从一个集合或数组中读取内容的同时修改它,那最好使用另外一个数组或集合来跟踪变更的内容,保持原始的数组或集合内容不变.同时读写一个集合会导致意外的结果,并带来并发问题.
  • 如果很难解释一个变量的值是在哪个分支中被赋予的,那么最好用多个具有良好命名的变量,而不是重用同一个.又或者将变更变量的代码拆分为多个小方法,从而将变更限制在小段代码中.
  • 方法最好使用返回值来向调用者传递消息,而不是通过修改输入参数对象告知调用者自己的结果.如果需要传递的信息比较复杂,可以声明一个包装类来维护所有需要返回的信息.
  • 如果方法中使用了计数器或布尔类型变量来跟踪状态,那么最好将这类变量移动到合适的业务领域对象中,以便于方法可以进行简单的重构.