Как решить перекрестные ссылки в ООП?

Решения gsub также работают, вот решение Tidyverse.

require(tidyverse)
b <- a %>% mutate(
    text_new = str_remove_all(text, c("hello <firstname>", "Can you repeat"))
  )
b
5
задан tehvan 5 March 2009 в 08:18
поделиться

7 ответов

Это не фундаментальная проблема в дизайне OO. Пример времени, это могло бы стать проблемой, находится в обходе графика, например, находя кратчайший путь между двумя объектами - Вы могли потенциально войти в бесконечный цикл. Однако это - что-то, что необходимо было бы рассмотреть в зависимости от конкретного случая. Если Вы знаете, что могли бы быть перекрестные ссылки в случае как этот, то кодировать некоторые регистрации для предотвращения бесконечных циклов (например, поддержав ряд посещаемых узлов, чтобы не пересматривать). Но если нет никакой причины, это могла бы быть проблема (такой как в примерах, которые Вы дали в своем вопросе), затем это не плохо вообще, чтобы иметь такие перекрестные ссылки. И во многих случаях, как Вы описали, это - хорошее решение проблемы под рукой.

1
ответ дан 15 December 2019 в 06:35
поделиться

Ссылка на другие объекты не является очень плохим дизайном OO вообще. Это - способ, которым состоянием управляют в каждом объекте.

Хорошим эмпирическим правилом является Закон Demeter. Посмотрите на эту идеальную газету ЛОДА (Разносчик газет и кошелек):щелкните здесь

0
ответ дан 15 December 2019 в 06:35
поделиться

Я не думаю, что это - пример перекрестных ссылок.

Перекрестные ссылки обычно принадлежат этому случаю:

class A
{
    public void MethodA(B objectB)
    {
       objectB.SomeMethodInB();
    }
}

class B
{
    public void MethodB(A objectA)
    {
        objectA.SomeMethodInA();
    }
}

В этом случае каждый объект отчасти "достигает в" друг другу; вызовы B, B называет A, и они становятся сильно связанными. Это даже усугублено, если A и B находятся в различных пакетах/пространствах имен/блоках; во многих случаях они создали бы ошибки времени компиляции, поскольку блоки компилируются линейно.

Способ решить, который должен иметь любой объект, реализует интерфейс с требуемым методом.

В Вашем случае у Вас только есть один уровень "достижения в":

public Class Person
{
    public void setSpouse(Person person)
    { ... }
}

Я не думаю, что это неблагоразумно, ни даже случай перекрестных ссылок/циклических ссылок.

1
ответ дан 15 December 2019 в 06:35
поделиться

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

Однако затрагивать Ваши примеры;

См. Также совершенно допустимо, если это - функция, Вам нужно в Вашем коде - это - простой список указателей (или ссылки) к другим объектам, которыми может интересоваться пользователь.

Так же это совершенно допустимо для добавления супруга, поскольку это - простые отношения реального мира, которые не сбивали бы с толку кого-то поддерживающего код.

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

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

1
ответ дан 15 December 2019 в 06:35
поделиться

Я не думаю, что циклические ссылки как таковые являются проблемой.

Однако помещение всех тех отношений в объектах может добавить слишком много помехи, таким образом, можно вместо этого хотеть представить их внешне. Например, Вы могли бы использовать хеш-таблицу для хранения отношений между продуктами.

0
ответ дан 15 December 2019 в 06:35
поделиться

Примерами, которые Вы даете, являются (мне, так или иначе) примеры разумного дизайна OO.

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

С чем Вы встретились, который произвел Вам впечатление, что этот подход является плохим дизайном?

Обновление 11 марта:

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

Одним примером является класс Delphi TComponent, который оказывает каскадную поддержку - уничтожают родительский компонент, и все находящиеся в собственности компоненты также уничтожаются.

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

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

2
ответ дан 15 December 2019 в 06:35
поделиться

Один способ зафиксировать это состоит в том, чтобы относиться к другому объекту с помощью идентификатора.

например.

Person jack = new Person(new PersonId("Jack"));
Person jill = new Person(new PersonId("Jill"));
jack.setSpouse(jill.getId());
jill.setSpouse(jack.getId());

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

-2
ответ дан 15 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: