В настоящее время я борюсь с проблемой круговой зависимости при разработке моих классов.OO дизайн и круговые зависимости
С тех пор как я читал о Anemic Domain Model (что-то, что я делал все время), я действительно пытался уйти от создания объектов домена, которые были всего лишь «ведрами геттеров и сеттеров» и возвращаться к моим корням 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() вызвать команду.removePlayer (это)? Не без создания бесконечного цикла!
В прошлом, я бы просто сделал эти объекты «немыми» POJO и имел сервисный уровень. Но даже сейчас я все еще остаюсь с этой проблемой: чтобы избежать циклических зависимостей, уровня обслуживания до сих пор связывает все это вместе - то есть
public class SomeService {
public void leave(Player player, Team team) {
team.removePlayer(player);
player.leaveTeam();
}
}
ли я над усложняя это? Возможно, мне не хватает очевидного недостатка в дизайне. Любая обратная связь будет принята с благодарностью.
Спасибо всем за ответы. Я принимаю решение Grodriguez, поскольку оно является наиболее очевидным (не могу поверить, что это не произошло со мной) и легко реализуется. Однако DecaniBass действительно подходит. В ситуации, о которой я рассказывал, игрок может покинуть команду (и быть в курсе, находится ли он в команде или нет), а также команда, ведущая удаление. Но я согласен с вашей точкой зрения, и мне не нравится идея о том, что в этот процесс есть две «точки входа». Еще раз спасибо.
Может быть, это только я, но мне нравится использовать, если ... еще так же экономно, насколько это возможно. Я заметил, что код делает немного менее поддерживаемым –
players.remove() вернет true, если коллекция была изменена; не нужно делать .contains(). – KarlP
@KarlP: Я знаю, но я думал, что явная проверка сделает логику более ясной. – Grodriguez