如何在这里避免循环依赖

zap*_*nat 15 design-patterns

有没有办法避免循环依赖,除了混合模块,在这样的安排(它是国际象棋应用程序)

详细描述:

  • Gui一个导入ChessWidget模块的模块;
  • ChessWidget只需包装ChessWorld模块并导入CellButton;
  • CellButton模块导入模块Cell;
  • 所述ChessWorld模块进口Board(以表示它)和Players(通知他们和他们的取移动);
  • Board模块导入模块Piece;
  • Piece模块导入模块Player;

这里是问题:

Player模块需要了解其他玩家和董事会,从而进口ChessWorld!

简短的介绍:

World模块需要了解的Player模块(甚至间接Board/ Piece),并Player需要了解World.

非常感谢帮助.

PS:不是因为我不能使用循环依赖,而是因为它们是邪恶的.

Ale*_*lli 16

遵循依赖性反转原则:引入一个接口,该接口ChessWorld实现并Player依赖于 - 和/或Player实现Piece依赖的接口(根据依赖性的细节,其中一个或两个可能是合适的).这通常与依赖注入一起使用,并且,如果依赖项需要使用Factory DP 动态实例化依赖项的多个实例.

  • 依赖关系有一个方向,例如A-> B-> C-> A是圆形的,但如果你反转任何一个箭头,它就不再是圆形. (8认同)

Coh*_*hen 6

我认为循环依赖的气味显示出更多的建筑/设计问题,不应该通过DI,后期边界,松散耦合或任何其他形式的额外抽象层来解决.虽然它们都是非常好的机制,但不解决下面的问题.

简而言之:我认为ChessWorld承担太多的责任.如果你拆分它们,你可能会发现依赖关系是更适合单独模块的职责.

很长的解释:我将尝试举例说明我将如何重构它,虽然这很难,因为我现在不是完整的问题域.

注意:我不熟悉Java,所以我可能会误解导入和换行的含义.

但据我所知,依赖关系看起来像这样:

Gui <- ChessWidget <- ChessWorld <- CellButton <- Cell
                                 <- Board <- Piece <- Player
                                 <- Players <- ChessWorld
Run Code Online (Sandbox Code Playgroud)

恕我直言,问题在于ChessWorld承担着太多不同的责任.在像PlayerList,RegisteredUsers或OnlineUsers等类似的单独模块中维护玩家列表可能更好.在重构后,您的依赖关系会发生如下变化:

 Gui <- ChessWidget <- ChessWorld <- CellButton <- Cell
                                  <- Board <- Piece <- Player
                                  <- Playerlist <- Player
Run Code Online (Sandbox Code Playgroud)

PlayerList可能是玩家模块中的内容.现在Chessworld依赖于玩家模块,而不是另一个方向.

我不确定它是否完全符合您的意图,但我对讨论这个问题非常感兴趣,所以请评论.