除非您抽象出设置器,否则您将不得不提供某种事件通知机制。如果您的对象是 JavaBean,那么您正在考虑使用 PropertyChangeSupport 并触发属性更改事件。
如果你这样做(或有一些其他机制来检测更改),那么 Glazed Lists 提供了一个ObservableElementList,它可以很容易地用于从列表端处理关联同步(即,将 A 添加到 List< A> 会自动调用 a.setB( b))。使用属性更改监视(或等效)可以轻松处理另一个方向。
我意识到这不是一个通用的解决方案,但它似乎是一个简单的基础。
请注意,这样的事情需要在 B 类中实现特殊的列表 - 在一般情况下(即使用 ArrayList 或类似的东西),您可以处理它的 AOP 类型解决方案绝非易事。
我还应该指出,您要实现的目标是数据绑定的圣杯。在字段级别有一些不错的绑定实现(例如 getter 和 setter)(参见 JGoodies 绑定和 JSR 295 示例)。列表类型绑定还有一个非常好的实现(Glazed Lists,上面提到过)。我们在几乎所有的应用程序中都同时使用这两种技术,但从未尝试过像您所询问的那样抽象。
如果我正在设计这个,我会看这样的东西:
AssociationBuilder.createAssociation(A a, Connector< A> ca, B b, Connector< B> cb, Synchronizer< A,B> sync)
连接器是一个接口,它允许单个接口用于各种更改通知类型。Synchronizer 是一个接口,它被调用以确保两个对象在其中一个对象发生更改时保持同步。
sync(ChangeInfo info, A a, B b) // make sure that b reflects current state of a and vice-versa.
ChangeInfo 提供有关哪些成员发生了变化以及实际发生了什么变化的数据。我们是。如果你想真正保持这个通用性,那么你几乎必须把它的实现交给框架用户。
有了上述内容,就有可能拥有许多满足不同绑定标准的预定义连接器和同步器。
有趣的是,上述方法签名与 JSR 295 createAutoBinding() 方法调用非常相似。属性对象等价于连接器。JSR 295 没有同步器(相反,它们具有指定为 ENUM 的绑定策略 - 加上 JSR 295 仅适用于 property->property 绑定,试图将一个对象的字段值绑定到该对象在另一个对象中的列表成员资格甚至不在他们的桌子上)。