Подтвердить что ты не робот

Почему круговые ссылки в Visual Studio - плохая практика?

Почему циркулярные ссылки в Visual Studio - плохая практика?

Во-первых, я опишу пример того, как это может произойти с использованием С# в Visual Studio, поскольку VS, как правило, информирует вас, если у вас есть циклическая ссылка и не рекомендуется.

Сначала создается класс Утилиты, основанный только на коде, предоставленном вам Visual Studio и .Net. Затем создается класс E-mail, который зависит от Утилиты. Вместо того, чтобы добавлять оба проекта в одно решение, создается новое решение и добавляется ссылка на Utilities.dll. Затем, спустя некоторое время, кто-то решает, что они хотят, чтобы класс Утилиты отправил электронное письмо и добавил ссылку на Mail.dll. Visual Studio с удовольствием позволит вам это сделать, но теперь источник не будет компилироваться как есть без одного из двоичных файлов.

В моем рабочем месте это стандартная процедура для копирования и вставки двоичных файлов при разработке, а затем только для создания проектов, над которыми вы работаете. Это привело к по крайней мере одной циркулярной ссылке в кодовой базе, которая осталась незамеченной более 3 лет.

Это кажется очень плохой практикой для меня, потому что нет возможности построить проект из источника, не имея вначале DLL. Этот аргумент мало подходит для "практических" людей, с которыми я работаю, поскольку маловероятно, что мы потеряем все копии наших двоичных файлов одновременно. Бинарные файлы не сохраняются в контроле версий в любой момент, что только меня больше беспокоит.

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

4b9b3361

Ответ 1

Да, это плохая практика именно по той причине, о которой вы заявили, - вы не можете перестроить из источника.

Ответ 2

Это один из симптомов чрезмерной модуляции.

Я работал в компании один раз с около двадцати разработчиков и более шестидесяти различных активных проектов в репозитории SVN. Каждый проект имел свою собственную конструкцию script и создал JAR файл, который был зависимым от по меньшей мере полудюжины или около того других проектов. Управление всеми этими зависимостями было настолько сложным, что мы потратили много времени на попытки (неудачно, я мог бы добавить), чтобы настроить проекты maven для автоматического получения всех правильных библиотек (и правильных версий) для всех этих небольших микропроектов.

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

Sheesh.

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

Конечно, модульность вообще хорошая вещь.

Но, как и все хорошие вещи, его можно воспринимать до смешных крайностей.

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

Ответ 3

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

Я заметил это много с сборками утилиты. Должен быть анти-шаблон.

Ответ 4

Вопрос, который я бы поставил перед вашими коллегами:

Хорошо, очень маловероятно, что мы потеряем все наши двоичные файлы одновременно. Но, скажите, какая польза от этого подхода?

Если они приходят с чем-то другим, чем "Мы всегда делали это так", я бы хотел это услышать. И, как всем известно, "мы всегда так делали это", это НЕ хорошая причина, и они не должны защищать его.

Ответ 5

круговые зависимости плохие, потому что:

  • проект Проект ссылок B
  • Когда изменения проекта B, проект A необходимо перестроить
  • теперь, если проект B также ссылается на проект A
  • тогда, когда один из них изменяется, другой нужно перестроить
  • из-за чего другой должен быть перестроен
  • из-за чего другой должен быть перестроен
  • и др.

это потенциально бесконечный цикл в процессе сборки

Ответ 6

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

Ответ 7

Hm, я думаю, что в терминах вопроса OP, о проектах Building с нуля, это плохая практика, из-за:

  • Неспособность построить из исходного кода/нуля - что, если я поддерживаю несколько версий кода. Между каждой версией было сделано несколько изменений в каждой из библиотек. Единственный способ, которым я могу поддерживать эти параллельные версии, - это сохранить скомпилированные двоичные файлы в моем управлении версиями. Это также означает, что сравнение между каждой версией библиотеки намного сложнее. (Мне нужно выяснить, какая версия используется, а затем взглянуть на фактический исходный код для lib, а не просто на прямой diff на самом источнике.
  • Возможно, сложнее вытолкнуть исправления для клиентов, которые имеют поэтапно исправленные версии. Где и что нужно запланировать?

Ответ 8

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

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

Кроме того, MSBuild позволяет использовать файл SLN для создания всего, если все ваши проекты используют VB или С#. Это позволяет создать файл uber-solution, который идеально подходит для процесса автоматической сборки. Уловка заключается в том, что для того, чтобы такой файл главного решения работал, все проекты в SLN должны использовать ссылки на проекты. Поэтому, чтобы воспользоваться этим, по определению, Microsoft ожидает, что вы не используете круговые ссылки, поскольку они явно запрещены средой Visual Studio IDE (для ссылок на проекты).

Скотт Хансельман ссылается на файл uber-solution в следующем сообщении:
Hack: параллельные MSBuild из среды Visual Studio IDE
http://www.hanselman.com/blog/CategoryView.aspx?category=MSBuild