Обратная разработка
В 1968 году Мелвин Конвей написал работу «Как комитеты создают новое?». Кратко эта работа нам известна основным своим тезисом, известным как «закон Конвея». Но сейчас я хотел бы обратить внимание на другую цитату, из этой статьи:
«Есть ли предсказуемая связь между структурой проектной организации и структурой системы, которую она создаёт? Ответ: да, зависимость настолько проста, что в некоторых случаях идентична».
В каком бы направлении мы ни пошли, эта зависимость присутствует как в прямом, так и в обратном направлении. Это очень помогает, когда занимаешься обратной разработкой.
Представьте, что у вас есть активно работающая система, которой потребовалась доработка. Взявшись за дело, вы понимаете, что разработчиков уже не найти, документация либо разрознена, либо утеряна, либо неактуальна. Исходный код присутствует полностью или частично. Под системой будем понимать довольно сложный функционал, переписывание плюс тестирование которого превращается в процесс, который вряд ли впишется в отведённые сроки. Бизнес-задачи не ждут, они актуальны здесь и сейчас. И даже если вы пройдёте все круги ада проектирования, согласований, разработки и тестирования, создадите систему заново, то, скорее всего, опоздаете с предложением.
Для доработок сложных систем важно: ● Знать все бизнес-процессы, лежащие в основе работы системы. ● Иметь полную документацию. ● Понимать связи внутри системы и связи самой исследуемой системы с внешними системами. ● Знать порядок запуска, процесс управления, регламенты обслуживания и эксплуатации. ● Иметь список участвующего программного обеспечения. ● Видеть границы функционала.
Немного о последнем пункте. Границы функционала определяют пространства каждого из модулей, составляющих исследуемую систему. Какие задачи решает каждый из модулей? Каковы интерфейсы их взаимодействия? Часть функционала системы может находится в ведении других команд разработки, как часть другого функционала. Каковы рамки этих общих блоков? Поскольку в этом случае становится важна кооперация команд разработки при решении поставленной задачи.
Границы вкупе со взаимосвязями формируют пространство необходимого тестирования, в рамках которого можно не только протестировать новый функционал, но и говорить о том, что, как минимум, не затронут остальной, не требующий изменений. Это очень важно — не сломать то, что уже есть. В противном случае результат работы становится непредсказуемым. И неуправляемым в случае отсутствия полных знаний о системе.
Но это же доработка, скажете вы. Необязательно знать всё. Давайте изучим и доработаем один модуль, пусть даже перепишем! Один модуль не вся система.
Переписать не проблема, но надо знать что в рамках каких границ. Мы же не знаем чётких границ модулей. Кроме того, если вам доводилось декомпилировать продукт, дорабатывать полученное, а потом вновь его собирать, вы уже знакомы с тем фактом, что полученное не всегда может соответствовать исходному варианту.
Да, добавленное вами соответствует техническому заданию, но вот остальное (что должно было бы остаться неизменным) вдруг приобретает неожиданные оттенки в поведении вплоть до отказов. Полученные после декомпиляции исходники могут нести в себе ошибки, связанные с ограничениями самих декомпиляторов.
Чтобы избежать таких проявлений приходится не просто тестировать написанное, возникает необходимость тестировать вдоль и поперёк весь существующий функционал. И это при полном неведении в основах процессов, что составляют основу функционирования системы. Один элемент или все, суть проблемы здесь не меняется. Надо знать буквально всё.
А что же исходный код? Может, изначально стоит начать с него?
Предположим, у нас имеется некий исходный код, который (подобно документации) может быть отрывочным, устаревшим. Или содержать ветви, которые хоть и отражены в документации, однако, по разным причинам, не были включены в работу. Технически можно попробовать пройтись по связям и построить иерархическую модель. Однако здесь также есть неопределённости, влияющие на результат. С одной стороны, связи бывают неявными и практически не отслеживаемыми без понимания процесса работы. С другой, есть такая особенность: если «потянуть за ниточку» в двух разных местах, получишь две разные картины связей. Плюс размытость границ и недостоверная документация, минус понимание процессов.
Неумолимое время...
Перед разработчиком незнакомой системы так или иначе встаёт в полный рост задача обратной разработки, которая заключается в доскональном изучении предоставленного ему «чёрного ящика». Своеобразные археологические раскопки.
Чтобы понять цель и средства важно идти ab ovo: вернуться назад и разобраться, какие же процессы лежат в основе всего. Они формируют структуру системы как часть процесса проектирования, как один из его результатов.
Архитектор в этом плане превращается в толмача между двумя не так уж часто понимающими друг друга блоками организации: бизнеса и разработки. Проектируя систему в техническом плане, он должен понимать все нюансы её работы в плане решения исходных бизнес-задач. В нашем случае, существующие бизнес-процессы (в которых участвует исследуемая система) он должен спроецировать на документацию и исходный код. Видеть систему и как разработчик, и как бизнес-аналитик. Более того, ему необходимо уметь говорить на языках разработчиков и бизнес заказчиков, что бывает, порой, непросто.
По мере понимания процессов актуализируется документация. Далеко не всегда имеющаяся документация оказывается достоверной. Что-то потерялось, где-то не внесли вовремя изменения, часть документации может поддерживаться в сторонних системах. Вот почему важно сравнивать текущее поведение системы не только с изученными процессами, но также и с тем, как это отражено в документах. На этом этапе нередко возникают дополнительные вопросы, связанные с межсистемным взаимодействием. Это приводит к чтению смежной документации, и такие процессы становятся частью исследуемой предметной области.
«Раскопки» включают в себя процесс тестирования. Установив изучаемую систему на тестовом стенде, вы можете создавать тесты по каждому из исследуемых процессов. С одной стороны, они лягут в основу автотестирования системы после доработок, с другой, позволят проверить соответствие работы системы и документации. Огромным плюсом станет экспертиза в эксплуатации и управлении.
«Раскопки» — довольно трудоёмкий увлекательный процесс, связанный с поиском, переговорами, агрегированием получаемой информации и аналитикой полученных результатов. Важно учесть то, как и где документация будет храниться. Информация в процессе поиска и переговоров постоянно трансформируется, читается и пересылается разными людьми. И потому, в рамках организации для хранения и редактирования документации хорошо подходят внутренние вики-системы с настраиваемыми правами доступа и поддержкой версионности документов.
Когда известны все процессы плюс документация, исходный код становится подобен увеличительному стеклу, позволяющему детально рассмотреть реализацию конкретного участка процесса. Он привносит следующие бонусы: ● Процесс становится максимально детализированным. ● Можно быстро проверить соответствие документации и кода. ● Есть возможность «точечно» дорабатывать функционал, не затрагивая остальное. ● При разборе инцидентов сокращается время поиска источника проблемы.
Заключение
Итак, несмотря на техническую сторону задачи, всегда важно начинать с изучения процессов, заложенных в систему. Идти от постановки бизнес задачи. Затем происходит актуализация документации. На этом этапе важно использовать тестовый стенд для проверки соответствия документации и реального состояния дел. Исходный код хорошо использовать для уточнения полученных данных. И только после того, как все составляющие от бизнес процессов до границ функционала становятся известны, можно начинать разработку.