После недавнего твита Илона Маска о том, что Twitter в конечном итоге потребуется полностью переписать, комментаторы-программисты увлеклись комедией, а некоторые предполагают, что теперь он достиг менталитета инженера среднего уровня. Поделившись твитом Маска, Амит Гупта, технический директор Food Market Hub, предположил, что из-за непрерывного развития программного обеспечения через три-четыре года возникает необходимость обсудить переписывание конкретного компонента или системы.

‍Это вызвало оживленную дискуссию между разработчиками в сообществе F’in Tech по извечному вопросу: Что лучше: переписать или обновить существующий код? В этой статье я описываю суть этой дилеммы, а также некоторые основные выводы из нашего разговора, отражая размышления тех, кто был в окопах и может поделиться опытом.‍

Лучше Дьявол, которого ты знаешь

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

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

‍Сложность лежит под поверхностью. Как правило, кодовые базы со временем развиваются, а исправления и нюансы требований встраиваются в код без последовательного документирования. Попытка переписать без всестороннего понимания того, что уже есть, может постоянно выявлять новые требования, часто во время приемочного тестирования пользователями. Это может затянуться на неопределенный срок, разочаровав ваших пользователей и сорвать ваши сроки. Как лаконично выразился советник F’in Tech Сэм Симопулос: «Эти вещи никогда не заканчиваются по-настоящему».

Скрытые ошибки ниже ватерлинии (Midjourney)

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

Не только техника

‍При полном переписывании (или значительном обновлении) важно учитывать потребности и ожидания пользователей, а также помнить о назначении продукта. Это максимизирует вероятность того, что то, что переписывается, соответствует цели. Джерри Энг, основатель и технический директор CoinHako, исходит из этого: «Часто это не только техническое переписывание, но и переписывание требований к продукту — призыв удалить устаревшие функции или ограничения может помочь разблокировать многие вещи». Однако это должен быть сбалансированный подход, так как он еще больше увеличивает потенциальный риск переписывания, особенно если видение продукта и технической команды не совпадают на 100%.‍

Что вы делаете, если система настолько запутана, что вы буквально не можете разумно извлечь из нее модули и, таким образом, вынуждаете полностью переписать? — спросила Нино Ульсамер в Сташавее. Он считает возможным, что при достаточной поддержке старшего руководства можно сосредоточить достаточно внимания и ресурсов, чтобы переписать работу. Переписывание все еще может работать, но оно должно быть закреплено на самом высоком уровне. Возможно, это невозможно без поддержки со стороны основателя-технического директора. Это не распространено, но не невозможно, как показал Uber с личным участием тогдашнего генерального директора Трэвиса Каланика. Подобные истории также раскрывают уровень товарищества, которое может проявиться в окопах, когда удается совершить невозможное.‍

Не недооценивайте данные

Как размышляет Кристиан Фишер, руководитель отдела разработки ADDX: «Настоящая боль после перезаписи — это миграция данных!» Без итеративного плана сложность переноса данных оставляет два возможных варианта:

  1. Переход «большого взрыва» с внезапным переходом от старой системы к новой.
  2. Запустите синхронизацию для двух наборов данных со «старым» набором данных, поддерживающим старые процессы‍

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

Часто инженеры пытаются синхронизировать наборы данных между старой и новой системами, чтобы сохранить гибкость, например, запуская один процесс из одного набора данных, а другой — из другого. Хотя это разумно, это добавляет новый уровень сложности в обеспечении согласования систем друг с другом для обеспечения согласованности, особенно если модели данных между двумя системами различаются. Поэтому нам нужно подумать о подходах, которые позволят нам повторять один и тот же набор данных‍.

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

Сделай это так

Как отмечает Диего Рохас, технический директор Tribe FinTech, «конечно, системы/продукты должны продолжать развиваться, мигрировать и изменяться, но это итеративный/постепенный процесс, пока основные риски не будут снижены». Изменения неизбежны, но то, как мы реализуем эти изменения, находится под нашим контролем, и целью является минимизация риска.

Как объяснил Манодж Авасти, технический директор Julo, большинство опытных инженеров попытаются переписать код, используя паттерн Strangler Fig Pattern. В этом захватывающем экологическом явлении вид инжира, известный как инжир-душитель, прорастает на дереве-хозяине и растет вокруг его ствола. По мере роста инжира его корни постепенно охватывают и сжимают дерево-хозяин, в результате чего оно ослабевает и в конечном итоге погибает. Корни инжира утолщаются и сливаются вместе, образуя плотную решетку, которая полностью окружает ствол дерева-хозяина, позволяя инжиру продолжать расти, питаясь деревом-хозяином.‍

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

Для реализации этого шаблона ключевые функции устаревшей системы идентифицируются и реализуются в новой системе по модульному принципу. Исходная система продолжает работать параллельно, в то время как в новую систему переносится больше функций. Зависимость от устаревшей системы уменьшается до тех пор, пока ее в конечном итоге нельзя будет вывести из эксплуатации. По словам Санни Сингха из штаб-квартиры, лучший подход — переписывать определенные модули по мере того, как вы касаетесь определенных частей кодовой базы. Тем не менее, рассмотрение ROI имеет решающее значение, чтобы избежать чрезмерных усилий для небольшой отдачи.

Шаблон инжира-душителя в действии (Midjourney)

«Некрасивые» переписывания можно считать пустой тратой времени: если вы переписываете приложение, то с тем же успехом можете его правильно собрать, верно? К сожалению, как отметил Томас Чиа, технический директор Chocolate Finance, это нарушает закон Галла. Мы пытаемся перейти к сложности и, таким образом, обречены на провал. Необходимо вносить непрерывный набор небольших изменений, чтобы постепенно заменять устаревшие системы новыми приложениями. Этот подход почти всегда требует набора «уродливых» промежуточных шагов, но каждая итерация используется реальными пользователями — доказывая, что он действительно работает.‍

Итак, переписать или обновить? В совокупности технические директора говорят: постарайтесь этого не делать! Но если ваш единственный вариант — переписать, попробуйте сделать это небольшими итеративными шагами, составьте план переноса данных, который минимизирует сбои, и убедитесь, что существует четкое согласование с высшим руководством. Но если вы инженер среднего звена, который прочитал это и подумал: «Эти ребята недостаточно хардкорны», то я слышал, что Илон нанимает…‍

Выражаем благодарность Маноджу Авасти, Томасу Чиа, Джерри Энгу, Кристиану Фишеру, Амиту Гупте, Илону Маску, Диего Рохасу, Сэму Симопулосу, Санни Сингху, Нино Ульсамер и всем участникам сообщества F'in Tech.