如何防止双向关系中出现环路

发布于 2024-11-06 14:07:58 字数 748 浏览 4 评论 0原文

假设我们有以下两个实体。

图书馆

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;
    }
}

这是一种双向关系,很可能很快就会破裂。即使您将一本书添加到图书馆,该书的图书馆也不会更新。即使您更新了一本书的图书馆,图书馆也不会更新。

那么,如何才能很好地维持这种双向关系呢?我当然可以在 setLibrary 中执行 add+remove ,反之亦然,但据我所知,这会导致循环这可能会以 StackOverflowError 结束。

Say we have the following two entities.

Library

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);
    }
}

Book

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

This is a bi-directional relationship which will most likely break pretty quick. Even though you add a book to a library, the library of the book is not updated. And even though you update the library of a book, the library isn't updated.

So, how would you maintain this bi-directional relationship in a good way? I could of course just do an add+remove in the setLibrary and vice versa, but this would as far as I can see cause a loop which would probably end in a StackOverflowError.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧夏天 2024-11-13 14:07:58

定义关系的“所有者”。图书馆“拥有”这本书还是这本书拥有图书馆?

该问题的答案告诉您谁更新了“从属”实体。

我觉得图书馆拥有这本书,所以“将书添加到图书馆”代码应该进入图书馆,然后更新后面的引用。

Define a "owner" for the relation. Does the library "own" the book or does the book own the library?

The answer to that question tells you who updates the "slave" entity.

I feel that the library owns the book, so the "add book to library" code should go into the library which will then update the back references.

墨洒年华 2024-11-13 14:07:58

虽然我推荐 Aaron 定义关系所有者的方法,但允许 set/add/remove 方法保留在原来位置的替代方法是还定义相应的 has 方法(Library 中的 hasBookBook 中的 hasLibrary) 。在关系另一端调用 addremove 方法之前,首先查询它是否已存在,如果存在则不调用它。

While I would recommend Aaron's method of defining a relationship owner, an alternative that allows the set/add/remove methods to remain where they are is to also define corresponding has methods (hasBook in Library and hasLibrary in Book). Before calling the add or remove method on the other end of the relation, you first query if it already exists, and if it does don't call it.

栖迟 2024-11-13 14:07:58

我是不是傻了?

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

Am I being dumb?

public boolean add(Book book)
{
   book.setLibrary(this);
   return books.add(book);
}
public boolean remove(Book book)
{
   book.setLibrary(null);
   return books.remove(book);
}
栖迟 2024-11-13 14:07:58

在您提出的解决方案中,您不能检查引用是否相等以避免循环吗?

public boolean add(Book book)
{
   if(book.getLibrary != this) book.setLibrary(this);
   return books.add(book);
}

In your proposed solution, couldn't you check references for equality to avoid loop?

public boolean add(Book book)
{
   if(book.getLibrary != this) book.setLibrary(this);
   return books.add(book);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文