Работа с трудными Legacy проектами
О том, как создавать проекты, строить архитектуру и писать приложения с нуля, пишется много материала каждый день. Люди, одержимые идеями быстрых стартов, делятся своим опытом на страницах линкедина, семинарах, пресс-конференциях и подкастах, попивая кофе в бездонных худи.

Однако редко можно услышать, кто с таким же энтузиазмом рассказывает о другой стороне разработки ПО, а именно о работе с legacy или просто запущенным в production проектом.
В этой статье хотелось бы привести пример ситуации возобновления разработки над ПО и предложить примерный план действий. Это не будет являться универсальным объяснением howto, но может дать представление о том, что может происходить в ситуациях подобного рода. Также хотелось бы ограничиться разбором самого худшего из возможных сценариев и дать ему заодно определение. Возможно это подскажет тем, кто еще раздумывает, стоит ли тратить деньги и снова нанять команду странных ребят копаться в штуке, которую для вас сделали другие странные ребята.
Как понять, что ваш случай worst case scenario?
1

По цели и функционалу продукта:

  • продукт сложнее личного блога и был разработан меньше, чем за квартал.
Иногда энтузиазм заказчика обусловлен тем, что его знакомый сделал для него версию, которую можно пощупать и потыкать за 2 месяца. Если это не кулинарный блог, то нужно поддерживать настрой заказчика до того момента, пока вы не начнете обсуждать проблемы.

  • функционал, необходимый заказчику, был не реализован, а добавлен по ходу разработки.
Пример ситуации: изначально проект разрабатывался как площадка для торговли, но потом команда маркетологов и product-owner решили, что на нём не хватает элемента социальных сетей и решили , что у продавцов и покупателей должны быть личные странички, они могут делать публикации
и писать комментарии друг другу. Всё это должно быть динамичным и алгоритмы сортировки должны обрабатывать такой контент. Пример довольно грубый, потому что такие перерождения вообще сами по себе нехороший знак в целом, но суть такова: если в начале проекта заказчик имел одну цель, а где-то посередине он решил, что ему чего-то критически не хватает и это улучшение в принципе не особенно связано с основным функционалом, то при возобновлении работ и улучшениях это будет добавлять незапланированной нагрузки.

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

По качеству взаимодействия:

1
после заполнения данными приложение стало работать заметно хуже
  1. Чаще всего “заметно хуже” - падение скорости. Тут есть два варианта:
  2. быстродействие заметно, но плавно ухудшилось, после нескольких лет эксплуатации и больших объемов сохраненных связанных данных
  3. быстродействие заметно и быстро ухудшилось за краткий срок (полгода) при больших, но не связанных объемах данных
Оба таких решения предполагают проблемы с архитектурой базы данных и её использованием вопрос лишь в том, будет ли команда улучшать её или исправлять (либо и то, и другое).
2
в некоторых частях приложения наблюдается явно незапланированное поведение, но продуктом всё еще можно пользоваться
Это лучше всего описывается фразой заказчика "Когда делаешь Х вот здесь, то тут почему-то происходит Y, хотя не должно, но в целом все работает правильно"
3
во многих инстанциях/страницах/сценариях использования существует множество путей взаимодействия, которые по идее должны приводить к одинаковому результату, но это не так
Например, пользователь может сохранить одинаковый набор данных на двух и более страницах, но при сохранении он может получить разный результат
4
пользователь часто сталкивается с ошибками 40*(404, 403, 400) и даже 50* без обработки сервисом
Сами по себе 40Х ошибки не так страшны, если такое поведение задумано, однако, если пользователь может внезапно получить пустой экран с 404, 403 или любую из ошибок с кодом 50Х, то продукт явно работает не так, как должен.
3

По безопасности данных и доступу:

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

По инфраструктуре:

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

По коммуникативным признакам:

  • у заказчика есть не письменный источник “сакральных знаний”. Под сакральными знаниями в мире разработки понимается совокупность знаний о проекте, которые не являются очевидными. Такую информацию необходимо где-то документировать. Это может делать и команда разработки, и заказчик (в идеале - оба), но одно техзадание такой информацией считаться не может.
  • каждое новое пожелание заказчика реализовывалось предыдущей командой за всё большее и большее время. Это лучше всего описывается понятие энтропия в ПО. Чем дольше существует и развивается ваш проект, тем он становится сложнее и тем больше в его состоянии хаоса. Эту характеристику нельзя измерить, но можно за ней проследить, ее рост - неизбежен, однако при структурированном, упорядоченном подходе, отлаженности рабочих процессов, ведении документации, использования вспомогательных систем и стабильной инфраструктуры энтропия будет расти медленно.
  • предыдущая команда не писала тесты. Некоторые заказчики полагают, что написание тестов это лишнее и только увеличивает бюджет и время
разработки. Но на самом деле, хотят они это понимать или нет, тесты это один из самых верных способов сдерживания
энтропии, сокращения расходов и уменьшения времени на дебаггинг.
  • в проекте отсутствует сборщик ошибок. Логи без инструмента обработки - не сборщик ошибок. Лучшее описание пунктов c и d можно выразить так:

нет тестов + нет сборщика ошибок = всё чинится через просмотр логов = много времени = много багов = много часов разработки = большие затраты

При всём при этом заказчик уверен в том, что он не только хочет, чтобы сервис работал лучше, но он еще хочет расширять возможности, подключать сторонние решение и т.д.
Что делать?
Если галочку можно поставить практически у каждого пункта предыдущего списка, то ситуацию можно охарактеризовать как MVP внезапно перешел в коммерческое использование и лучшее его описание можно найти здесь. В лучшем мире такое никогда не происходит.
К чему должен готовиться заказчик:

К чему готовится команда разработки:

  1. самое базовое в начале работ:
  • отладить стадию тестирования
  • подключить debugging инструмент
  • начать документирование
2. “если оно работает, то не нужно это трогать”.
Менять что-то, даже внося мелкие изменения, может быть рискованно. Поэтому Нужно готовиться к тому, что придется писать всё заново, где-то копируя и заимствуя старые функции и flow и следуя правилу разделения окружений и тестируя компоненты!
3. как можно скорее разобраться с базой данных и её структурой.
Если её придется менять, то делайте как можно больше бекапов на каждом шаге
4. искать способы сегментирования логики.
Если проект на Django и framework относится к MVC - нужно придерживаться этого - разделить на model-view-controller
5. писать тесты, писать тесты и писать тесты
6. атомарность и автоматизация:
  • процесс поставки и интеграции изменений должен быть как можно более автоматическим
  • процесс тестирования должен быть автоматическим
  • процесс запуска вспомогательных сервисов должен быть автоматическим
  • действия должны быть атомарными.
Made on
Tilda