Зачем в коде 1С используются конструкции «Если Истина И...» и «Если Ложь ИЛИ...»?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При анализе чужого кода или типовых конфигураций разработчики периодически сталкиваются с загадочными логическими конструкциями, которые на первый взгляд кажутся избыточными или ошибочными. Например, зачем писать Если Истина И Условие1 И Условие2 Тогда, если результат логического выражения никак не изменится, если убрать ключевое слово Истина? То же самое касается и конструкций с использованием Ложь Или.

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

Суть методологии «И-ИЛИ дерева» логических выражений

Такой подход — не случайная ошибка программиста, которому было лень удалить старый код, и не «костыль» для обхода платформенных ограничений. Это элемент структурированного стиля кодирования, основанный на математической концепции представления сложных логических условий в виде дерева (так называемого «И-ИЛИ дерева» условий). Данная концепция была детально описана и популяризирована в сообществе 1С разработчиком под ником TormozIT, автором известного проекта «Инструменты Разработчика».

С точки зрения алгебры логики, любое сложное условие можно декомпозировать на группы союзов «И» и союзов «ИЛИ». Чтобы сделать структуру логического дерева визуально однородной, в начало каждой новой логической группы добавляется так называемый нейтральный элемент, который не влияет на итоговый результат вычислений всей группы:

Давайте посмотрим на классический пример оформления такого условия:


Если Истина
    И ЗначениеЗаполнено(ЭтотОбъект.Ссылка)
    И Не ЗначениеЗаполнено(ЭтотОбъект.Ссылка.Реквизит)
Тогда
    Если Ложь
        Или ЭтотОбъект.Реквизит1
        Или Не ЭтотОбъект.Первичный
    Тогда
        Возврат;
    КонецЕсли;
КонецЕсли;

Проанализируем ситуацию: зачем разработчик пошел на усложнение кода и добавил лишние строки? Выясним главные практические причины использования этого подхода.

Причина 1. Идеальные условия для быстрого комментирования (Toggling)

Представим стандартный вариант записи сложного условия без нейтральных элементов:


Если Условие1 
    И Условие2 
    И Условие3 Тогда

Допустим, в процессе тестирования или отладки алгоритма нам потребовалось временно отключить (закомментировать) Условие1. Если мы просто поставим символы комментария перед ним, наш код превратится в следующую конструкцию:


Если // Условие1 
    И Условие2 
    И Условие3 Тогда

При попытке синтаксического контроля или компиляции система выдаст ошибку, так как выражение не может начинаться с бинарного оператора И. Разработчику придется переносить оператор И со второй строки на первую, убирать его или придумывать другие обходные пути, а затем возвращать все в исходное состояние. Это отнимает драгоценное время.

Теперь посмотрим, как эта же задача решается при использовании нейтрального элемента Истина:


Если Истина
    // И Условие1 
    И Условие2 
    И Условие3 Тогда

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

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

В платформе 1С логические выражения вычисляются по принципу «ленивых вычислений» (короткозамкнутая оценка). Это означает, что вычисление выражения происходит слева направо и прекращается сразу же, как только результат становится однозначно определен:

Для оптимизации быстродействия системы крайне важно размещать самые «легкие» (быстрые) проверки в самом начале выражения, а «тяжелые» (запросы к базе данных, обращение к свойствам через несколько точек) — в самом конце.

Если код написан в стиле «И-ИЛИ дерева», разработчик может очень легко перемещать строки с условиями вверх и вниз с помощью стандартных сочетаний клавиш текстового редактора (например, Alt + Стрелка вверх / Alt + Стрелка вниз). При этом не требуется следить за тем, где находится первый операнд, у которого нет ведущего оператора И или ИЛИ. Все строки логического блока становятся полностью равноправными и независимыми друг от друга.

Причина 3. Красивое форматирование и самодокументируемый код

При ведении разработки в крупных проектах важно обеспечивать читаемость кода для всей команды. Использование дерева условий позволяет красиво форматировать выражения, размещая каждое элементарное условие на отдельной строке и снабжая его персональным комментарием:


Если Истина
    И ЗначениеЗаполнено(Ссылка) // Объект уже записан в информационную базу
    И Не Ссылка.ПометкаУдаления // Объект активен (не помечен на удаление)
    И ЭтотОбъект.Проведен       // Документ проведен
Тогда
    // Выполнение логики алгоритма
КонецЕсли;

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

Причина 4. Применение в запросах 1С

Аналогичный прием очень часто используется разработчиками при динамическом формировании текстов запросов. Строка вида "ГДЕ ИСТИНА" или "ГДЕ 1=1" служит базовой заглушкой, к которой в цикле или по условиям в коде можно легко прибавлять новые фильтры с помощью простой конкатенации строк:


ТекстЗапроса = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ ИСТИНА";
Если ТолькоУслуги Тогда
    ТекстЗапроса = ТекстЗапроса + " И Услуга = ИСТИНА";
КонецЕсли;

Если бы начальной заглушки ГДЕ ИСТИНА не было, разработчику пришлось бы писать сложные проверки, чтобы определить, является ли добавляемый фильтр самым первым (и тогда нужно вставить ключевое слово ГДЕ), или он уже последующий (и тогда нужно вставлять И).

Разбор популярного мифа: Защита от значений «Неопределено»

Среди начинающих программистов бытует мнение (отраженное в некоторых сообщениях на форумах), что конструкция Если Истина И ... защищает систему от возникновения ошибок при приведении типов. Например, предполагается, что если переменная имеет значение Неопределено, то при проверке Если Истина И Переменная ошибка не возникнет.

Это предположение абсолютно ошибочно!

Платформа 1С в любом случае попытается вычислить все элементы выражения (за исключением случаев, когда результат определен ленивыми вычислениями на предыдущих шагах). Проанализируем простой пример:


Переменная = Неопределено;
Если Истина И Переменная Тогда
    // Код не выполнится, возникнет ошибка выполнения
КонецЕсли;

При выполнении этого фрагмента система незамедлительно выдаст ошибку: «Преобразование значения к типу Булево не может быть выполнено». Конструкция с нейтральным элементом Истина не спасает от несоответствия типов. Для безопасной проверки необходимо использовать только явное приведение типов или специализированные функции, например:


Если ЗначениеЗаполнено(Переменная) И (Истина И Переменная) Тогда
    // Безопасный код
КонецЕсли;

Недостатки данного подхода

Несмотря на очевидные плюсы для отладки и рефакторинга, у методологии «И-ИЛИ дерева» есть и противники. Основные аргументы против использования такого стиля сводятся к следующему:

  1. Эффект недоумения (WTF-эффект). Разработчики, не знакомы с этой методологией (особенно начинающие специалисты), тратят время на попытки понять, зачем здесь написаны очевидные константы Истина или Ложь.
  2. Увеличение вертикального размера кода. Код «раздувается» по высоте, из-за чего на экране монитора помещается меньше полезной логики алгоритма.
  3. Микроскопическое влияние на производительность. Процессору приходится обрабатывать на одну логическую операцию больше. В реальной практике эта задержка стремится к нулю и никак не ощущается пользователями, но для перфекционистов это является дополнительным аргументом «против».

Подведем итоги

Мы выяснили, что конструкции Если Истина И... и Если Ложь Или... представляют собой удобный профессиональный инструмент оформления сложных ветвлений. Использовать данный стиль на постоянной основе или писать условия в классическом стиле — решать вам и вашей команде разработчиков на уровне внутренних стандартов кодирования. Однако теперь, встретив такую конструкцию в кодовой базе, вы точно будете знать, с какой целью ее применил автор.

← На главную