Рефакторинг компонента 1С‑Битрикс: шесть кейсов со «сломанной простынёй»
Не «ради красоты»: когда рефакторинг обязателен
Речь про реальный производственный сценарий: длинное наследие в одном компоненте 1С‑Битрикс, из‑за которого нельзя быстро поправить баг без риска снова что‑то сломать в соседнем участке и без чтения «простыни» сверху донизу. Ниже — шесть типичных симптомов такого кода и практический подход к переработке с опорой на декомпозицию через класс (по замыслу оригинальной заметки — структура «до и после» удобно сравнима через архив в примере источника; здесь текст пересказан, без копирования формулировок).
Проблема раздутого процедурного скрипта
Отдельную строку в середине файла сложно связать головой целиком: вы не уверены, через какую ветвь if..else вы сюда попали и что произойдёт на выходе. Поиск по имени свойства может увести в лабиринт вложенных условий — и вы теряете нить задачи.
Выход здесь простой как идея: разбить файл на понятный «каркас» и маленькие методы класса наследника CBitrixComponent, чтобы главный сценарий умещался в нескольких строках вроде инициализации, подготовки данных и вызова шаблона. Тогда любой блок можно изолировать, протестировать взглядом или инструментами отладки и не простаивать в бесконечном скролле вверх по файлу.
Зависимости явно через конструктор
Второй вопрос после длины: от чего вообще зависит компонент. Логичнее не размазывать глобальные побочные эффекты по середине методов, а собрать ожидания контекста (идентификатор пользователя, массивы параметров инфоблока, временные промежутки и т.д.) там, где вы их один раз сохранили в свойства объекта при создании экземпляра.
Имеет смысл частично сохранить узнаваемые имена с префиксами Битрикс, если вы параллельно держите открытым старый вариант — меньше риска перепутать поля при переносе. Если же имя давно живёт исторически как «перевозчик/транспортёр», но по сути хранятся иные сущности, например ставки заказов, смело переименуйте внутренний массив во что‑то без двусмысленности вроде $arBidSnapshots — по мотивам совета про силу имён переменных.
Разовый вывод проверки вместо семи одинаковых вызовов
Отдельный анти‑паттерн — когда вспомогательная функция вроде isUserCargoCourier($visitorId) дергается много раз подряд тем же входом. Формально результат не меняется между вызовами, а накладные расходы и шум во вложенных условиях есть.
Вычислите результат один раз, сохраните в булевые флаги с положительной семантикой и дальше читайте человеческое «если менеджер», а не «если не не‑курьер»:
<?php
$this->roleIsCargoCourier = isUserCargoCourier((int)$this->visitorId);
$this->roleIsDeskManager = !$this->roleIsCargoCourier;
Так условные ветви по роли становятся самодокументируемыми и уменьшается нагрузка на лишний вывод одной и той же информации из хелпера.
Ссылки как способ расчистить промежуточный расчёт
Бывает цепочка из длинной встроенной арифметики и смешения индексов — читатель «летит по диагонали» и ломает голову. Вынесение части шага в промежуточные переменные или работа с временным массивом по ссылке $row =& $parcel['lines'][$idx], если это уместно в вашем случае, часто экономит несколько строк визуального шума. Речь именно про баланс: не превращать всё подряд в ссылки без необходимости, а облегчить самый узкий участок там, где и у автора источника нагромождали логики в строку.
Дубликаты времени или одинакового смещения
Ещё частый симптом — три–четыре ветки if / elseif, которые на деле добавляют одну и ту же добавку времени («+N часов»), только условие сверху написано по‑разному. Перед тем как поддерживать лес копипасты, стоит упростить ветвление или вынести общий шаг в одну секцию после выяснения исхода. История правок живёт в Git: не надо сохранять в коде каждое прошлое значение если все уже приведено к одинаковому литералу.
<?php
$parcelReadyAt = new \Bitrix\Main\Type\DateTime();
if ($state === 'delayed') {
// ...
} elseif ($state === 'routed') {
// ...
}
if ($parcelHasPriority) {
$parcelReadyAt->add('PT3H');
}Второй фрагмент иллюстративный — фактический рефакторинг завязан на вашем домене; идея в том, чтобы убрать копирование одинакового смещения и оставить различия только там, где они реально нужны поведению пользователя или бизнеса.
Кратко
- Длинную процедурную «простыню» разбирайте до короткой формы главного потока плюс мелкие методы класса компонента.
- Зависимости и параметры аккумулируйте в начале жизненного цикла, имена свойств поддерживайте осмысленными.
- Тяжёлые проверки с неизменным результатом выполняйте один раз и фиксируйте результат в понятные булевы поля без двойных отрицаний.
- Уберите худшие дубликаты времени или однотипных веток — проще понять действительную логику и быстрее закрыть баг.
Не хотите копаться сами?
Починю за 1-3 дня. Без предоплаты — оплата по результату.
15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии