Связь ребенка с родителем - плохая идея?

15

У меня есть ситуация, когда мой родитель знает о своем ребенке (дух), но я хочу, чтобы ребенок мог ссылаться на родителя. Причина этого в том, что я хочу, чтобы ребенок имел возможность обозначать себя как наиболее важный или наименее важный, когда ему это нравится. Когда ребенок делает это, он перемещает его в верх или низ дочерних элементов родителя.

В прошлом я использовал свойство WeakReference для дочернего элемента для обращения к его родителю, но я чувствую, что это добавляет раздражающие накладные расходы, но, возможно, это просто лучший способ сделать это.

Это просто плохая идея? Как бы вы реализовали эту способность по-другому?

Обновление 1: добавление контекста. Это система рендеринга, поэтому родительский контейнер представляет собой список окон, сгруппированных вместе. Детский элемент (окно) с надписью "Я самый важный!" хочет в основном быть представленным на вершине остальных окон.

Родитель - это просто логический контейнер для группировки этих детей. Я вижу, где добавление события, сигнализирующего о том, что запрос находится на вершине, является хорошей идеей. Но кроме реализации (то, что ребенок хочет делать с родителем), почему бы вам не захотеть связать child-> parent? Дважды связанные списки делают это, чтобы люди могли переходить к чему-то и от чего-либо.

Thraka
источник
3
Вам не нужно WeakReference. Сборщик мусора .net может обрабатывать циклы. Если ребенок больше не используется (родитель не указывает на него), он будет собран, несмотря на то, что содержит ссылку на родителя.
ДБКК
Что происходит, если двое детей думают, что хотят быть самыми важными детьми?
Btilly
@btilly Самый важный дочерний элемент на самом деле просто переупорядочивает его в верхней части стека в дочернем списке родителя. Так что, кто бы ни делал это последним, становится самым важным. В моем сценарии у вас никогда не было бы конфликта самых важных.
Thraka

Ответы:

18

Это просто плохая идея?

Oftentimes.

  • Это нарушает инкапсуляцию родителя.
  • Это увеличивает сцепление в обоих.
  • Это служит точкой прорыва для ребенка, чтобы получить доступ к остальной части системы, усиливая связь с чем-то неопределенным рядом с ней (потому что люди будут злоупотреблять этой ссылкой)
  • Это ограничивает ваш дизайн, если вы хотите детей без родителей.

Как сделать это лучше? Ребенок не должен знать или заботиться о том, что он находится в коллекции. Вместо того, чтобы считать себя важным, он должен сигнализировать о том, что произошло какое-то событие, о котором он знает, так что кто бы ни заботился (родитель), может увеличить свой приоритет (или каковы правила для контекста, в котором живет ребенок). Я не в восторге от этого и, возможно, предпочел бы лучшее разделение проблем между моделью ребенка и поведением важности, но не могу уточнить без дополнительного контекста.

[редактировать:]

Да, системы рендеринга - это тот случай, когда владение родителями ... ну, я не хочу сказать, имеет смысл, но это один случай, когда это было сделано, и это не конец света. Для придания фокуса контроля я все же предпочел бы дизайн, в котором обработчик ввода (или что-то еще) обходит дерево и знает, какую коллекцию переупорядочить, а не находит дочерний элемент, вызывая что-то, что знает, чтобы перейти к его родителю.

Telastyn
источник
1
Это хороший ответ, и вам, вероятно, следует рассмотреть все вопросы, поднятые им, и посмотреть, относятся ли они к вашей проблеме. Сказав это, хотя я не думаю, что это конец света, если вы начнете с ссылки как простой реализации и реорганизуете ее, когда / если вещи выходят из-под контроля.
rperetti
Ответ правильный. Но если связывание детей с родителями - плохая идея, тогда объектно-ориентированное программирование больше не связано с объектами реальной жизни. Разве нет способа сделать это хорошо?
Маной Р
Спасибо за этот ответ. Я добавил больше контекста в свой оригинальный вопрос.
Трака
1
@ManojR - объектно-ориентированное программирование никогда не было связано с реальными объектами.
Теластин
Ваше редактирование заставляет меня задуматься о VisualTreeHelper в WPF \ Silverlight. Это позволило вам узнать о взаимосвязи текущего элемента управления с остальными элементами системы управления пользовательским интерфейсом. Я думаю, я мог бы реализовать что-то вроде этого, потому что у меня также есть корневой элемент управления, который будет размещать все остальное. Благодарность!!
Трака
0

Как исполнение дошло до того, что ребенок решает, что хочет быть самым важным? Дошло ли это через родителя? Если да, вы можете отправить ссылку на родителя для этого метода.

например. если все узлы имеют какой-то метод update (), который делает что-то вроде

void update() {
    doSomething()
    for(Node n:childs){
        //do something
        n.update();
    }
}

Вы можете изменить это на

void update(Node parent) {
    doSomething(parent)
    for(Node n:childs){
        //do something
        n.update(this);
    }
}
user470365
источник
Да, это отличный способ сделать это. Однако в моей ситуации вполне возможно, что клиентский логический код не инициируется родительским циклом.
Трака
0

Я не думаю, что это плохая идея. Вы можете решить эту проблему, добавив значение порядка сортировки для каждого дочернего элемента. Я предполагаю что-то вроде "z-index", используемый для отображения объектов поверх или позади друг друга на веб-страницах.

Я не уверен, как вы могли бы написать что-то подобное, но концепция звучит выполнимо.

Майкл Райли - AKA Gunny
источник
С этим решением, проблема все еще существует, хотя. Это только заменяет концепцию порядка в массиве на z-index. Я все еще должен был бы иметь систему связи от ребенка к родителю. Спасибо, хотя :)
Thraka