При разработке на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с дилеммой: где разместить серверную процедуру, которая должна вызываться как с клиента, так и с сервера. Если поместить ее напрямую в модуль с флагом Вызов сервера, мы рискуем «размазать» серверный интерфейс по разным модулям. Если же оставить ее в обычном серверном модуле и сделать «обертку» в модуле вызова сервера, возникает проблема дублирования кода и документации. В этой статье мы подробно разберем, как организовать этот процесс эффективно, следуя лучшим практикам и стандартам разработки.
Рассмотрим две основные стратегии, которые обсуждаются в сообществе разработчиков 1С:
Проанализируем ситуацию: почему второй подход считается более профессиональным? Модуль с флагом Вызов сервера — это публичный интерфейс вашего сервера для тонкого клиента. Согласно принципу Separation of Concerns (разделение ответственности), бизнес-логика не должна зависеть от того, каким способом ее вызвали. Поэтому правильным считается вынесение логики в неконтекстный серверный модуль.
Многие разработчики опасаются, что при изменении сигнатуры метода в серверном модуле они забудут обновить обертку. Чтобы минимизировать риск расхождений, в Библиотеке стандартных подсистем (БСП) и стандартах 1С применяются следующие приемы:
Вместо копирования всего блока описания параметров (программного интерфейса), в модуле-обертке используется краткая ссылка. Рассмотрим, как это выглядит на практике:
// В модуле ОбщегоНазначенияСервер (Сервер)
// Выполняет расчет остатков по складу.
//
// Параметры:
// Склад - СправочникСсылка.Склады - Склад для расчета.
// Дата - Дата - Момент времени.
//
// Возвращаемое значение:
// Число - Сумма остатка.
Функция ОстатокНаСкладе(Склад, Дата) Экспорт
// ... логика расчета ...
КонецФункции
// В модуле ОбщегоНазначенияВызовСервера (Вызов сервера)
// См. ОбщегоНазначенияСервер.ОстатокНаСкладе
Функция ОстатокНаСкладе(Склад, Дата) Экспорт
Возврат ОбщегоНазначенияСервер.ОстатокНаСкладе(Склад, Дата);
КонецФункции
Такой подход позволяет хранить описание логики и параметров только в одном месте. Если вы используете среду разработки 1C:EDT, аннотации типа @see помогут среде автоматически связывать эти методы, обеспечивая удобную навигацию.
Выясним важный момент: модуль вызова сервера не всегда является «пустой» оберткой. Одной из его ключевых функций является преобразование типов. Серверные методы часто работают с объектами, которые недоступны на клиенте или не могут быть переданы по сети (например, ТаблицаЗначений, МенеджерЗаписи).
Проанализируем пример, где модуль вызова сервера выступает в роли адаптера:
// В серверном модуле логика работает с таблицей значений
Функция ПолучитьДанныеДляОтчета() Экспорт
ТЗ = Новый ТаблицаЗначений;
// ... заполнение ТЗ ...
Возврат ТЗ;
КонецФункции
// В модуле вызова сервера мы преобразуем ТЗ в массив структур для клиента
Функция ПолучитьДанныеДляОтчета() Экспорт
ДанныеТЗ = МойСерверныйМодуль.ПолучитьДанныеДляОтчета();
Возврат ОбщегоНазначения.ТаблицаЗначенийВМассив(ДанныеТЗ);
КонецФункции
В этом случае это уже не «лишний шаблонный код», а необходимая логика подготовки данных для передачи на тонкий клиент. При таком подходе клиент всегда получает универсальные коллекции (массивы, структуры), а сервер внутри себя оперирует производительными серверными типами.
Чтобы ваш код соответствовал стандартам и был понятен другим разработчикам, придерживайтесь следующей классификации модулей, предложенной в методиках 1С:
Важный нюанс: Стандарты разработки 1С рекомендуют не ставить флаг Внешнее соединение у модулей вызова сервера. Это подтверждает концепцию того, что данные модули предназначены исключительно для взаимодействия Клиент -> Сервер.
Подводя итог, разберем по шагам создание идеальной обертки:
ИмяМодуляСервер. Тщательно задокументируйте все параметры и возвращаемые значения.ИмяМодуляВызовСервера одноименную функцию.// См. ИмяМодуляСервер.ИмяПроцедуры.ТаблицуЗначений, в обертке обязательно преобразуйте ее в Массив структур.Следуя этим правилам, вы обеспечите модульность системы, упростите поддержку кода и избежите накопления «мертвой» документации, которая со временем перестает соответствовать реальности. Помните: хороший код — это код, который легко читать и трудно сломать при рефакторинге.