В процессе разработки на платформе 1С:Предприятие 8.3 часто возникают вопросы, связанные с взаимодействием различных программных слоев. Один из типичных сценариев: у нас есть общий модуль, у которого установлен флаг «Вызов сервера», и мы пытаемся обратиться к его экспортным методам из другого серверного модуля. На первый взгляд, это кажется удобным, но давайте разберем ситуацию подробно, чтобы понять, какие последствия это несет для архитектуры и производительности системы.
Проанализируем техническую сторону вопроса. Платформа 1С не накладывает жесткого запрета на подобные вызовы. Если процедура или функция в модуле с флагом «Вызов сервера» помечена ключевым словом Экспорт, она будет доступна для вызова из любого серверного контекста. Рассмотрим пример кода, который часто вызывает споры:
Процедура ВыполнитьРасчеты(НоменклатураСсылка) Экспорт
// Вызов из обычного серверного модуля
РезРасчета = _РасчетНоменклатурыВызовСервера.ВыполнитьРасчет(НоменклатураСсылка);
// Дальнейшая логика обработки...
КонецПроцедуры
Если в модуле _РасчетНоменклатурыВызовСервера процедура ВыполнитьРасчет объявлена как экспортная, система успешно выполнит этот код. Как отмечают участники обсуждения, ограничений на уровне компиляции здесь нет. Однако важно понимать, почему опытные разработчики называют такой подход «неправильным».
Выясним причину, по которой существуют рекомендации разделять модули. Флаг «Вызов сервера» (Server Call) предназначен исключительно для одной цели: предоставить программный интерфейс клиентскому приложению для обращения к серверным процедурам.
Рассмотрим стандартную иерархию вызовов:
Вызов сервера.Когда мы вызываем модуль «Вызов сервера» из другого серверного модуля, мы нарушаем эту цепочку, заставляя серверный код обращаться к интерфейсному слою, предназначенному для клиента. Это создает избыточную связанность кода.
Проанализируем ситуацию с точки зрения ресурсов системы. Каждый экспортный метод в модуле с флагом «Вызов сервера» регистрируется платформой в специальном реестре методов, доступных для удаленного вызова (маршаллинга). Это увеличивает объем метаданных, которые платформа обрабатывает при инициализации сеанса и передаче контекста между слоями.
Если мы начинаем «складировать» в таких модулях всю серверную логику только потому, что нам удобно вызывать её и с клиента, и с сервера, мы неоправданно раздуваем интерфейсную часть системы. В больших конфигурациях это может привести к замедлению работы интерфейса и увеличению потребления памяти клиентским приложением.
Если вы обнаружили, что вам необходимо вызвать метод модуля «Вызов сервера» из другого серверного модуля, давайте разберем правильный алгоритм действий по шагам:
Сервер (флаг Вызов сервера должен быть снят).Вызов сервера оставьте только вызов этого метода.Посмотрим на пример правильной организации кода. Было:
// Модуль: _РасчетНоменклатурыВызовСервера (Сервер, Вызов сервера)
Функция ПолучитьЦену(Товар) Экспорт
// Сложный запрос к БД
Возврат РезультатЗапроса;
КонецФункции
Стало (правильный вариант):
// Модуль: НоменклатураСервер (Только флаг Сервер)
Функция ПолучитьЦену(Товар) Экспорт
// Сложный запрос к БД здесь
Возврат РезультатЗапроса;
КонецФункции
// Модуль: _РасчетНоменклатурыВызовСервера (Сервер, Вызов сервера)
Функция ПолучитьЦену(Товар) Экспорт
// Тонкая обертка для клиента
Возврат НоменклатураСервер.ПолучитьЦену(Товар);
КонецФункции
В этом случае любой другой серверный модуль будет обращаться напрямую к НоменклатураСервер.ПолучитьЦену(), что соответствует стандартам разработки 1С:Совместимо.
Как отметили участники обсуждения на форуме, иногда «голоса в голове» или жесткие дедлайны заставляют писать код быстрее. В небольших доработках или внешних обработках вызов ВызовСервера из серверного контекста не приведет к немедленному падению системы. Технически это будет работать, так как контекст исполнения уже находится на сервере, и платформа просто перейдет к выполнению метода в том же сеансе без сетевых задержек.
Однако при проектировании тиражных решений или крупных корпоративных систем следует строго придерживаться разделения ответственности. Модули с флагом «Вызов сервера» должны оставаться максимально «тонкими» и не содержать бизнес-логики, которую хотелось бы повторно использовать внутри сервера.
Подведем итог нашему анализу:
Экспорт.Соблюдение этих простых правил сделает ваш код более понятным, упростит поиск ссылок и обеспечит высокую производительность системы в долгосрочной перспективе.