Путь к повышению эффективности программ заминирован грязным кодом Кирк Пеппердин

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

Допустим, вы обнаружили место, где теряется производительность. В этом случае обычно пытаются снизить сложность алгоритма, создающего недопустимую нагрузку. Вы сообщаете своему менеджеру, что исправление займет у вас, скажем, три-четыре часа. Работая над исправлениями, вы обнаруживаете, что перестал работать зависимый участок кода. Родственные фрагменты кода часто связаны друг с другом, что вызвано объективной необходимостью, и такое нарушение работы, скорее всего, предполагалось и учитывалось в оценке времени. Но что если исправление этой зависимости приведет к нарушению работы и других зависимых частей? Более того, чем дальше эти зависимости находятся от исходной точки, тем менее вероятно, что вы их обнаружите и учтете в своей оценке. Внезапно начальная оценка раздувается от трех-четырех часов до трех-четырех недель. Часто одна подобная неожиданность увеличивает сроки сразу на 1–2 дня. Не столь уж редко «небольшой» рефакторинг затягивается на несколько месяцев. В таких ситуациях ущерб, нанесенный доверию к действующей команде и ее «политическому капиталу», может быть тяжелым и даже смертельным. Вот если бы у нас был инструмент, позволяющий обнаружить и оценить такой риск…

На самом деле, существует много способов измерить и проконтролировать степень и глубину связанности и сложности нашего кода. С помощью программных метрик можно посчитать встречаемость в коде определенных характеристик. Эти количественные показатели коррелируют с качеством кода. Отметим две метрики из тех, которые оценивают связанность кода: число входов (fan-in) и число выходов (fan-out). Например, для классов fan-out определяется как количество классов, к которым прямо или косвенно обращается оцениваемый класс. Это можно представить себе как количество всех классов, которые нужно скомпилировать, прежде чем можно начать компилировать ваш класс. С другой стороны, fan-in — это количество классов, которые зависят от данного класса. Зная fan-out и fan-in, можно по формуле I = fo / (fi + fo) рассчитать коэффициент нестабильности. Чем ближе I к нулю для конкретного класса или модуля, тем он стабильнее. Когда значение I близко к 1, модуль становится нестабильным. Изменение кода стабильных модулей сопряжено с меньшим риском, тогда как в нестабильных модулях более вероятно наличие бомб грязного кода. Задача рефакторинга — приблизить I к нулю.

При использовании метрик нужно помнить, что это всего лишь эмпирические правила. Исходя из чистой математики мы увидим, что увеличивая fi, не изменяя при этом fo, мы приближаем I к нулю. Однако слишком большая величина fan-in имеет и обратную сторону: такие классы труднее изменить, не нарушая работу классов, зависимых от них. Кроме того, не решая проблемы fan-out, вы на самом деле не снижаете свои риски, поэтому нужно соблюдать некоторое равновесие.

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

Загрузка...