将Map的键存入对应value对象是否属于合理设计范式?
关于Map键冗余存入Value对象的设计问题解答
设计合规性
这种设计完全合规,也是工业界非常常见的实践,不存在原则性的设计错误。它的优势非常明显:
- 无需在业务逻辑中额外传递Map键与对应的Value对象,从Map中取出Value后直接就能从对象属性获取主键,大幅简化调用链的参数传递
- Value对象脱离Map上下文后依然可以独立使用,不会出现拿到数据却无法匹配对应主键的场景
- 可通过比对Map键和Value内存储的主键,快速排查数据写入逻辑的错误
当然这种设计也存在两个微小的弊端:
- 存在极小的数据冗余,会额外占用一点内存,对于UUID这类小对象而言基本可以忽略
- 如果没有统一的写入管控,可能出现Map键与Value内存储的主键不一致的问题,引发数据异常
更优实现方案
你可以根据自己的使用场景选择合适的优化方案:
- 如果Value对象几乎不会脱离Map上下文单独使用,不需要额外在Value内存储主键。需要同时获取键和值时直接遍历Map的EntrySet即可:
for (Map.Entry<UUID, PlayerData> entry : allPlayerData.entrySet()) { UUID uuid = entry.getKey(); PlayerData data = entry.getValue(); // 业务逻辑 } - 如果确定需要在Value内存储主键,务必对Map的写入逻辑做封装,禁止上层业务直接调用Map的put方法,从根源上避免数据不一致:
// 封装统一的写入方法 public void addPlayerData(PlayerData playerData) { allPlayerData.put(playerData.getUuid(), playerData); } - 如果你使用Java 8及以上版本,也可以用
computeIfAbsent原子方法实现写入,同时保证键值一致性:PlayerData playerData = allPlayerData.computeIfAbsent(uuid, id -> { PlayerData newData = new PlayerData(); newData.setUuid(id); // 其他属性初始化 return newData; });
内容的提问来源于stack exchange,提问作者Caleb Owens
相关产品推荐
相关产品推荐

