В настоящее время я борюсь с проблемой циклической зависимости при разработке своих классов.
С тех пор, как я прочитал о Анемичной Доменной Модели (чем-то, что я делал все время), я действительно пытался уйти от создания доменных объектов, которые были просто "блоками геттеров и сеттеров" и вернись к моим ОО-корням.
Однако проблема, с которой я столкнулся, часто встречается, и я не уверен, как мне ее решить.
Скажем, у нас есть класс Team , в котором много игроков . Неважно, что это за спорт :) Команда может добавлять и удалять игроков, почти так же, как игрок может покинуть команду и присоединиться к другой.
Итак, у нас есть команда, у которой есть список игроков:
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...
}
}
Можно предположить, что оба метода (удалить и уйти) имеют специфическую для домена логику, которую необходимо запускать всякий раз, когда команда удаляет игрока, а игрок покидает команду. Поэтому моя первая мысль - когда Team пинает игрока, removePlayer (...) также должен вызывать метод player.leaveTeam () ...
Но что, если Player управляет отъездом - должен ли метод leftTeam () вызывать team.removePlayer (this)? Не без создания бесконечного цикла!
В прошлом я бы просто сделал эти объекты "тупыми" POJO и сделал бы работу сервисным слоем. Но даже сейчас я все еще остаюсь с этой проблемой: чтобы избежать циклических зависимостей, сервисный уровень по-прежнему связывает все это вместе, т.е.
public class SomeService {
public void leave(Player player, Team team) {
team.removePlayer(player);
player.leaveTeam();
}
}
Я слишком усложняю это? Возможно, мне не хватает какого-то очевидного недостатка дизайна. Любая обратная связь будет принята с благодарностью.
<Ч />
Спасибо всем за ответы. Я принимаю решение Grodriguez , так как оно является наиболее очевидным (не могу поверить, что оно мне не пришло в голову) и простым в реализации. Тем не менее, DecaniBass имеет смысл. В ситуации, которую я описывал, игрок может покинуть команду (и знать, находится ли он в команде или нет), а также команду, управляющую удалением. Но я согласен с вашей точкой зрения, и мне не нравится идея, что в этом процессе есть две «точки входа». Еще раз спасибо.