除非您抽象出设置器,否则您将不得不提供某种事件通知机制。如果您的对象是 JavaBean,那么您正在考虑使用 PropertyChangeSupport 并触发属性更改事件。
如果你这样做(或有一些其他机制来检测更改),那么 Glazed Lists 会提供一个ObservableElementList,它可以很容易地用于处理来自列表端的关联同步(即自动将 A 添加到 List调用 a.setB(b))。使用属性更改监控(或等效)可以轻松处理另一个方向。
我意识到这不是一个通用的解决方案,但它似乎是一个简单的基础。
请注意,这样的事情需要在 B 类中实现一个特殊的列表 - 在一般情况下您可以处理它的 AOP 类型解决方案(即使用 ArrayList 或类似的东西)绝非易事)。
我还应该指出,您要实现的目标是数据绑定的圣杯。在字段级别有一些不错的绑定实现(例如 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 绑定,试图将一个对象的字段值绑定到该对象在另一个对象中的列表成员资格甚至不在他们的桌子上)。