Как предотвратить петлю в двунаправленных отношениях - PullRequest
1 голос
/ 11 мая 2011

Скажем, у нас есть следующие две сущности.

Библиотека

public class Library
{
    private Collection<Book> books = new ArrayList<Book>();

    public boolean add(Book book)
    {
        return books.add(book);
    }
    public boolean remove(Book book)
    {
        return books.remove(book);
    }
}

Книга

public class Book
{
    private Library library;
    public setLibrary(Library library)
    {
        this.library = library;
    }
}

Этоэто двунаправленные отношения, которые, скорее всего, разорвутся довольно быстро.Даже если вы добавляете книгу в библиотеку, библиотека книги не обновляется.И даже если вы обновляете библиотеку книги, библиотека не обновляется.

Итак, как бы вы поддерживали эти двунаправленные отношения хорошим способом?Конечно, я мог бы просто сделать add + remove в setLibrary и наоборот, но, насколько я вижу, это может вызвать цикл, который, вероятно, закончится StackOverflowError.

Ответы [ 4 ]

2 голосов
/ 11 мая 2011

Определите «владельца» для отношения.Владеет ли библиотека книгой или ей принадлежит библиотека?

Ответ на этот вопрос говорит вам, кто обновляет «ведомую» сущность.

Мне кажется, что библиотеке принадлежитbook, поэтому код «добавить книгу в библиотеку» должен войти в библиотеку, которая затем обновит обратные ссылки.

1 голос
/ 11 мая 2011

Хотя я бы рекомендовал метод Аарона для определения владельца отношений, альтернатива, которая позволяет методам set / add / remove оставаться там, где они есть, также должна определять соответствующие has методы (hasBook в Library и hasLibrary в Book). Прежде чем вызывать метод add или remove на другом конце отношения, вы сначала запрашиваете, существует ли он уже, и не вызывает ли он его.

0 голосов
/ 11 мая 2011

В предложенном вами решении не могли бы вы проверить ссылки на равенство, чтобы избежать цикла?

public boolean add(Book book)
{
   if(book.getLibrary != this) book.setLibrary(this);
   return books.add(book);
}
0 голосов
/ 11 мая 2011

Я тупой?

public boolean add(Book book)
{
   book.setLibrary(this);
   return books.add(book);
}
public boolean remove(Book book)
{
   book.setLibrary(null);
   return books.remove(book);
}
...