Obecnie pracuję z problemem zależności cyklicznej podczas projektowania moich zajęć.Projekt OO i zależności cykliczne
Odkąd przeczytałem o Anemic Domain Model (coś, co robiłem cały czas), naprawdę próbowałem uciec od tworzenia obiektów domeny, które były po prostu "kubełkami pobierających i ustawiających" i wracają do moich korzeni OO.
Jednak poniżej jest problem, który często spotykam i nie jestem pewien, jak powinienem go rozwiązać.
że mamy zespołu klasy, który ma wiele Gracze. Nie ma znaczenia, jaki to sport :) Zespół może dodawać i usuwać graczy, podobnie jak gracz może opuścić drużynę i dołączyć do innej.
Więc mamy zespół, który ma listę graczy:
public class Team {
private List<Player> players;
// snip.
public void removePlayer(Player player) {
players.remove(player);
// Do other admin work when a player leaves
}
}
Następnie mamy gracza, który ma odniesienie do zespołu:
public class Player {
private Team team;
public void leaveTeam() {
team = null;
// Do some more player stuff...
}
}
Można przypuszczać, że zarówno metody (usuwanie i opuszczanie) mają specyficzną dla domeny logikę, która musi być uruchamiana za każdym razem, gdy drużyna usuwa gracza, a gracz opuszcza zespół. W związku z tym, moja pierwsza myśl to, że gdy zespołu wykopuje gracza, removePlayer (...) powinny również wywołać metodę player.leaveTeam() ...
ale co jeśli gracza napędza odjazd - czy metoda leaveTeam() powinna wywoływać team.removePlayer (this)? Nie bez tworzenia nieskończonej pętli!
W przeszłości, właśnie zrobiłbym te obiekty "głupimi" POJO i miał warstwę usług do pracy. Ale nawet teraz mi pozostało z tym problemem: aby uniknąć wzajemnie od siebie zależnych, warstwa usługa nadal ma połączyć to wszystko razem - tzn
public class SomeService {
public void leave(Player player, Team team) {
team.removePlayer(player);
player.leaveTeam();
}
}
jestem na komplikowania tego? Być może brakuje mi oczywistej wady konstrukcyjnej. Wszelkie opinie będą mile widziane.
Dziękuję wszystkim za odpowiedzi. Przyjmuję rozwiązanie Grodriguez, ponieważ jest to najbardziej oczywiste (nie mogę uwierzyć, że nie przyszło mi do głowy) i łatwe do wdrożenia. Jednak DecaniBass ma dobry punkt. W opisywanej sytuacji możliwe jest, że gracz opuści zespół (i będzie świadomy, czy jest w zespole, czy nie), a także zespół prowadzący usuwanie. Zgadzam się z twoim punktem widzenia i nie podoba mi się pomysł, że w tym procesie są dwa "punkty wejścia". Dzięki jeszcze raz.
Może być tylko ja, ale lubię go używać, jeśli ... tak oszczędnie jak to możliwe. Zauważyłem, że czyni kod trochę mniej łatwym do utrzymania –
players.remove() zwróci wartość true, jeśli kolekcja została zmieniona; nie trzeba wykonywać .contains(). – KarlP
@KarlP: Wiem, ale myślałem, że wyraźne sprawdzenie poprawi logikę. – Grodriguez