一尘不染

OO设计和循环依赖

java

我目前在设计类时遇到循环依赖问题。

自从我了解Anemic域模型(我一直在做的事情)以来,我一直在努力摆脱创建仅仅是“
getter和setter的存储桶”的域对象,并回到我的OO根。

但是,下面的问题是我遇到的很多问题,我不确定应该如何解决。

假设我们有一个 Team 类,其中有很多 Player
。这是什么运动都没有关系:)球队可以添加和删除球员,就像球员离开球队并加入另一个球队一样。

所以我们有了团队,其中有一个球员名单:

public class Team {

    private List<Player> players;

    // snip.

    public void removePlayer(Player player) {
        players.remove(player);
        // Do other admin work when a player leaves
    }
}

然后我们有了玩家,该玩家可以参考团队:

public class Player {
    private Team team;

    public void leaveTeam() {
        team = null;
        // Do some more player stuff...
    }
}

可以假设这两种方法(删除和离开)都具有特定于域的逻辑,每当团队撤离一名球员且一名球员离开球队时都需要运行该逻辑。因此,我首先想到的是,当一个 团队
踢一个球员时,removePlayer(…)也应该调用player.leaveTeam()方法…

但是,如果 播放机 正在推动出发,该怎么办-
LeaveTeam()方法应该调用team.removePlayer(this)吗?并非没有创建无限循环!

过去 ,我只是将这些对象设置为“哑”
POJO,并让服务层来完成工作。但是即使到现在,我仍然面临着这个问题:为了避免循环依赖,服务层仍然将它们链接在一起-即

public class SomeService {

    public void leave(Player player, Team team) {

        team.removePlayer(player);
        player.leaveTeam();

    }

}

我是否使这个复杂化了?也许我缺少一些明显的设计缺陷。任何反馈将不胜感激。


谢谢大家的答复。我接受 Grodriguez 的解决方案,因为它是最显而易见的(不敢相信这不是我想到的)并且易于实现。但是,
DecaniBass
确实很不错。在我描述的情况下,玩家可能会离开团队(并知道他是否在团队中)以及推动移除的团队。但是我同意你的观点,并且我不赞成在此过程中有两个“入口点”的想法。再次感谢。


阅读 182

收藏
2020-12-03

共1个答案

一尘不染

您可以通过添加警卫人员来检查团队是否仍然有该球员/该球员仍在团队中,从而打破循环依赖。例如:

在课堂上Team

public void removePlayer(Player player) {
    if (players.contains(player))
    {
        players.remove(player);
        player.leaveTeam();
        // Do other admin work when a player leaves
    }
}

在课堂上Player

public void leaveTeam() {
    if (team != null)
    {
        team.removePlayer(this);
        team = null;
        // Do some more player stuff..
    }
}
2020-12-03