Code Smell: Mutation : 突变
问题概述
在Java中,默认情况下很多东西是可变的.
- 类的字段导致对象状态是可变的
- 方法的参数/局部变量可以重复赋值
- 集合容器的内容可变
这些可变性,导致方法的逻辑复杂性很难理解并限制了并发性.
症状
- 对变量不只一次赋值
- 修改方法参数的状态(重新赋值,或修改对象内部状态)
- 为改变参数内容而传递包装类型(例如:StringBuilder,可变的集合等等)
- 由于代码中有多个原始类型变量被更新,导致很难做方法提取重构
- 使用计数器或布尔类型变量跟踪分支代码的状态变更
可能的解决方案
- 如果代码在从一个集合或数组中读取内容的同时修改它,那最好使用另外一个数组或集合来跟踪变更的内容,保持原始的数组或集合内容不变.同时读写一个集合会导致意外的结果,并带来并发问题.
- 如果很难解释一个变量的值是在哪个分支中被赋予的,那么最好用多个具有良好命名的变量,而不是重用同一个.又或者将变更变量的代码拆分为多个小方法,从而将变更限制在小段代码中.
- 方法最好使用返回值来向调用者传递消息,而不是通过修改输入参数对象告知调用者自己的结果.如果需要传递的信息比较复杂,可以声明一个包装类来维护所有需要返回的信息.
- 如果方法中使用了计数器或布尔类型变量来跟踪状态,那么最好将这类变量移动到合适的业务领域对象中,以便于方法可以进行简单的重构.