В идеальном случае — разработка программы начинается с формирования четкого представления о системе. Системный проект — это некий живой образ, сформированный в вашем воображении. В идеальном случае четкое осознание проекта приводит к появлению первой версии программы, она первый взгляд не может «издавать запах».
Дальнейшие события могут принять нежелательный характер. Программа начинает «издавать запах», т. е. неаккуратно написанная программа приводит к значительному усложнению процессу технического сопровождения.
В итоге — явные усилия, требующие выполнения простейших изменений, становятся настолько обременительными, что разработчики и project-менеджеры требуют выполнение повторной разработки программного проекта.
Признаки плохого проекта и запах
Диагноз «загнивания» (издавать запах) программы устанавливается в случае обнаружения одного из следующих признаков плохого проекта:
-
Закрепощенность: система с трудом поддается изменениям, поскольку любое минимальное изменение вызывает эффект «снежного кома», затрагивающие другие компоненты системы;
-
Неустойчивость: в результате осуществляемых изменений система разрушается в тех местах, которые не имеют прямого отношения к непосредственно изменяемому компоненту;
-
Неподвижность: достаточно трудно разделить систему на компоненты, которые могли бы повторно использоваться в других системах;
-
Вязкость: сделать что-то правильно намного сложнее, чем выполнить какие-либо некорректные действия;
-
Неоправданная сложность: проект включает инфраструктуру, применение которой не влечет непосредственно выгоды;
-
Неоправданные повторения: проект содержит повторяющиеся структуры, которые могут унифицироваться с применением простой абстракции;
-
Неопределенность: проект трудно читать и понимать. Недостаточно четко выражено содержимое проекта.
Закрепощенность
Закрепощенность проявляется в том случае, когда программа с трудом поддается изменениям, производимым с помощью простых методов. Проект становится жестким, если одно изменение влечет за собой каскад следующих изменений в зависимых модулях. Чем больше модулей подвержено изменениям, тем более жестким считается проект.
Большинство разработчиков, так или иначе, сталкиваются с этой проблемой. Их просят сделать простые на первый взгляд изменения. Они внимательно изучают характер будущих изменений, а затем выполняют обоснованную оценку требуемого в этом случае объема работы. Позднее, в процессе реализации изменений, разработчики приходят к выводу о непредсказуемых последствиях возможных изменений. В частности, подвергаются переработке огромные блоки кода, причем в процессе модификации вовлекается намного больше модулей, чем говорят результаты первоначальной оценки. Как правило, внедрение изменений занимает намного больше времени, чем планировалось изначально. Если спросить разработчиков о том, почему не оправдались их расчеты, они будут жаловаться на то, что задача оказалась намного сложнее, чем предполагалось изначально.
Неустойчивость
Неустойчивость при внесении одного изменения, программа «разрушается» во многих местах. Очень часто новые проблемы возникают в тех местах, которые не связанны с изменяемым компонентом (модулем). В процессе исправления этих ошибок возникают новые ошибки, в результате чего команда разработчиков начинает походить на собаку, гоняющуюся за своим хвостом.
По мере возрастания неустойчивости программного модуля, вероятность появления непредвиденных проблем приближается к 100%. Несмотря на всю абсурдность подобного утверждения, подобные модули встречаются довольно часто. Они могут занимать первые места в перечне ошибок, и, кроме того, по мнению разработчиков, должны перерабатываться повторно (но никто не желает иметь с этим дело). В данном случае идет речь о модулях, которые ухудшаются по мере их корректирования.
Неподвижность
Проект считается неподвижным, если он содержит компоненты (модули), которые могут применяться в других системах, однако усилия и степень риска, связанные с изоляцией этих компонентов от первоначальной системы, слишком велики. К сожалению, эта тенденция проявляется весьма часто.
Вязкость
Вязкость может проявляться в двух формах: по отношению к проекту и к среде.
В случае необходимости внесения изменений разработчики, как правило, применяют различные методы. Некоторые из них способствуют сохранению исходного проекта, а другие — нет (поскольку относятся к разряду «хакерских» приемов). Если предлагаемые проектом методы сложнее в применении, чем «хакерские» приемы, то говорят, что вязкость проекта очень высока. В этом случае легко допустить ошибку, а нужные и корректные действия выполнить не так уж и просто. В идеале требуется разработка программы, допускающих внесение изменений и сохраняющих структуру проекта.
Симптом вязкости наблюдается и в случае, если среда разработки характеризуется словами «медленный» и «неэффективный» (т.е. начинает издавать запах). Например, если количество повторных компиляций очень высоко, может возникнуть желание изменять программный код таки образом, чтобы избежать подобной ситуации (даже если нарушается структура проекта).
В обоих случаях вязкий проект представляет собой проект, в котором трудно сохраняется разработка программы. Мы хотим создавать такие системы и среды проектов, благодаря которым можно без особых усилий сохранить проект.
Неоправданная сложность
Проект имеет неоправданную сложность, если содержит элементы, не использующиеся в настоящий момент времени. Это часто происходит в том случае, когда разработчики предвидят изменения в требованиях и проводят мероприятия, направленные на то, чтобы справиться с этими потенциальными изменениями. На первый взгляд кажется, что это неплохо. В конце концов, подготовка к предстоящим изменениям должна сохранить наш код гибким и предотвратить кошмарные изменения, которые могут возникнуть впоследствии.
К сожалению, эффект от таких мероприятий может быть совсем противоположным. При подготовке наступлению множества дополнительных непредвиденных обстоятельств, проект начинает изобиловать никогда не использующимися конструкциями. Некоторые из таких подготовительных мероприятий — могут окупаться, а другие — нет. А между тем, проект несет в себе груз неиспользуемых элементов проекта. В силу этих причин, программа получается сложной и трудной понимаемой.
Сюда же относится и отсутствие мероприятий по рефакторингу неиспользуемых частей проекта, ввиду своей неактуальности, которые также добавляют к проекту неоправданную сложность. К сожалений, этот «феномен» очень часто встречается в живых веб-проектах, когда компонента (модуль) со старым функционалом проекта не «вычищается» из кода, а деактивируется путем игнорирования этого старого кода в общем функционале проекта и таким образом продолжительный по времени жизни и успешный проект, начинает обрастать большим количество неактуального набором кода (иногда его именую техническим долгом).
Неоправданные повторения
Операция «копирования» и «вставки» могут быть полезны при редактировании текста, но в то же время они могут быть опасными операциями в случае редактирования кода. Слишком часто программные системы выстраиваются на десятках и сотнях повторяющихся элементов кода.
Если один и тот же код появляется несколько раз в нескольких отличных формах, разработчики теряют его абстрактный образ. Поиск всех повторений, а также их сокращение с применением соответствующих абстракций, может и не включаться в первые пункты списков приоритетов, но следует учитывать то, что в противном случае затрачивается не мало усилий и времени для того, чтобы система получилась доступной для понимания и управления в дальнейшем.
Слишком громоздкий системный код — усложняет работу по изменению системы. Ошибки, обнаруженные в модуле, содержащем повторяющийся код, требуют исправления при каждом повторении. Однако, поскольку каждое повторение лишь в незначительной степени отличаются от всех остальных, то исправления не всегда могут носить одинаковый характер.
Неопределенность
Неопределенность программного модуля проявляется в сложности его понимания. Код может быть написан либо в четкой и выразительной манере, либо быть неопределенным и трудным для понимания. Код эволюционирующий с течением времени, становится все более неопределеенным. Необходимо постоянно следить за тем, чтобы код оставался «прозрачным» и выразительным, сводя возможную неопределенность к минимуму.
На начальном этапе составления модуля — код разработчикам может показаться достаточно «прозрачным». То происходит в силу того, что они, погружаясь в проблему с головой, воспринимают код на своем внутреннем уровне. Позднее, когда это состояние проходит, они могут вернуться к модулю и удивиться, что могли составить нечто подобное. Чтобы предотвратить такие случаи, разработчики должны представить себя на месте своих читателей и предпринять согласованные усилия для разложения кода на элементарные операции, чтобы читатели могли его понять. Кроме того, желательно, чтобы кто-то еще просмотрел составленный ими код (т. е. провел код-ревью).