Здравствуйте, уважаемые кывт'еры!
Занимаясь разработкой я сталкивался с необходимостью иметь коллекции некоторых Элементов, которые вынуждены знать о коллекции, в которую они добавлены (Родителе), а так же встречал подобные ситуации в различных фреймворках. Часто с подобной ситуацией сталкивался при описании различных моделей, иерархии классов которых построенны согласно шаблону проектирования Composite. Например, некоторому элементу могло требоваться знать в каком "контексте" он находится — приходилось спускаться по дереву вниз, к Родителям.
Необходимость иметь в элементе ссылку на Родителя создаёт проблемы:
Необходимо отслеживать ситуации, когда один Элемент добавляется в несколько Родителей.
И политика тут может быть разная, я встречал два подхода: запрещать подобные ситуации, просто бросая исключение при добавлении к воллекцию Элемента, уже имеющего Родителя, или делать глубокую копию Элемента и добавлять в другого Родителя её (подобный подход в .NET применяется в классах Linq to XML). Второй подход имеет узкое применение, вынуждает описывать клонирование (подвержено ошибкам и потенциально ударяет по производительности) и не нравится лично мне тот факт, что добавляя Элемент в Родителя нельзя быть уверенным, что в Родителя добавится Элемент, ссылочно равный тому, который изначально добавляли.
Необходимо управлять видимостью свойства/метода, задающего элементу родителя.
В случае паттерна composite, можно просто объявить свойство с public-геттером и protected-сеттером. Однако Родитель не всегда разделяет с Элементом общий базовый класс, тогда приходится использовать более широкую область видимости, типа internal в дотнет. Иногда встречаются свойста родителей вовсе с public-сеттером (Windows.Forms тому пример), которые сами удаляются из бывшего Родителя и добавляются в коллекцию нового. Такой подход лично мне не нравится (слишком много видимых снаружи эффектов для "простого" присвоения свойству), да и вовсе не годится, если порядок дочерних Элементов в коллекции Родителя имеет значение (в Windows.Forms при задании нового Parent'а, контрол просто добавляется в конец коллекции контролов), хоть и может выглядеть удобно.
При этом в .NET я не встречал никаких средств обобщения, каких-нибудь специальных коллекций, осуществляющих слежение за инвариантом ссылок на Родителей.
Собственно я прошу как-то формализовать мой взгляд на проблему ссылок на Родителей, может кто подскажет годные статьи по теме, какие-нибудь шаблоны проектирования или альтернативные подходы, что-нибудь ещё...