Объектно-ориентированный дизайн и циклические зависимости

В настоящее время я борюсь с проблемой циклической зависимости при разработке моих классов.

С тех пор, как я прочитал о Анемической модели домена (что-то, что я делал все время), я действительно пытался уйти от создания объектов домена, которые были просто «ведрами геттеров и сеттеров» и вернуться к своим объектно-ориентированным корням.

Тем не менее, я часто сталкиваюсь с проблемой, описанной ниже, и не знаю, как ее решить.

Допустим, у нас есть класс Team , у которого много игроков . Неважно, какой это вид спорта :) Команда может добавлять и удалять игроков, почти так же, как игрок может покинуть команду и присоединиться к другой.

Итак, у нас есть команда, в которой есть список игроков:

public class Team {

    private List players;

    // snip.

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

Затем у нас есть Player, имеющий ссылку на команду:

public class Player {
    private Team team;

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

Можно предположить, что оба метода (remove и leave) имеют логику, зависящую от домена, которая должна выполняться всякий раз, когда команда удаляет игрока, а игрок покидает команду. Поэтому моя первая мысль заключается в том, что когда Команда кидает игрока, 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 действительно хороший аргумент. В ситуации, которую я описывал, игрок может покинуть команду (и знать, входит ли он в команду или нет), а также команда, управляющая удалением. Но я согласен с вашей точкой зрения, и мне не нравится идея, что в этом процессе есть две «точки входа». Еще раз спасибо.

19
задан Ben J 24 October 2010 в 11:22
поделиться