Какой вариант оформления условий в 1С читать легче и как снизить когнитивную сложность кода?

Программист IT и автоматизация бизнеса
← На главную

При написании логики программистам регулярно приходится проверять множество условий. Часто возникает дискуссия: как именно оформлять эти проверки, чтобы код легко читался, поддерживался и не вызывал головной боли у коллег? Рассмотрим подробнее популярную проблему — выбор между глубокой вложенностью условий и плоскими, объединенными проверками.

Сравнение подходов: вложенные условия против плоских

Проанализируем два типичных варианта написания условных конструкций.

Вариант 1: Вложенные условия


Если А Тогда
    Если Б Тогда
        // какие-то действия
    КонецЕсли;
    Если С Тогда
        // какие-то действия
    КонецЕсли;
Иначе
    Если Д Тогда
        // какие-то действия
    КонецЕсли;
КонецЕсли;

Вариант 2: Плоские условия


Если А И Б Тогда
    // какие-то действия
КонецЕсли;
Если А И С Тогда
    // какие-то действия
КонецЕсли;
Если НЕ А И Д Тогда
    // какие-то действия
КонецЕсли;

На первый взгляд разница может показаться непринципиальной. Однако современные стандарты разработки 1С и инструменты контроля качества кода однозначно отдают предпочтение второму (плоскому) варианту. Выясним причину такого выбора.

Понятие когнитивной сложности кода

Для оценки запутанности алгоритма статические анализаторы (например, SonarQube, который активно используется в CI/CD контурах 1С) применяют метрику когнитивной сложности (Cognitive Complexity). В отличие от устаревшей цикломатической сложности, которая просто подсчитывает количество ветвлений, когнитивная метрика накладывает прогрессивный штраф за вложенность.

Разберем по шагам, как она рассчитывается:

  1. Первое условие Если дает +1 балл к сложности метода.
  2. Если поместить еще одно условие внутрь первого, внутренний блок получит уже +2 балла (+1 за само ветвление и +1 за уровень вложенности).
  3. Каждый следующий уровень вложенности экспоненциально увеличивает сложность восприятия.

Именно поэтому первый вариант из нашего примера объективно хуже. Он очень быстро приведет к превышению допустимых лимитов (стандартом считается не более 15 баллов на одну функцию или процедуру), и система автоматизированного контроля просто отклонит такой код.

Использование конструкции ИначеЕсли

Посмотрим на пример того, как можно дополнительно улучшить второй вариант, задействовав логическую конструкцию ИначеЕсли:


Если А И Б Тогда
    // действия 1
ИначеЕсли А И С Тогда
    // действия 2
ИначеЕсли НЕ А И Д Тогда
    // действия 3
КонецЕсли;

Главное преимущество этого способа заключается в том, что при чтении кода моментально пропадает иллюзия параллельности: мы четко видим, что выполнится только один блок. В случае с отдельными блоками Если (без Иначе) разработчику приходится держать в памяти все условия и анализировать, могут ли они пересекаться и выполняться друг за другом.

Ленивые (короткие) вычисления логических выражений

При объединении условий часто возникает опасение: а не будет ли тратиться лишнее процессорное время на повторное вычисление переменных (например, условия А)?

Важно помнить, что платформа 1С:Предприятие применяет принцип ленивых вычислений. Проанализируем выражение Если А И Б Тогда. Платформа вычисляет значения слева направо. Если переменная А равна Ложь, система сразу же понимает, что все выражение уже не сможет стать истинным. Следовательно, операнд Б вообще не вычисляется. Это делает объединенные проверки безопасными для быстродействия и не создает лишней нагрузки.

Паттерн "Ранний возврат" (Guard Clauses)

Чтобы избежать написания огромных и вложенных друг в друга условий, давайте применим профессиональный паттерн раннего возврата (Guard Clauses). Его суть — отсечение неподходящих и ошибочных сценариев в самом начале метода при помощи оператора Возврат.

Рассмотрим применение на практике:


Если НЕ А Тогда
    Возврат;
КонецЕсли;

Если Б Тогда
    // Выполняем действия
    Возврат;
КонецЕсли;

Если С Тогда
    // Выполняем другие действия
    Возврат;
КонецЕсли;

Использование раннего возврата избавляет нас от создания антипаттерна "Arrow Code" (когда код смещается вправо формой стрелы из-за множества отступов). Вся позитивная бизнес-логика остается на верхнем уровне, и процедура читается легко — линейно и строго сверху вниз.

Контекст и грамотная декомпозиция

Следует отметить, что объединение условий не всегда является универсальной "серебряной пулей". Если условия семантически различны и не связаны между собой общей бизнес-задачей, разделять их логично.

Посмотрим на пример корректного разделения уровней логики:


Если ЭтоРабочаяБаза Тогда
    Если ПроверкаБизнесЛогики Тогда
        // Основной алгоритм
    Иначе
        // Отказ
    КонецЕсли;
Иначе
    // Логика, специфичная только для тестовых баз
КонецЕсли;

В этом случае проверка среды (рабочая база или копия) никак не относится к логике проведения документа, поэтому объединять их через И было бы смысловой ошибкой.

Если же код внутри ваших условий все равно получается слишком большим, всегда прибегайте к декомпозиции. Выносите однотипные проверки и объемные блоки логики в отдельные функции со своими зонами ответственности. Это не только снизит когнитивную сложность до приемлемых значений, но и сделает разработку удобной и безошибочной.

← На главную