2014-11-07 5 views
5

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

Тогда почему круговая зависимость плохой дизайн? Если нам действительно нужно избегать этого, то какова наилучшая возможная конструкция в объектно-ориентированном мире для такой ситуации?

+1

В моем опыте основная проблема с циркулярными ссылками - это управление памятью - кому принадлежит что? –

+0

Это ни хорошо, ни плохо: это то, что есть. Если вы чувствуете, что вы должны, остерегайтесь утечек памяти. – YvesLeBorg

+0

В прошлый раз, когда я проверил (иначе мне пришлось скомпилировать это), проект 'llvm' был включен для круговых зависимостей, и они пишут виртуальную машину/компилятор. Вы можете принять это в качестве примера и, возможно, спросить, почему они идут с этим дизайном. – user2485710

ответ

7

Проблема с круговыми зависимостями скорее напоминает проблему с курицей и яйцом.

Если вы зависеть от меня, что-то настраиваете, и я полагаюсь на то, что вы что-то наладите, как мы начнем?

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

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

+0

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

+0

hmmm thanks gbjbaanb. Но это также означает, что в виртуальном мире 2 друзья не могут напрямую взаимодействовать друг с другом, им нужен посредник, чтобы сделать это – Nipun

+0

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

2

Вы должны понимать, что циклическая зависимость означает, что вы можете использовать только соответствующие круговые зависимые классы вместе: если у вас есть циклическая зависимость между, скажем, A и B, вы не можете использовать A или B самостоятельно в любой программе. Чтобы придерживаться вашей проблемы: конечно, вам не нужны два других друга! Все, что вам нужно, это какой-то способ ссылаться на некоторых и взаимодействовать с ними таким образом, который может быть ограничен их фактическими способностями.

Однако часто бывает, что объекты классов используют друг друга без причины круговой зависимости. С этой целью важно определить, что на самом деле вызывает зависимость между двумя классами/компонентами (они не совсем эквивалентны, но предоставление подробного определения будет несколько длинным). A зависит от B при следующих условиях:

  1. Когда A содержит элемент типа B.
  2. Когда A происходит от типа B.
  3. Когда A использует значение типа B как часть сигнатуры функции.
  4. Когда A использует B в своей реализации.
  5. Я, наверное, кое-что забыл (я помню, было больше причин, по которым были бы связаны классы).

Если у вас есть циклическая зависимость между двумя классами, могут быть способы разбить эту зависимость. Часто зависимость может быть разбита путем разбиения одного из двух классов на базовый класс и производного класса с базовым классом, не зависящим от другого класса. Существует ряд других подходов к разрыву циклов зависимостей. «Большой масштаб C++» Джона Лакоса (1996), по сути, касается циклов взаимозависимости и мотивации, почему циклические зависимости плохие (я думаю, он не согласился бы с этой упрощающей характеристикой).

...и, да, циклические зависимости являются плохо:

  1. Они вызывают программы включают в себя ненужную функциональность, потому что вещи валяются, в которых не требуется.
  2. Они затрудняют тестирование программного обеспечения.
  3. Они делают намного сложнее рассуждать о программном обеспечении.
  4. Они значительно упрощают замену частей системы.
  5. ... и, возможно, ряд других причин.

Вышеупомянутое сформулировано с точки зрения C++. Некоторые из причин круговых зависимостей могут отсутствовать [непосредственно] в C, но те же самые понятия применимы и к C.