Как очистить двусвязные отношения «многие ко многим»? - PullRequest
1 голос
/ 27 апреля 2009

Прежде всего, я не уверен, что заголовок точно описывает то, о чем я говорю, поэтому не стесняйтесь оставлять комментарий о том, как это назвать, или просто переименуйте его, если у вас есть представитель.

Скажем, например, у меня есть 2 класса, Книга и Библиотека. Библиотека содержит свойство, представляющее собой список всех книг, которыми она владеет. У книги есть свойство, представляющее собой список всех библиотек, к которым она принадлежит.

В книге У меня есть метод RemoveFromLibrary, который удаляет библиотеку из списка библиотек. Я также хочу, чтобы тот же метод очистил другой конец, а именно список книг библиотеки, которой он владеет. То же самое относится и к другому концу, к методу RemoveBook в библиотеке, который также очищает список библиотек этой книги, которые его содержат.

Прежде всего, имеет ли это смысл? Мне кажется удобным, чтобы вызывающий код не беспокоился об очистке и не вызывал 2 метода для выполнения одного логического действия. Я имею в виду, что не имеет смысла удалять из одного списка, но не из другого. В то же время можно сказать, что это делает их слишком тесно связанными, но я думаю, что я просто сделаю рефакторинг для отделения, если это станет проблемой.

В чем я не уверен, насколько это реализовано, если я просто вызову обычный публичный метод, то я получу бесконечный цикл каждого метода, вызывающего другой. Я мог бы создать отдельное внутреннее свойство (работающее в C #), которое не очищает, но мне кажется, что я засоряю API методом, который должен вызываться только из одного другого метода. В качестве альтернативы я мог бы представить базовую коллекцию как внутреннюю, что немного лучше, но она все еще не кажется идеальной. Есть ли лучшее решение, или мне просто нужно пойти с одним из этих двух, или убедиться, что вызывающий код выполняет саму очистку?

1 Ответ

1 голос
/ 27 апреля 2009

Может быть, это будет работать. Перед вызовом метода remove другого класса убедитесь, что в его списке объектов (например, книг) все еще содержится объект, который нужно удалить.

Кстати это только псевдокод (может не скомпилироваться)

class Book
{
    Library[] libraries;

    void RemoveFromLibrary(Library lib)
    {
        libraries.remove(lib);
        if (IsInLibrary(lib) && lib.HasBook(this)) // prevents call-loop
            lib.RemoveBook(this);
    }

    bool IsInLibrary(Library lib)
    {
        return libraries.Contain(lib);
    }
}


class Library
{
    Book[] books;

    void RemoveBook(Book bk)
    {
        books.remove(bk);
        if (HasBook(bk) && bk.IsInLibrary(this)) // prevents call-loop
            bk.RemoveLibrary(this);
    }

    bool HasBook(Book bk)
    {
        return books.Contain(bk);
    }
}

edit : исправлен код, основанный на комментариях ... Я засыпал, когда писал: P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...