Как управлять изменениями фреймворка?

Я постараюсь быть кратким, чтобы не превратить это в сообщение в блоге. Если есть конкретные вопросы, дайте мне знать, и я постараюсь на них ответить.

По сути, меня интересует, какие методологии придумали люди, какие преимущества и недостатки они испытали при управлении переходом проекта с одного фреймворка (или одного языка программирования, или одного стека технологий) на другой.

Установка

Предположим, у вас есть простое веб-приложение, написанное на некогда популярной серверной платформе, которое работает на одном сервере Apache/Nginx/любом другом и доставляет страницы, отображаемые на стороне сервера. Каждый раз, когда пользователь щелкает ссылку для выполнения действия, запрос отправляется на сервер, один сервер обрабатывает запрос, подключается к одной базе данных, вносит изменения, а затем предоставляет новую страницу с видимыми результатами своего действия.

Теперь предположим, что за 10 лет ваше приложение превратилось в широко популярного гиганта, и вы сталкиваетесь с проблемами масштабирования, проблемами с производительностью, вы не можете создавать функции очень быстро, потому что весь код тесно связан, некоторые громкие имена начали появляться в зависимости от того, является ли ваш сервис «Всегда доступным» ™, или по какой-то другой причине вам теперь нужно изменить движок, лежащий в основе вашего приложения.

После нескольких недель исследований вы, возможно, приняли одно небольшое решение, например «Давайте использовать React и перенесем большую часть обработки и логики отображения на ЦП клиента», или, возможно, вы приняли несколько решений, включающих разделение вашего приложения на несколько микросервисов и переизобретение базы данных с использованием алгоритма уменьшения карты и всплеск машинного обучения. Каким бы ни было окончательное решение, вам необходимо сохранить паритет функций со старым приложением и перенести его на новый фреймворк.

Вопрос

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

Вы относитесь к этому так, будто создаете новое приложение с нуля, а каждая функция в старом приложении — это просто история пользователя в новом?

Или вы рассматриваете это как новую функцию для существующего приложения?

Следует ли вам отделить старый код и начать переработку новой ветки старого репозитория?

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

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

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

Теги

Я буквально понятия не имел, какие теги выбрать. Пожалуйста помоги.

Ответы (2)

Я делал это пару раз, хотя это не всегда было веб-приложением и не из соображений масштабирования. Вот что мы сделали:

  • Относитесь к нему как к новому приложению. В нашем случае мы переименовали приложение, когда сделали это.
  • Поместите его в собственное репо.
  • Приостановить разработку на старом, за исключением критических исправлений, чтобы все ресурсы можно было направить на миграцию.
  • Сократите набор функций, если это возможно, по крайней мере, для первого выпуска. Например, если у вас есть функции, которые редко используются, если вообще когда-либо используются, не связывайтесь с ними. Очевидно, делайте это, консультируясь с заинтересованными сторонами, объясняя, что вы пытаетесь управлять объемом работ, чтобы график был разумным.
  • Четко определите критерии приемки. Помогите заинтересованным сторонам понять, почему поведение, внешний вид или результаты могут не совпадать из-за скрытых вещей, о которых они обычно не задумываются, и/или из-за того, что в новую структуру встроены другие вещи.
  • Ожидайте, что вы найдете ошибки в существующем коде, которые должны быть исправлены в новом коде. Однако имейте в виду, что вам может потребоваться исправить новый код, чтобы воспроизвести плохое поведение старого кода для упрощения приемочного тестирования, с пониманием того, что после принятия вы удалите эти исправления и получите одобрение нового поведения.
  • Не поддавайтесь искушению внести изменения или улучшения в поведение во время миграции. Файловые билеты для них; возможно, оставить для них архитектурные зацепки или комментарии в коде; но не пытайтесь одновременно «мигрировать на новый фреймворк» и «изменить существующее поведение».
  • Запланируйте в конце написать отчет о вводе в эксплуатацию, в котором будет объяснено, как вы сверяли новый код со старым, и учтены любые внесенные изменения, включая приложение с любыми соответствующими отчетами о тестировании. Пишите по ходу, это избавит вас от горя позже.
  • Позвольте себе большой перерыв в своем графике, потому что вы, вероятно, столкнетесь с непредвиденными техническими трудностями. Всегда лучше меньше обещать и делать больше.
  • Убедитесь, что ваши заинтересованные стороны знают об этом графике, и поддержите его заранее. Это управляет ожиданиями и дает вам что-то, на что можно указать, когда они начинают терять терпение из-за того, что это занимает так много времени.

Пара технических моментов:

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

Существует противоречие между выполнением в первую очередь простых вещей, чтобы вы могли проверить концепцию и как можно скорее запустить и проверить подмножество, и выполнением в первую очередь самых сложных вещей, чтобы вам не пришлось перестраивать архитектуру. наполовину. Обычное agile-предложение делать простейшие вещи, которые работают, и проводить рефакторинг по мере необходимости, по моему мнению, немного не соответствует этой ситуации, потому что в этом случае вы ДЕЙСТВИТЕЛЬНО знаете, что «вам это понадобится». Я мог бы предложить, чтобы часть команды инвестировала в анализ наиболее сложных битов, пока идет начальная инфраструктура, выбор технологий / кривая обучения и т. Д.

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

Надеюсь это поможет! Мне будут интересны и другие ответы.

Я не думаю, что есть "правильный" ответ на этот вопрос. Ответ Вики совершенно правильный. Я собираюсь дать другой ответ, который я считаю также правильным.

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

Легко, верно? Ну, есть несколько вещей, которые следует учитывать:

1) код вашего приложения слабо связан или, что еще лучше, развязан? Сколько частей вы можете выделить? Если у вас много тесно связанных компонентов, вы, вероятно, застряли в подходе с полной заменой, как предлагает Вики, или вам нужно приложить некоторые усилия для улучшения архитектуры и удобства обслуживания вашего приложения, прежде чем вы сможете делать что-либо еще.

2) Небольшие частичные исправления или большие исправления? Возьмем ваш пример с React. Предположим на мгновение, что ваш существующий пользовательский интерфейс взаимодействует с веб-службами для бизнес-логики. Вы можете просто заменить всю сторону пользовательского интерфейса и позволить реагировать на взаимодействие с веб-сервисами. Это также может означать некоторую настройку веб-служб для REST, если вы ранее использовали SOAP или протокол веб-службы Microsoft. Это большое решение проблемы с ресурсами. С другой стороны, небольшое исправление может быть таким же простым, как добавление оборудования или решение для балансировки нагрузки. Это может не решить проблему навсегда, но может привести к значительному уменьшению проблемы в невыполненной работе. За стоимость одного или трех серверов вы только что купили себе год в своем приложении и можете сосредоточиться на других проблемах, которые сложнее решить, чем покупка дополнительных процессоров.

3) Сосредоточьтесь на решении проблем, а не на реализации проектов. Для каждого из этих элементов цель состоит в том, чтобы увеличить скорость загрузки на величину X или уменьшить количество ошибок до порогового значения Y. Если вы просто реализуете предопределенное решение по крупицам, вам может быть лучше использовать подход полной замены, потому что вы все равно делаете это в основном. Этот подход окупается только в том случае, если вы получаете выгоду от решения каждой проблемы по ходу дела.

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