Автор оригинала: Pakal de Bonchamp.
Почему обратно соответствует совместимости
(Если вы уже убеждены, что стабильность API является решающей проблемой, а не прихоть из нескольких консервативных мумий, спасай себя некоторое время и спешит в следующую главу.)
Это Известный Рэн из Линуса Торвальдс это, увы, более актуально, чем когда-либо.
Давайте заменим «ядро» любыми рамочными/библиотеками и «значением ошибки» «подписью API», и мы получаем бесценную заповедь хорошего программирования. Мы можем жить довольно хорошо с несколькими бугочками и несовершенными функциями, но когда наши приложения доставляют SegFaults или длинные трассировки после простого обновления версии, возникает проблема. Настоящая проблема.
И здесь есть парадокс. Что касается распределений ОС, драйверов, Libc/GTK/QT и других низкоуровневых, статически набранных библиотек, мы ожидаем – и рады испытать – безболезненные обновления, приносящие только новые функции и исправления. Принимая во внимание, что для наших веб-каркасов высокого уровня, в основном закодированной на динамических языках, мы стали уйти в отставку к тому факту, что каждое обновление может стать 3-дневным трудом понимания поломок, нахождение совместимых версий зависимостей, а также перехватывания или обезьян. Люксы снова зеленые. Логично, это не должно быть наоборот? Почему большинство в 1995 году Win32 Freewares все еще работает, почему миграция X32/X64 такая прозрачная для большинства пользователей, если приложение подключаемого сервера выпущено 2 года назад, сломано на нескольких аспектах?
Я скажу вам, почему.
Стабильность API однажды была очень высоко оценена обязательством. Семантическая версификация была обязательной. Проекты, такие как QT, гордо подробные меры, которые они взяли, чтобы обеспечить их C/C ++, будет развиваться без поломок. Некоторые даже заполнили свои параметры функции с нулевыми значениями «зарезервированы для будущего использования». И несовместимые изменения были отклонены только тогда, когда не можно найти решение.
К счастью, это мышление все еще действует в больших областях программирования. Но теперь другая философия имеет загрязненные умы, особенно в веб-индустрии. Этот спартанский образ мышления можно назвать «прогуляться или умереть», «нет рая для слабых», или «до тех пор, пока я предупреждаю, я могу стрелять в пулю». Иногда прячутся за милыми понятиями, как «календарь», или «вечнозеленые приложения», или «вечнозеленые приложения», этот образ мышления на самом деле кристально-ясным: самым незначительным обновлением программного обеспечения может ввести изменения – документированные или нет, гордо предполагаемые или нет – просто разобраться с ним Отказ
Почему? Почему бы не просто пускать псевдонимы, адаптеры и другие прокладки совместимости, при перемещении модулей вокруг, при переименовании объектов, при изменении функциональных подписей? С динамической и интроспективной природой самых современных языков, не так ли ветер? Иногда ресурсы развития настолько скудны, что это уже слишком много. Но в остальное время? Я предполагаю, что когда это не проблема технических навыков, ни о лени, это может быть культурной проблемой.
Знаете ли вы, что этот дофамин ударил вас, когда вы отметите коробку в контрольном списке, особенно последний? Это удовлетворение, которое иногда заставляет вас написать уже выполненную задачу просто так вы можете отметить это ? Вы можете получить то же самое ощущение, когда вы жестоко ревертируете код в более чистой архитектуре или стираете совместимость прокладок « согласно политике амортизации ». Это счастье потрясения долга, молодцы, возвращения к чистоте.
Но это точное чувство – огромная ложь. Ослепительное самопоглощение. Вредная психологическая смещение.
Шимс совместимости не является техническим долгом; ни набор бородавок. Напротив, они являются неоценимыми активами. Благодаря этим нескольким кускам исходного кода наше программное обеспечение расширяет свою совместимость на десятки, сотни, тысячи разных библиотек и приложений, распространяющихся в Интернете, как в государственных, так и в частных репозиториях, начиная от крошечных утилит в огромные корпоративные приложения. Эти зарубежные кодовые базы, полные бизнес-логики, о возможностях денег, особенно конкретным кодексом, являются то, что заставляют их основы стоит существовать.
Но эта экосистема имеет необычайное разнообразие. Некоторые репозитории получают коммуникацию каждый день от нескольких участников, некоторые получают массу обновления время от времени, когда их сопровождающие получают немного свободного времени, а некоторые не были тронуты в течение многих лет (потому что их создатель потерял интерес, или просто не мог найти ничего улучшить). У некоторых есть Tox, подобные многоможным тестированию и непрерывную интеграцию, некоторые даже не имеют единого теста.
Итак, что происходит, когда разработчики следуют этой модной «ходить или умереть» философию? Экосистема, уже сильно фрагментированная по языку (python2vs3, Ruby, Go, php … просто для динамических языков), по формату файла и сетевым протоколом, по стилю Framework и выполнения (синхронизация VS Async), становится фрагментом еще больше. В самый тихий и смертельный путь. В основном, если мы рассмотрим кодовые базы в зависимости от структуры или библиотеки (здесь называется «Программное обеспечение»):
- Репозитории, которые не были обновлены в течение нескольких лет, по умолчанию нарушены.
- Репозитории, которые активно поддерживаются, но не нацеливаются на ту же версию программного обеспечения, как и нас, тоже не работают.
- Опытные трекеры заполнены бесполезными «PLZ Добавить поддержку для версии X.y.z» или «Поддержка восстановления PLZ для версии X.y.z».
- Вилки процветают вокруг слегка известных репозиториев; вилки, которые не могут быть объединены, поскольку каждая из их модификаций весьма может нарушать вещи для других версий программного обеспечения; И последующие улучшения, привезенные каждым форкором, привязанным к расходящимся кодовым базам, продолжать распространяться, не состоявшаяся когда-либо слияние; Естественно, они получают переделанные несколькими разработчиками друг на сайте, так как немногие из них нашли время, чтобы рассмотреть график вил и интересные коммиты вишни.
- Самые большие проекты иногда получают достаточно хорошие, чтобы обеспечить матрицу совместимости или «известные рабочие наборы», прикрепленные к их номеру версии патча. Но, как только у вас есть более нескольких зависимостей, вы входите в зависимость от зависимости, что никакие алгоритмы разрешения конфликта не могут решать; Вам просто нужно вилочную, вилку, вилку и обезьяну-патч, пока ваши зависимости не найдут соглашения.
- Требования к проекту заполняются ссылками на Git Repository и совершать хэши; семантические данные, которые сделают следующие улучшения еще более неловко экспериментальными; или который исчезнет из-за неожиданного «силового толчка».
- Без удивления, многие сопровождающие эти подключаемые приложения не хотят брать на себя дополнительную нагрузку на заполнение их кода с особыми случаями, для работы вокруг разрыва о безубыточности разработчиков основных программ. В результате зависимость ад продолжает расширяться безудержно.
Поэтому, когда гордо волюряют название подмодуля, при удалении ясно используемого класса утилиты, при этом необязательный аргумент стал обязательным, мы ничего не улучшаем. Мы просто убиваем практичность ради эстетической чистоты. Мы безрассудно уничтожаем целые регионы экосистемы программного обеспечения, превращая газиллионы тестовых люков в красноватые кошмары. Но мы никогда не узнаем, в какой степени; Особенно, если мы не проверяем. Невежество – блаженство.
Биологические экосистемы могут достигать глубины пропасти или другим планетам, если у них есть много времени; Когда вещи меняются слишком быстро, это массовое вымирание. Экосистемы программного обеспечения не отличаются. Наслаждаясь чистотой API «Reamade с нуля», как наслаждаться микробным стерильным лесом, витрифицированным ядерным взрывом.
Наверняка, это ложь, чтобы подумать, что мы используем программное обеспечение с открытым исходным кодом, мы имеем право на получение ошибок и функций, которые мы запрашиваем. Но одинаково ложно, чтобы подумать, что потому, что пользователи наших рамках/библиотеки не платят клиентам, мы ничего не обязаны им. Они доверяли нам, построили свой собственный код против наших, следовали нашим конвенциям и лучшим практикам, когда они могли выбрать другой язык/рамки/библиотеку. Как мы можем оправдать вытаптывать свои собственные усилия, заставляя их отпустить дни или недели развития, только потому, что мы вдруг почувствовали нерепрессируемое желание изменить схему именования или падение идеальному рабочему коду? Мы все взаимозависимы от экосистемы программного обеспечения, а крошечная доза осознания, осторожность и рациональность могут пройти долгий путь. « Но вы никогда не уверены, что изменение не нарушает вещи », некоторые задумывают. Конечно. Никто не требует совершенства. Но не преднамеренно вредно это уже очень хорошее начало.
Там как от патерналистского настроения за некоторыми сторонниками подхода «прогулки или умирания». « Если мы придерживаемся стабильности API, участники будут ленивы и никогда не обновлять свои модули, экосистема будет гнить на месте вместо того, чтобы двигаться вперед ». Ой, блин, насколько это опасно, чтобы люди были добрыми против их воли. Если мы хотим, чтобы пользователи обновили свою кодовую базу, на самом противореку, мы должны начать с жестоко разбитых вещей. Мы должны принести блестящие новые черты, а не просто пистолет до головы. Мы должны позволить им починить слегка раздражающие «преданные пределы амортизации», когда они чувствуют себя и могут, а не прямо сейчас Отказ Мы должны позволить им проводить свое время на полезные взносы, а не на ремонт того, что мы сломали с запланированным устареванием, которую мы смеем называть «прогресс».
Забавные факты: рекламные изменения в заметках выпуска не дают им легитимность; И когда частное API так удобно, что он используется несколькими проектами, может быть, это признак того, что его следует обнародовать и задокументировать, не то, что он должен быть разрушен на первом импульсе.
Итак, давайте вырещимся в мраморе наших рабочих столов: API стабильность, должна быть, на нашем списке проблем; наряду с надежностью и адеквацией с нужными конечными пользователями; Но бесконечно выше любого эстетического рассмотрения. Только с долгосрочной совместимостью могут расти наши экосистемы программного обеспечения от короткой элиты постоянно обновляемых приложений, в огромную и разнообразную галактику модулей; Некоторые последние обновлены вчера, некоторые последние десять лет назад, но все они Получение вещей сделано Отказ Потому что то, о каком программном обеспечении все о том, и это то, что люди платят, в конце дня. Не тратя время, исправляя колесо, которое работало вчера, и не будет завтра больше, потому что мы слышали призвание пустоты.
Compat Concept Concept
Я спрашиваю (с открытым исходным кодом) сопровождающих программного обеспечения, чтобы приложить больше усилий, чтобы достичь этого настолько важнейшей долгосрочной стабильности API? Неа. Я не смею. Напротив, я прошу их быть лениве. Но хорошие, разумные, как самоинтересные, так и доброжелательные, вид ленивый.
Более совместимость означает меньшего количества запросов в поддержку, меньше времени оправдывания спорных изменений и дополнительных вкладов функций/ошибок из нашего сообщества. Больше совместимости даже не означает больше набора клавиатуры. За исключением случаев, если мы только в игрушечных проектах, мы уже на некоторое время помещали совместимость прокладок. Только одна вещь, чтобы сделать: оставьте их Отказ Они не причиняют нам боль. Они не тратят дисковое пространство. Они, вероятно, стоит тысячи долларов за персонаж. Давайте просто избегаем одной дистанции «Удаление совместимости Shim Xyz», и двигаться дальше к большим целям.
И если просто вид совместимости Шим делает нас рвоту (не очень необычную патологию), есть потрясающие новости: с языками высокого уровня нам больше не нужны прокладки в нашем коде. Мы просто должны принять концепцию Совместимость Patcher (или «Compatcher» для любителей неологизма).
Ват-ИЗ-Дат? Просто библиотека с компаньоном, часто живем своей собственной жизнью в собственном репозитории, которая подключается к настоящему программному обеспечению во время запуска и восстанавливает свою совместимость с десятилетом его предыдущих версий. Таким образом, мы можем сохранить нашу кодовую базу совершенно не знать о том, что может быть «амортизация», при этом сохраняя симбиотическое сосуществование с тысячами модулей, живущих в нашей экосистеме.
Обезьяна-исправляющая уродливая, кто-то сказал? Может быть, но никогда не такие уродливые, как проводить часы ретро-инженеров целый архитектуру плагинов, просто чтобы понять, что дополнительные «S» в соответствии с именами, чтобы испортить все. Программирование владельцев, которые могут предпочесть съедать свой код с внешними прокладками, используя Аспектно-ориентированное программирование , но для большинства из нас простые смертные, простота и прагматизм широко достаточно широко. Некоторая документация, регистрация и консольные предупреждения, являются «явными» достаточно, чтобы заставить кого-то контролировать контроль над кодовой базой.
Давайте не будем недооценивать силу языков высокого уровня. Примеры с Python. Мы переименовываем подмодуль? Хорошо, благодаря импортным крючкам, « из каркасных импорта OldModule » и « из каркасных импорта NewModule » вернет тот же объект. Мы меняем подпись функции? Одна крошечная инъекция позже старый набор параметров вызова автоматически адаптирован и переадресован к новой подписи. Мы перемещаем целую группу коммунальных услуг из основного хранилища? Хорошо, но до тех пор, пока нужна, Patcher совместимости принесет их из своего нового местоположения и закроет их, где они когда-то так хорошо принадлежали. Мы переименовываем константы, классы, функции? Выход из псевдонимов был затрагивал только одну линию кода, теперь с патчами совместимости этой строки даже не приходится причинять боль нашим глазам и сердцам.
Пожалуйста, обратите внимание, совместимость патчеров действует как время путешественников. Они работают даже когда разработчики удаляют функцию, повторно добавьте ее под другую форму, затем снова удалите ее. Они работают, даже когда разработчики безрассудно изменяют функциональные поведения, например, путем обмена подобными аргументами. Поэтому представьте, что, когда разработчики сотрудничают с этой системой, и красиво разделяют проблемы программирования, так что патч минимален!
Вишня на торте, отделяя «состояние искусства» кода и совместимость прокладок, Compat Patchers делают его ветером на Выборочно активируйте наборы совместимости Отказ Ваш проект совершенно новый и только полагается только на библиотеки кровотечения? Хорошо, деактивирует весь патчер. Вам просто нужна совместимость с последними двумя важными версиями рамки? Просто включите соответствующие семьи прокладок. Вам нужна поддержка очень старых пакетов? Оставьте конфигурацию патчей в максимальном режиме.
Сейчас приходит тревога-провоцирующая часть: каковы недостатки патчеров Compat? Ответ: до нескольких секунд задержки при запуске (когда все прокладки активированы), и несколько логических операций и тип проверки здесь и там во время выполнения. Вот и все. В современном веб-мире Web, где большинство серверных процессов выполняются в течение нескольких часов бесперебойных часов, обрабатывают наиболее неоптимизированные (текстовые) форматы, возможны, и где производительность зависит гораздо больше на оптимизации БД и правильной кэширования, чем на скорости выпуска необработанного, она звучит как законный Расходы, не так ли?
Редактировать : Еще одним ограничением Compat Patchers состоит в том, что им требуется крошечная малообеспечение сотрудничества от основных разработчиков. Действительно, мы все неявно знаем правила обратной совместимости: « Только добавьте дополнительно l». Добавить новые необязательные аргументы, добавьте новые функции, добавьте новые модули; Не удаляйте элементы и поведение, не делайте старые варианты обязательными. Но есть дополнительное, золотое правило: Никогда не измените семантические вещи на месте Отказ Если мы изменим значение аргумента, формат вывода, действие Callable, без какого-либо дополнительного индикатора, затем настройки прокладок становится (почти) невозможно; В этом случае даже Compat Patchers не смогут решить эту двусмысленность и угадать поведение, которое наши пользователи запрашивали при использовании нашего API. Давайте черный список навсегда этими видами Брутал и Изуивают изменения.
Время для практики!
Софтепунсы не просто желаемое мышление.
Вот один Для знаменитого веб-структуры Django. С несколькими десятками небольших фиксаторов он позволяет использовать подключаемые приложения, ориентируясь от версий от 1,6 до 2,2 рамки. И это только начало – запросы на функции и комментарии приветствуются.
Этот патчер используется в производстве на нескольких сайтах, включая ПИХРОНИЯ Портал и его CMS/Blog Ecosystem. Он работает на CompatPatchercore , микро-каркас Python для создания таких компаньонных приложений в мгновение ока (A рецепт кухонного рецепта даже включен).
Без удивления, я тепло побуждаю вас загрузить патчевителю Compate для рамки/библиотеки, которую вы можете поддерживать, если вы не являетесь одним из немногих доблестных умов, уже настоятельно приверженных стабильности API.
Эта концепция также должна быть легкой в порту в Ruby, PHP, JavaScript и других языках высококачественной активности. С более низким уровнем и статическими языками задача может быть намного сложнее (и требуют макро-процессоров и подобных), но кто знает.
Так что здесь мы. Обновление разрывов не являются смертностью. Просто плохая привычка, которую мы должны перерыв благодаря маленькому размышляю и несколько технических окуриев. Таким образом, мы можем наслаждаться прелестями постоянно растущих и постоянно работающих программных экосистем, те, которые делают развлечения и захватывающие!
Edit 2019/07/05: отклонить «твердое дефицит ресурсов» как возможную причину отсутствия прокладок и настроить тон этой части.
Edit 2019/07/14: Исправьте опечатки и предупредите от на месте семантических изменений.