【发布时间】:2015-08-30 01:00:49
【问题描述】:
我正在编写一个 Java 类来管理包含 Cell 对象的十六进制映射 (class GameMapImpl implements GameMap)。单元格对象保存在HashMap<Hex,Cell> 中,其中键是十六进制图上的位置。
过去,cell 和 GameMap 之间的耦合非常紧密,两者之间存在循环依赖关系,但我正在尝试对其进行重构,以便更轻松地进行测试。
(以下代码已简化)
public interface GameMap {
void hasCell(Hex hex);
void getCell(Hex hex);
}
class GameMapImpl implements GameMap
{
private Map<Hex, Cell> cellMap;
GameMapImpl(Set<Cell> cells) {
cellMap = new HashMap<>();
for (Cell cell : cells) {
// check some conditions on the cells
// ensure the map is correct, e.g. only one cell
// of a particular type
// ensures that the cellMap key is always the cell's position.
cellMap.put(cell.position(), cell);
}
}
//obvious implementation for hasCell and getCell methods
}
每个Cell 都需要有一个Hex position 字段,以便它可以在GameMap 中查找自己的位置。此外,Cell 对象需要引用拥有的GameMap,才能执行常见的有用操作,例如寻找邻居。
public class Cell {
final Hex position;
final GameMap gameMap;
Cell(Hex position, GameMap gameMap) {
this.position = position;
this.gameMap = gameMap;
}
public Set<Cell> getNeighbours() {
//perform operation that needs both gameMap and position
}
}
GameMap 内置在 GameMapBuilder 中,它为 GameMap 构造函数提供了一个 Set<Cell>。
public class GameMapBuilder {
public GameMap build(...) { // args omitted for simplicity
Set<Cells> cells = new HashSet<>();
for (... : ...)
{
Hex position = calculatePosition(...);
Cell cell = new Cell(position, gameMap);
}
GameMap gameMap = new GameMap(cells);
return gameMap;
}
}
您可能会看到,最后一个 sn-p 代码是错误的,因为我引用了一个不存在的 gameMap 变量。这是我的问题:如果我在初始化单元格后创建GameMap,我不能在Cell 的构造函数中传递它。如果我反其道而行之,我将无法将 Set<Cells> 传递给 gameMap 以正确初始化。
有没有经验丰富的程序员知道如何正确解耦这两个类?
或者,我可以回到之前的紧密耦合设计,并假设 Cell 仅在 GameMap 创建它们时才存在。作为这些小物件并包含在同一个包装中,这没什么大不了的。
【问题讨论】:
标签: java dependency-injection dependencies circular-dependency decoupling