В практике разработки на платформе 1С:Предприятие 8.3 часто возникает дилемма: использовать стандартные контекстные серверные вызовы или пытаться оптимизировать код с помощью директивы &НаКлиентеНаСервереБезКонтекста. Вопрос становится особенно острым, когда разработчики начинают передавать в такие процедуры саму форму в качестве параметра. Проанализируем, насколько оправдан такой подход, какие преимущества он дает и когда он превращается в «избыточное проектирование».
Для начала разберем, как именно платформа обрабатывает эту директиву. Важно понимать, что при компиляции модуля формы 1С создает две версии такой процедуры: одну для клиентского приложения, другую — для сервера. Это так называемая двойная компиляция.
Когда мы вызываем подобную процедуру из клиентского кода, управление не передается на сервер. Код исполняется локально на клиенте. Если же вызов происходит из серверного метода (например, ПриСозданииНаСервере), код исполняется на сервере. Главный выигрыш здесь — отсутствие «сетевого прыжка» и отсутствие необходимости синхронизировать контекст формы (реквизиты, элементы, переменные) между клиентом и сервером.
Рассмотрим ситуацию подробнее. Если у нас есть задача, которую нужно выполнить и при открытии формы (на сервере), и при изменении пользователем какого-то поля (на клиенте), у нас есть три пути:
&НаСервере и в &НаКлиенте. Это плохая практика, нарушающая принцип DRY (Don't Repeat Yourself).&НаСервере. В этом случае при вызове с клиента платформа будет вынуждена передать «дельту» (измененные данные формы) на сервер, выполнить код и вернуть результат.&НаКлиентеНаСервереБезКонтекста с передачей формы или её части в параметре.Проанализируем третий вариант. Здесь экономия серверного вызова достигается за счет того, что при интерактивной работе пользователя (на клиенте) процедура отрабатывает моментально, не тревожа сервер. Это критически важно при работе через медленные каналы связи или в высоконагруженных системах, где каждый лишний вызов сервера создает очередь на рабочих процессах.
Часто возникают споры: стоит ли передавать всю форму (параметр Форма) или лучше ограничиться конкретными реквизитами? С точки зрения чистоты кода, сужение контекста до необходимых данных предпочтительнее. Однако передача ссылки на форму (объект ЭтотОбъект) не является «тяжелой» операцией. В 1С объекты передаются по ссылке, и если вызов происходит внутри одной стороны (клиент-клиент или сервер-сервер), физического копирования всех данных формы не происходит.
Посмотрим на классический пример реализации такой оптимизации:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Вызов на сервере - отработает серверная копия кода
ОбновитьСостояниеИнтерфейса(ЭтотОбъект);
КонецПроцедуры
&НаКлиенте
Процедура КоличествоПриИзменении(Элемент)
// Вызов на клиенте - отработает клиентская копия БЕЗ обращения к серверу
ОбновитьСостояниеИнтерфейса(ЭтотОбъект);
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Процедура ОбновитьСостояниеИнтерфейса(Форма)
// Управляем видимостью и доступностью через переданный контекст
Форма.Элементы.ГруппаИтоги.Доступность = (Форма.Объект.Товары.Количество() > 0);
КонецПроцедуры
Выясним причины, по которым даже передача всей формы в бесконтекстный метод эффективнее обычного &НаСервере:
БезКонтекста, точно знает, что данный метод не может случайно изменить реквизиты, не переданные в него явно, и не делает скрытых запросов к базе данных.Рассмотрим ситуацию, когда «игра не стоит свеч». Если логика внутри процедуры требует обращения к базе данных (например, получение остатков или цен), то использование &НаКлиентеНаСервереБезКонтекста становится бессмысленным. Вам всё равно придется делать вызов &НаСервереБезКонтекста внутри этой процедуры, что аннулирует всю экономию.
Также проанализируем аспект поддержки кода. Бесконтекстные методы в модулях форм лишены подсказок (IntelliSense) для переданных параметров. Разработчику приходится «вслепую» писать обращения к элементам формы, что повышает риск опечаток. Если форма постоянно дорабатывается и её структура меняется, такие «зацементированные» методы могут стать источником трудноуловимых ошибок.
Проанализировав доводы опытных разработчиков, выделим правила хорошего тона при использовании данного подхода:
&НаКлиентеНаСервереБезКонтекста для простой визуальной логики: управление доступностью, видимостью, пересчет простых формул в строках (например, Сумма = Цена * Количество).Объект (тип ДанныеФормыСтруктура). Это сделает метод более универсальным.Итог: Передача всей формы в бесконтекстный клиент-серверный метод — это не «говнокод», а вполне легальный инструмент оптимизации. Он позволяет сократить количество серверных вызовов до минимума, делая интерфейс отзывчивым. Однако применять этот прием стоит осознанно, не превращая его в самоцель там, где задержки не критичны, а сложность поддержки кода важнее экономии миллисекунд.