В среде разработчиков 1С существует давняя проблема — так называемые «процедуры-портянки». Это огромные блоки кода на несколько сотен или даже тысяч строк, внутри которых перемешаны запросы, расчеты, работа с интерфейсом и запись в базу данных. Сопровождать такой код крайне сложно: даже небольшое изменение может привести к непредсказуемым ошибкам в других частях системы. В этой статье мы разберем принципы создания качественных методов, опираясь на опыт классиков программирования (М. Фаулер, С. Макконнелл, Р. Мартин) и специфику платформы 1С.
Проанализируем типичную ситуацию: программист создает процедуру ВыполнитьЗагрузку(). Внутри он пишет сложный запрос на 5 экранов, затем обрабатывает результат в цикле, накладывает десяток условий и в конце обновляет форму. Пока автор «в потоке», он понимает логику. Однако через полгода другой специалист потратит часы, чтобы просто разобраться в хитросплетениях переменных. Рассмотрим основные минусы такого подхода:
Разберем, как декомпозиция (разделение на части) помогает сделать код понятным без комментариев. Посмотрим на пример расчета НДФЛ. Вместо того чтобы писать все условия в одном месте, проанализируем следующий подход:
Функция РассчитатьНДФЛПоСотруднику(Сотрудник, Параметры)
НДФЛ = 0;
ЯвляетсяРезидентом = СотрудникЯвляетсяРезидентомРФ(Сотрудник);
Если ЯвляетсяРезидентом Тогда
НДФЛ = РассчитатьНДФЛПоСтавке13(Сотрудник, Параметры);
Иначе
НДФЛ = РассчитатьНДФЛПоСтавке30(Сотрудник, Параметры);
КонецЕсли;
Возврат НДФЛ;
КонецФункции
Здесь мы видим идеальную структуру. Нам не нужно вчитываться в алгоритм расчета ставки 30%, если нас интересует только логика выбора ставки. Метод выступает в роли оглавления книги. Если нам нужно погрузиться в детали, мы переходим в конкретную функцию. Это экономит мыслительные ресурсы и время.
Одной из главных метрик сложности кода является степень вложенности циклов и условий. Проанализируем ситуацию, когда код «убегает» далеко вправо из-за многочисленных Если ... Тогда и Для каждого ... Цикл. Хорошим тоном считается вложенность не более 2–3 уровней.
Рассмотрим пример плохого кода:
Процедура ОбработатьДанные()
Если Условие1 Тогда
Для каждого Строка Из Таблица Цикл
Если Условие2 Тогда
Для каждого Элемент Из Массив Цикл
Если Условие3 Тогда
// Слишком глубокая вложенность!
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Чтобы упростить такой код, применим технику инверсии условий и раннего выхода. Выясним, как это работает: вместо того чтобы оборачивать весь код в огромное Если, мы проверяем негативное условие и сразу выходим из процедуры через Возврат или переходим к следующей итерации через Продолжить.
Разберем улучшенный вариант:
Процедура ОбработатьДанные()
Если Не Условие1 Тогда
Возврат;
КонецЕсли;
Для каждого Строка Из Таблица Цикл
Если Не Условие2 Тогда
Продолжить;
КонецЕсли;
ОбработатьЭлементыМассива(Строка.Массив);
КонецЦикла;
КонецПроцедуры
Такой код читается линейно, сверху вниз, и не заставляет программиста помнить все уровни вложенности, в которых он сейчас находится.
Выясним, какой длины должен быть метод. Большинство экспертов сходятся во мнении: процедура в идеале должна умещаться на один экран монитора (примерно 25–50 строк). Если метод не влезает в экран, это сигнал о том, что он делает слишком много вещей одновременно (нарушает принцип Single Responsibility).
Стив Макконнелл в книге «Совершенный код» указывает, что методы до 200 строк не всегда являются ошибочными, но к ним нужно относиться настороженно. В 1С, учитывая многословность языка, порог в 50-70 строк является разумным компромиссом.
В платформе 1С есть механизм #Область. Некоторые разработчики используют их, чтобы визуально скрыть «портянку». Однако важно понимать различие:
Следовательно, области полезны для группировки списка методов (например, #Область ОбработчикиСобытийФормы), но они не заменяют декомпозицию логики.
Помните, что имя метода — это его документация. Рассмотрим несколько правил:
РассчитатьСкидку(), ЗаполнитьТаблицуОстатков().ВыполнитьДействие() лучше написать ПроверитьЗаполнениеОбязательныхПолей().СформироватьДвиженияПоРегиструПродажи() гораздо лучше, чем СформДвиж().Резюмируем: создание коротких методов — это не фанатизм, а забота о коллегах и о себе в будущем. Качественный код в 1С должен выглядеть как набор четких, коротких инструкций, каждая из которых решает ровно одну задачу. Это делает систему гибкой, надежной и легкой в сопровождении.