The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:
Вы указываете точные версии своих зависимостей? Я имею в виду, когда ваш пакет программного обеспечения зависит от другого, вы записываете ли его версию, как 1.13.5
, или просто 1.+
, в своем pom.xml
, Gruntfile
, Gemfile
или другом файле? Я всегда считал, что лучше использовать точные номера версий, чтобы избежать так называемого ада зависимостей, и я не был одинок. Однако, очень скоро я понял, что динамические версии, такие как 1.+
, предоставляют большую гибкость. Всего несколько недель назад я понял, что ни один из подходов не является правильным, и разработал гибридную формулу. Неудивительно, я снова увидел, что я не был одинок.
Сначала позвольте мне объяснить, что не так с фиксированными зависимостями.
Предположим, что я создаю библиотеку X, которая зависит, например, от библиотеки ведения журнала, которая является сторонней библиотекой, а не моей. Таким образом, моя библиотека X имеет зависимость. Библиотека ведения журнала имеет номер версии, например, 1.13.5
. Я помещаю этот текст в файл pom.xml
X:
Многие сторонники фиксированных зависимостей утверждают, что очень важно придерживаться версии 1.13.5
, вместо использования более гибкой динамической версии: 1.13)
(т.е. любой версии, предоставленной, что она 1.13
или новее). Почему? Потому что будущие версии могут внести изменения, которые сломают сборку X. Они могут изменить интерфейсы, переименовать классы или методы, или удалить то, что я использую. Вы никогда не знаете, что могут сделать авторы этой библиотеки log-me
. Поэтому лучше жестко привязаться к 1.13.5
и считать это завершенным.
But.
Что, если библиотека X используется другой библиотекой Y, которая также зависит от “log-me”, но требуется версия “1.14.1”. Вот и проблема! В библиотеке Y возникнет конфликт: Maven, менеджер пакетов, не сможет решить, какую версию использовать. Понадобится некоторое разрешение конфликта. В случае с Maven это возможно, а в случае с, например, Rake, нет (насколько мне известно).
Чтобы решить эту проблему, библиотека Y должна явно указать, какую версию нужно использовать. Но она не может быть уверена, что “1.14.1” будет работать корректно с библиотекой X. Чтобы подтвердить это, авторы библиотеки X должны протестировать ее с этой версией. Так что все, что создатели библиотеки Y могут сделать, это попробовать и надеяться на лучшее. В случае с другими инструментами сборки, такими как Rake, у авторов не будет выбора, кроме как попросить авторов библиотеки X обновиться до “1.14.1” и выпустить новую версию. Затем библиотека Y сможет использовать библиотеку X.
Эта проблема не возникла бы, если бы библиотека X зависела от “1.13”. Но, как я упоминал ранее, в этом случае авторы библиотеки посадили бы “замедленную бомбу” — рано или поздно одна из будущих версий определенно сломает сборку.
Так в чем же решение?
Вот моя формула: если вы доверяете авторам библиотеки, используйте динамическую версионирование; если нет, используйте фиксированную версию.
Что я имею в виду, доверяете ли вы им, что они профессионалы, достаточно внимательные, чтобы думать о обратной совместимости и следовать принципам семантического версионирования? Если они достаточно осторожны, чтобы не удалять или изменять что-то, что может повлиять на будущие версии, не изменив при этом основной номер версии, то вы можете им доверять. Как узнать, кому можно доверять? Я не доверяю никому, кроме своих собственных библиотек и очень небольшого количества других библиотек, которые я изучил на GitHub и проверил качество их репозиториев.
Конечно, полностью доверять никому нельзя, но это формула, которую я использую сейчас. Вы можете посмотреть, как она работает в этом Gemfile, например. Обратите внимание на номера версий. Те, что начинаются с “~>” или “>=”, являются динамическими, а остальные являются фиксированными. Это гибридный подход, но он работает для меня.
Может быть, он поможет и вам.
Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-22 at 10:04