【问题标题】:Managing bidirectional associations in my java model在我的 java 模型中管理双向关联
【发布时间】:2009-11-28 21:47:06
【问题描述】:

我有一个 java 模型,其中类具有应该双向工作的关联(1 到 1、1 到 n、n 到 n)。

示例: A 类有 B 类的集合

B 的所有实例都必须知道它们的父 (A) 是谁。如果我更改了 B 的父属性,则关联也需要在另一侧进行更新。

我认为,编写代码来使两端的关联保持最新是相当乏味且容易出错的。

那么:有没有更好的方法来做到这一点?是否有可以管理两个对象之间双向关联的 java 库?

【问题讨论】:

  • “我认为,编写代码来使两端的关联保持最新是非常乏味且容易出错的。”你为什么这么说?这通常一点也不难。
  • 乏味,因为我必须向所有模型类添加相同的功能。我觉得这是一个相当重复的工作。容易出错,因为我必须记住一些特殊情况。例如。如果我将 B 的父级设置为 A 的另一个实例(将 B 从一个 A 转移到另一个)会发生什么。我必须确保删除旧链接。但是,如果我第二次设置同一个父级怎么办。那么代码不应该触及已经存在的链接。等等当然不是不能做对,但是如果这个问题已经有了解决办法,那我为什么要重新发明轮子呢?

标签: java


【解决方案1】:

另一种方法是将关系移出相关对象。很多时候,A 和 B 都不需要彼此了解;是使用代码发现这些属性很方便。这就是图表或双向地图可以发挥作用的地方。

双向映射可以简单地用于跟踪一对一的关系。图表可以更好地跟踪其他类型的基数(多对一、多对多等)

有几个不同的图形实现可以为此提供帮助。我听说过但从未使用过 JGraphT,而且我使用了很多称为 plexus(与 IOC 容器无关)。分别为http://jgrapht.sourceforge.net/http://plexus.sf.net/

图表很好,因为它可以完全灵活地定义不同的关系,并且隐式维护双向链接。

关系的双方都需要保持同步这一事实通常表明关系本身与端点同等重要,而不是双方都应该试图封装的东西。

不过,如果父母和孩子真的确实需要相互操作,那么一种方法是确定哪个是主要的,以及是否所有操作都可以通过该对象完成。因此,例如,在父子关系中,子操作可以在父节点上完成,父节点在该操作期间将自身的引用传递给子节点。我认为,如果你不能,那么这是一个很好的指标,表明需要在设计中重新绘制一些线条。

再次使用父子示例,我还没有真正发现父->子和子->父关系如此动态以至于一端无法控制的情况。在 99% 的情况下,我保留从次要到主要的反向引用,这是为了方便,并且关系的生命周期已经建立。

...否则,我使用图表。

【讨论】:

    【解决方案2】:

    您有三个选择:

    1. 管理此关联的两端;
    2. 使其有效地双向。我的意思是它是单向的,但实际上是通过代码的另一种方式;或
    3. 面向方面的编程。

    作为 2 的示例,您在 House 和 Room 之间具有一对多的关系。房间有参考房子。您可以维护房屋中的房间列表或执行以下操作:

    public class House {
      ...
    
      public List<Room> getRooms() {
        List<Room> ret = new ArrayList<Room>();
        for (Room room : /* list of ALL rooms */) {
          if (room.getHouse().equals(this)) {
            ret.add(room);
          }
        }
        return ret;
      }
    }
    

    在某些情况下,这样做对性能的影响是合理的。

    通过 (3),您可以使用面向方面的编程(例如 Spring AOP、AspectJ)创建一个切入点,将 House on Room 设置为自动更新 House。就我个人而言,我倾向于回避这种方法,因为您很容易陷入“魔法”过多的情况,这可能会令人困惑并且是调试的噩梦。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-27
      • 2013-06-17
      • 2023-04-08
      相关资源
      最近更新 更多