我正在编写一个Java类来管理包含class GameMapImpl implements GameMap
个对象的十六进制映射(Cell
)。单元格对象保存在HashMap<Hex,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
,为Set<Cell>
构造函数提供GameMap
。
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;
}
}
正如您可能看到的,最后一段代码是错误的,因为我引用了一个不存在的gameMap
变量。这就是我的问题:如果我在初始化单元格后创建GameMap
,我无法在Cell
的构造函数中传递它。如果我反其道而行之,我无法将Set<Cells>
传递给gameMap
以便正确初始化。
有经验的程序员是否知道如何正确地解耦这两个类?
或者,我可以回到之前的紧耦合设计,并假设Cell只在GameMap创建它们时才存在。作为这些小物件并包含在同一个包装中,它不会是一件大事。
答案 0 :(得分:0)
我认为这里的问题是你使用了一个建设者。基本上你在构建器中所做的就是从GameMap
构造函数中取出代码。如果您要将此代码放在GameMap
构造函数中,则可以将this
提供给Cell
构造函数。
如果您仍希望将构建器代码与GameMap
代码分开,则可以在构建器上创建一个静态方法GameMap
构造函数调用并传递this
({{ 1}} object)作为参数。
答案 1 :(得分:0)
使用setter将 alert(member_id);
alert(msg);
alert(type_id);
传递给GameMap
而不是构造函数。您可以使其受包受保护以将其与其他代码隐藏,并在Cell
构造函数或GameMap
中的另一个循环中调用setter。所有已知的DE框架都使用setter来解决循环依赖。