应将混装异构数据的数组替换为对象。当数组各索引承载不同语义(如person[0]为姓名、person[1]为年龄)且需同步维护多处代码时,表明其已被当作弱类型结构体使用,此时适用Replace Array with Object重构;需分步实施:先建类封装数组、再引入语义化访问方法、最后以独立私有字段取代数组,并注意避免对纯同构集合或性能敏感路径滥用。

当一个数组里混着名字、数量、状态等不同含义的元素,靠记下标来读写,迟早出错。用对象取代数组,就是把这种“靠人脑记忆”的结构,换成靠字段名说话的清晰模型。
什么情况该动手换
数组本该装同类数据,比如一串数字、一组字符串。一旦它变成这样:
- person[0] 是姓名,person[1] 是年龄,person[2] 是入职年份
- row[0] 是球队名,row[1] 是胜场,row[2] 是负场
- 每次改数组长度,都得同步更新所有用到它的代码和注释
那就说明:这个数组已经不是容器,而是被当成“弱类型结构体”在用——正是 Replace Array with Object 的典型信号。
分步替换不踩坑
别一上来就删数组,按节奏走更稳:
- 先新建一个类(比如 TeamPerformance),里面放一个 public 数组字段暂存旧数据
- 把所有创建
String[] row = new String[3]的地方,替换成new TeamPerformance() - 为每个数组位置加带语义的访问方法:比如
getName()、getWins()、setLosses(int) - 把所有
row[0]、row[1]的调用,全改成走这些方法 - 确认全部跑通后,把数组字段设为 private,再逐个用独立字段(
private String name)替代数组索引 - 最后删掉那个数组字段
换完不只是字段名变了
对象带来的好处是渐进释放的:
- 字段命名直接表达意图,不再依赖注释或约定
- 可以加校验逻辑,比如
setWins(int w)拒绝负数 - 能自然封装行为,比如
isPlayoffEligible()判断是否进季后赛 - 后续加新字段(如“平局场次”“主场胜率”)不影响原有调用
注意两个关键边界
这个重构不是万能的,要避开两个常见误用:
-
别对纯同构集合用它:比如
double[] temperatures存一天10个温度值——这本来就是数组的正当用途,强行包一层TemperatureList反而啰嗦 - 别在性能敏感路径上盲目替换:高频循环里反复构造小对象可能带来 GC 压力,需结合实际 profile 决定

















