Поток лавы.
Поток лавы — антипаттерн, при котором непонятный недоделанный код застывает в продакшене, потому что никто не понимает его достаточно, чтобы удалить.
На жаргоне компьютерного программирования поток лавы — это антипаттерн, возникающий, когда исходный код, написанный в неоптимальных условиях, развёртывается в продакшен-окружении и затем расширяется, всё ещё оставаясь в недоработанном состоянии. Термин происходит от природного явления — лавы, которая, остыв, застывает в трудноудаляемую породу. Аналогично такой код становится трудно рефакторить или заменять из-за зависимостей, возникающих со временем, что вынуждает поддерживать обратную совместимость с исходным незавершённым дизайном.
Причины
Поток лавы может возникать по множеству причин в рамках процесса разработки ПО:
- Давление сроков, из-за которого временные решения становятся постоянными
- Недостаточная документация, мешающая понять назначение кода
- Отсутствие автоматических тестов, делающее рефакторинг рискованным
- Частые изменения в составе команды разработки, ведущие к потере знаний
Последствия
Недоработанный код, становящийся частью инфраструктуры ПО, повышает сложность системы, и кодовую базу становится всё труднее понимать и сопровождать. Это приводит к:
- Необходимости обратной совместимости, которая может душить инновации и препятствовать внедрению более новых, более эффективных решений
- Росту технического долга, накапливающегося со временем и приводящего к более высокой стоимости изменений и сопровождения
- Препятствиям для рефакторинга или улучшения системы из-за страха сломать зависимые компоненты
Влияние на команды
Команды разработки часто ощущают влияние потока лавы, когда участники приходят и уходят:
- Потеря знаний об аспектах кода системы, когда уходят первоначальные разработчики
- Нежелание новых разработчиков рефакторить незнакомый код, что ведёт к дальнейшему усложнению, поскольку они добавляют, а не наводят порядок
Стратегии снижения вреда
Несколько практик способны смягчить эффекты антипаттерна поток лавы:
- Продвижение хороших практик документирования для ясного понимания кода
- Поощрение регулярных код-ревью, чтобы рано выявлять неоптимальные практики
- Приоритизация рефакторинга как неотъемлемой части жизненного цикла разработки
- Поддержание полноценного набора автоматических тестов для снижения риска при изменениях
Пример
Унаследованная ветка ниже переживает любую чистку: для неё нет ни теста, ни задачи, ни документации — только предупреждающий комментарий, поэтому никто не знает, зачем она нужна, и никто не решается её удалить.
class Pricing {
// никто не помнит, кто выставляет этот флаг; не удалять, что-нибудь может сломаться
private static final boolean LEGACY_MODE = Boolean.getBoolean("pricing.legacy");
double price(Order order) {
double total = order.total() * 1.1;
if (LEGACY_MODE && order.items() > 10) {
total = legacyAdjust(total); // ???
}
return total;
}
private double legacyAdjust(double total) {
return Math.floor(total * 0.97);
}
}
Выход — зафиксировать текущее поведение характеризационными тестами, убедиться, что ветка не используется, и удалить её:
// 1. Характеризационные тесты фиксируют текущее поведение до любых изменений
@Test
void addsTenPercentMarkup() {
assertEquals(110.0, new Pricing().price(new Order(100.0, 1)), 1e-9);
}
// 2. Поиск по коду и конфигурация продакшена показывают, что pricing.legacy никто не задаёт,
// поэтому ветка удалена; тесты подтверждают, что больше ничего не изменилось
class Pricing {
double price(Order order) {
return order.total() * 1.1;
}
}
Недостижимый код — это обычный мёртвый код, а система контроля версий всё равно его сохранит, так что держать его «на всякий случай» незачем.
Адаптировано по статье Википедии “Lava flow (programming)” (версия 1309138267), распространяется по лицензии CC BY-SA 4.0; текст переведён и отредактирован, добавлены примеры.