Diseño OO y dependencias circulares

Actualmente estoy luchando con un problema de dependencia circular al diseñar mis clases.

Desde que leí sobre elModelo de dominio anémico (algo que hacía todo el tiempo), realmente he estado tratando de escapar de la creación de objetos de dominio que eran solo "cubos de captadores y establecedores" y volver a mis raíces OO.

Sin embargo, el siguiente problema es uno con el que me encuentro mucho y no estoy seguro de cómo debería resolverlo.

Digamos que tenemos unEquipo clase, que tiene muchosJugadores. No importa de qué deporte se trate :) Un equipo puede agregar y eliminar jugadores, de la misma manera que un jugador puede abandonar un equipo y unirse a otro.

Entonces tenemos el equipo, que tiene una lista de jugadores:

public class Team {

    private List<Player> players;

    // snip.

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

Luego tenemos el jugador, que tiene una referencia al equipo:

public class Player {
    private Team team;

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

Se puede suponer que ambos métodos (eliminar y dejar) tienen una lógica específica de dominio que debe ejecutarse cada vez que un equipo elimina a un jugador y un jugador deja un equipo. Por lo tanto, mi primer pensamiento es que cuando unEquipo patea a un jugador, removePlayer (...) también debe llamar al método player.leaveTeam () ...

Pero entonces, ¿y si elJugador está impulsando la salida: ¿el método leaveTeam () debe llamar a team.removePlayer (this)? ¡No sin crear un bucle infinito!

En el pasado, Habría hecho que estos objetos fueran "tontos" POJO y que una capa de servicio hiciera el trabajo. Pero incluso ahora todavía me queda ese problema: para evitar dependencias circulares, la capa de servicio todavía tiene unirlo todo, es decir

public class SomeService {

    public void leave(Player player, Team team) {

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

    }

}

¿Estoy sobre complicando esto? Quizás me estoy perdiendo algún defecto de diseño obvio. Cualquier comentario sería muy apreciado.

Gracias a todos por las respuestas. Estoy aceptandoGrodriguezLa solución es la más obvia (no puedo creer que no se me haya ocurrido) y fácil de implementar. Sin embargo,DecaniBass hace un buen punto. En la situación que estaba describiendo, es posible que un jugador deje un equipo (y sepa si está en un equipo o no), así como el equipo que conduce la eliminación. Pero estoy de acuerdo con su punto y no me gusta la idea de que hay dos "puntos de entrada" en este proceso. Gracias de nuevo.

Respuestas a la pregunta(4)

Su respuesta a la pregunta