Каждый раз меняя код, я задаюсь вопросами. Сломалось ли что-нибудь? На что повлияли изменения? Как проверить изменения?
Код по своей сути предполагает стабильность своей работы без изменени внешних факторов. Любое же изменение самого кода влечет за собой изменения как очевидные, так и неявные (например, производительность или время компиляции). Трудно себе представить код, который не имеет предпосылок для эволюции.
Нужно разобраться как все таки изменить код, ничего не поломав, а также убедиться, что программа работает корректно после правки.
Корректность - это способность ПО выполнять точные задачи так, как они определены их спецификацией. -- Бертран Мейер
Этот фактор качества один из первых, о котором стоит вообще говорить. Без корректной работы программного кода, остальные факторы не имеют ценности, например, такие как эргономичный интерфейс или высокая производительность.
Я много раз сталкивался с тем, что современные практики разработки стремятся снизить необходимость спецификаций на этапе проектирования и разработки, ставя перед собой целью ускорение этапов производства и уменьшения итераций в циклах создания продукта, а также повышение эффективности на этапе разработки. В крайнем случае спецификация пишется на конкретный модуль, без указания участия модуля в экосистеме. В такой ситуации одно только следование спецификации не сможет помочь. Всегда будет оставаться чувство, что остается что-то упущенное. Для ответственных разработчиков это влечет за собой лишние затраты времени на тестирование.
Модульное тестирование призвано обеспечить гарантию качества отдельного модуля и обеспечение корректности его работы. Однако, что если спецификация не учитывает формат результата в достаточной мере? Например, модификация позволила повысить точность расчета и теперь модуль возвращает число с точностью до четвертого знака после запятой. Вполне может оказаться, что система визуализации данных не имеет декоратора или обработчика для этого значения, поскольку изначально данные всегда возвращались с точностью до двух знаков, и значение выводится без форматирования. Кроме того, может оказаться, что форма, в которой выводится значение органичена количеством знаков. В такой ситуации, в условиях архитектуры, которая не предполагает отдельный модуль для форматирования результатов расчета, модульное тестирование также не поможет выявить проблему на раннем этапе.
Отсутствие интеграционных тестов не сможет помочь убедиться, что изменение не оказало негативного эффекта.
Любое изменение должно происходить с пониманием работы системы. Стоит уделить время и проверить места использования изменяемого модуля. Это может дать более полную информацию о способах использования и потенциально скрытых возможностей. Изменение вносится с целью исправить ошибку или усовершенствовать модуль - ввести новый аттрибут или функцию. Недопустимо при этом нарушить работоспособность остальных модулей системы. Каскадные изменения должны быть распланированы заранее, если ваше изменение меняет способ использования. Ответственный разработчик обязательно добавит интеграционные тесты в систему, чтобы обезопасить себя и будущих разработчиков при следующей модицикации, а также сократить время на внесение изменений в будущем. И конечно же это повысит устойчивость системы при внесении правок, снижая риск ошибки на этапе разработки.
Комментарии к коду имеют свойство устаревать. Недоверие комментариям вполне может оказаться оправданным. История изменений может показать менялся ли код с момента написания комментария и какие изменения ранее вносились.
Если код удается ввести в средства тестирования и проверка занимает комфортное время ожидания, то тесты можно выполнять постоянно, в каждый удобный момент, чтобы сразу же проверять воздействие изменений. Более аггресивным методом достижения осторожного изменения будет автоматический запуск тестов в ответ на изменение исходного кода.
Любое изменение должно производиться с единственной целью. Изменение, требующее реорганизацию кода может надолго задержать правку, поскольку, чтобы довести изменение до логической точки с возможностью проверки, может потребовать высокой концентрации и принятия новых важных решений. При этом хочется сделать все изменния сразу, максимально приблизив полученное решение к задумке. В итоге самое главное изменение потеряется в десятках других. Такое изменение будет сложнее понять вашему товарищу, который не сразу понимает главный посыл правки. В группах разработчиков приветствуется изменение кода с единственной целью.
Программирование - это искусство все делать по порядку. -- Майкл Физерс
Особое отношение заслуживает изменение спецификации: добавление новых или удаление аттрибутов, замена переменных и их типов, поскольку это влечет за собой изменение протокола общение с другими модулями, а также каскадное изменение в них. Подобный шаг может сильно повлиять на затраченное время. Вы полне можете выбиться из предварительной оценки по времени, если не знаете полностью как реализованы и организованы другие модули. Возможно в системе есть копии кода, который вы сейчас правите и узнать об этом вы вполне сможете уже на этапе тестирования. В таком случае вам придется убедиться, что копия может содержать аналогичные изменения.
Если изменение влияет на разные группы разработки и применение парного программирования невозможно, то нужно позаботиться о том, чтобы все участники процесса разработки были уведомлены об изменениях в протоколе. В частности необходимо внести правки в документацию. Всегда следует помнить, что разработка - не единственный этап жизненного цикла программы.