Если вы не абстрагируете сеттеры, вам придется предоставить какой-то механизм уведомления о событиях. Если ваши объекты являются JavaBeans, то вы рассматриваете использование PropertyChangeSupport и запуск событий изменения свойств.
Если вы делаете это (или имеете какой-то другой механизм для обнаружения изменений), то Glazed Lists предоставляет ObservableElementList , который можно легко использовать для обработки синхронизации ассоциации с конца списка (т.е. добавление A в список автоматически вызывает a.setB (b)). Другое направление легко обрабатывается с помощью мониторинга изменения свойств (или эквивалентного ему).
Я понимаю, что это не универсальное решение, но кажется, что оно будет легким основанием для него.
Обратите внимание, что что-то вроде этого потребует специальной реализации списка в классе B - ни в коем случае не меньше решений типа AOP, которые вы могли бы обработать в общем случае (например, используя ArrayList или что-то подобное) .
Я также должен отметить, что то, что вы пытаетесь достичь, является чем-то вроде святого Грааля привязки данных. Существует несколько достойных реализаций для связывания на уровне полей (например, геттеры и сеттеры) (см. Пример привязки 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 (). Объекты свойств являются эквивалентом Connector. JSR 295 не имеет синхронизатора (вместо этого у них есть стратегия привязки, заданная как ENUM - плюс JSR 295 работает только с привязкой свойства-> свойства, пытаясь привязать значение поля одного объекта к членству списка этого объекта в другом объекте даже не на столе для них).