OO 设计和循环依赖关系

2022-09-02 01:31:35

我目前在设计类时正在努力解决循环依赖问题。

自从我读到关于Anemic Domain模型(我一直在做的事情)以来,我真的一直在努力摆脱创建只是“getters和setters桶”的域对象,并回到我的OO根源。

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

假设我们有一个团队职业,里面有很多玩家。这是什么运动并不重要:)一个团队可以添加和删除玩家,就像玩家可以离开一个团队并加入另一个团队一样。

所以我们有球队,它有一个球员名单:

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确实提出了一个很好的观点。在我所描述的情況下,球員有可能離開一個球隊(並注意他是否在一個隊伍中)以及推動移除的球隊。但我同意你的观点,我不喜欢这个过程有两个“切入点”的想法。再次感谢。


答案 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..
    }
}

答案 2

我首先会问一个球员是否可以(从逻辑上,法律上)将自己从球队中移除。我会说玩家对象不知道他在哪支球队(!),他是球队的一部分。因此,删除并通过该方法进行所有团队更改。Player#leaveTeam()Team#removePlayer()

如果您只有一名球员并且需要将其从其团队中删除,则可以在Team上使用静态查找方法public static Team findTeam( Player player ) ...

我知道这不如一种方法令人满意和自然,但根据我的经验,你仍然可以有一个有意义的领域模型。Player#leaveTeam()

2种方式引用(父->子项和子项->父项)通常充满了其他内容,例如垃圾回收,保持“引用完整性”等。

设计是一种妥协!