Почему циклические ссылки в Visual Studio - плохая практика? - PullRequest
30 голосов
/ 21 ноября 2008

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

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

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

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

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

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

Ответы [ 8 ]

40 голосов
/ 21 ноября 2008

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

23 голосов
/ 21 ноября 2008

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

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

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

Sheesh.

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

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

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

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

13 голосов
/ 21 ноября 2008

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

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

3 голосов
/ 21 ноября 2008

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

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

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

1 голос
/ 25 июня 2009

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

1 голос
/ 21 ноября 2008

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

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

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

0 голосов
/ 17 апреля 2009

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

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

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

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

0 голосов
/ 21 ноября 2008

Хм, я думаю, что с точки зрения ОП вопрос о строительстве проектов с нуля, это плохая практика, из-за:

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