Является ли subversion externals антипаттерном?


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

хотя они кажутся идеальными для повторного использования библиотек и контроля версий поставщик программного обеспечения, они не без их критики:

пожалуйста, не используйте Subversion externals (или аналогичные в других инструментах), они являются анти-шаблоном и, следовательно, ненужные

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

7 68

7 ответов:

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

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

в дальнейшем, объясняя мой комментарий, позвольте мне сначала сказать, что есть "безопасные" способы использования svn:external-как функция, так же, как с любым другим инструментом или функцией. Однако я называю его антиобразец потому что эта функция гораздо более вероятно, чтобы быть использованы. По моему опыту, он всегда был неправильно использован, и я нахожу себя очень маловероятным, чтобы когда-либо использовать его таким безопасным способом или когда-либо рекомендовать это использование. Пожалуйста, обратите внимание, что я не имею в виду никакого пренебрежения к команде Subversion-я люблю Subversion, хотя я планирую перейти на Bazaar.

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

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

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

Итак, что же такое "безопасный" способ использования этой функции? Я считаю, что будет, когда он временно используется только одним человеком, например, способ "настроить" рабочую среду. Я мог видеть, где программист может создать свою собственную папку в репозитории (или один для каждого программиста), где они будут настраивать svn:external ссылки на различные другие части хранилища, которое в настоящее время они работают над этим. Затем проверка этой одной папки создаст рабочую копию всех их текущих проектов. Когда проект добавлен или завершен,svn:external определения могут быть скорректированы и рабочая копия обновляется соответствующим образом. Однако я предпочитаю подход, который не привязан к конкретной системе управления версиями, например, делать это со скриптом, который вызывает проверки.

для записи, мой последний контакт с этой проблемой произошел летом 2008 года на консультационном клиенте, который использовал svn:external в массовом масштабе -- все было сшито, чтобы создать единую мастерскую рабочую копию. Их сценарии сборки на основе Ant & Jython (для WebLogic) были построены поверх этой основной рабочей копии. Конечный результат: ничто не могло быть построено отдельно, были буквально десятки подпроектов, но ни один не был безопасным для проверки/работы сам по себе. Поэтому любая работа на этой системе сначала требовала проверки / обновления более 2 ГБ файлов (они ставили бинарники в репозитории). Делать что-либо было упражнением в тщетности, и я ушел после трех месяцев попыток (было много других антипаттернов).

EDIT: Expound на рекурсивных построениях -

за эти годы (особенно в последнее десятилетие) я построил массивные системы для компаний Fortune 500 и крупных государственных учреждений, включающих в себя множество десятков подпроектов, расположенных в иерархиях каталогов, которые имеют много уровней глубины. Я использовал Проекты/решения Microsoft Visual Studio для организации систем на основе .NET, Ant или Maven 2 для систем на основе Java, и я начал использовать distutils и setuptools (easyinstall) для систем на основе Python. Эти системы также включали огромные базы данных, как правило, в Oracle или Microsoft SQL Server.

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

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

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

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

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

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

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

наконец, построение массивной иерархии проектов может быть просто слишком интенсивным. Например, весной 2007 года я попытался создать скромную исходную иерархию (Java plus Oracle), которая Я построил с помощью Ant, который в конечном итоге потерпел неудачу, потому что сборка всегда прерывалась с помощью Java OutOfMemoryException. Это было на рабочей станции 2 GB RAM с 3,5 GB swap space, для которой я настроил JVM, чтобы иметь возможность использовать всю доступную память. Приложение / система была относительно тривиальной с точки зрения количества кода, но рекурсивные вызовы сборки в конечном итоге исчерпали память, независимо от того, сколько памяти я ей дал. Конечно, это также заняло целую вечность, чтобы выполнить (30-60 минут было обычным делом, до того, как он прервался). Я знаю, как настроить очень хорошо, но в конечном итоге я просто превысил пределы инструментов (Java/Ant в этом случае).

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

изменить: больше на антимоделей

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

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

однако иногда кажется особенно оправданным сделать эту растяжку, например, в этом случае. Некоторые инструменты, похоже, "приводят" пользователя к определенным методам их применения, до такой степени, что некоторые утверждают, что инструменты формируют мысль (немного перефразированный.) Именно в этом духе я и предлагаю svn:external - это антипаттерн.

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

правильная обработка зависимостей между проектами включает в себя обращение к этой динамике вместе с базовой проблемой, а инструменты и методы ведут по другому пути. Примером, который следует учитывать, является Айви, что помогает таким же образом, как Maven, но без многих недостатков. Я исследую Ivy в сочетании с Ant, как мое краткосрочное решение проблемы сборки Java. В долгосрочной перспективе, я ищу, чтобы включить основные концепции и функции в инструмент с открытым исходным кодом, который облегчает мультиплатформенное решение.

Я не думаю, что это анти-паттерн вообще. Я сделал несколько быстрых поисков в google и ничего не придумал... никто не жалуется, что использование svn:externals плохо или вредно. Конечно, есть некоторые предостережения, которые вы должны знать... и это не то, что вы должны просто сильно брызгают во все ваши репозитории... но что касается оригинальной цитаты, то это просто его личное (и субъективное) мнение. Он никогда не обсуждал svn: externals, за исключением осуждайте их как анти-образец. Такие громкие заявления без какой-либо поддержки или, по крайней мере, рассуждения о том, как человек пришел, чтобы сделать заявление, всегда вызывают подозрения.

тем не менее, есть некоторые проблемы с использованием внешних. Как ответил Майк, они могут быть очень полезны для указания на стабильные ветви выпущенного программного обеспечения... особенно программное обеспечение, которое вы уже контролируете. Мы используем их внутренне в ряде проектов для служебных библиотек и тому подобное. У нас есть небольшая группа, которая улучшает и работает на базе библиотеки утилит, но этот базовый код является общим для нескольких проектов. Мы не хотим, чтобы различные команды просто проверяли код проекта утилиты, и мы не хотим иметь дело с миллионом ветвей, поэтому для нас svn:externals работает очень хорошо. Для некоторых людей, они не могут быть ответом. Однако я бы категорически не согласился с утверждением "пожалуйста, не используйте..."и что эти инструменты представляют собой анти-паттерн.

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

лично я использую только svn: externals, чтобы указать на "стабильные" ветви репозитория, которым я владею.

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

для некоторых наших внутренних библиотек, которые мы используйте в качестве внешних в наших проектах конечных пользователей, я нашел полезным создать тег библиотеки в Major.Второстепенная версия, где мы не применяем никаких критических изменений. С четырехточечной схемой управления версиями (Мажор.Незначительный.исправление ошибки.Build), мы позволяем тегу оставаться в актуальном состоянии с исправлением ошибок.Создайте изменения (опять же, не применяя никаких критических изменений). Это позволяет нам использовать внешнюю ссылку на тег без номера редакции. В случае серьезных или других критических изменений, новый тег создан.

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

Если обычный внешний является анти-шаблоном, потому что он может сломать ваш репозиторий, то один с явной ревизией не должен.

фрагмент svn book:

внешнее определение-это сопоставление локального каталога с URL**-и, возможно, конкретной версией-**версионного ресурса.

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

в Subversion есть определенные недостатки, но мы, похоже, используем их достаточно успешно для включения библиотек (как наших собственных, так и поставщиков), от которых зависит текущий проект. Поэтому я не вижу их как "анти-паттерн". Важными пунктами использования для меня являются:

  • Они указывают на определенную ревизию или тег (не руководитель) из другого проекта.
  • они вставляются в текущий проект далеко от его собственного исходного кода и т. д. (Например, в a подкаталог называется "файлы поддержки").
  • Они относятся только к другим файлам "интерфейса" проектов (например, включают папку) и двоичным библиотекам (т. е. мы не получаем полный источник другого проекта).

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

сказав, что a - это b не делают a a b Если ты не скажешь почему это так.

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

Subversion внешние ссылки могут быть использованы, и злоупотреблять, и объект сам по себе только что функция. Нельзя сказать быть шаблон, ни антиобразец.

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

Да, вы можете использовать его неправильно, не указывая конкретно, какая версия этой ссылки вам нужна. Это создаст вам проблемы? Скорее всего!

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