Каталог решений - Прокси-функции

Прокси-функции

Прокси-функции

В наличии

Прокси-функция — техническая, не содержащая непосредственно в себе основную логику, функция-обертка, функция-представитель, которая предназначена для совершения "прозрачного" вызова (возможно проходящего через границы различных систем) другой функции, которая содержит в себе всю основную логику.

Категория:

Описание

Давайте рассмотрим такую ситуацию.

У нас две базы: одна основана на конфигурации «Управление торговлей» (далее по тексту УТ), а другая на конфигурации «Розница» (далее по тексту РТ). Между базами настроен типовой онлайн обмен. Обе конфигурации сняты с поддержки и мы вольны дорабатывать их как пожелаем. В базе «Розница» учет себестоимости не ведется.

Вдруг возникает необходимость определения себестоимости номенклатуры в базе РТ. Сразу скажу, что первая мысль которая приходит: «Наверное, в нашей архитектуре что-то не так!». Но сейчас мы не будем это обсуждать.

Вторая мысль, которая приходит: «Подключусь к базе УТ из базы РТ используя ComConnector и получу любые данные, которые потребуются». Если воплотить эту мысль в функцию ПолучитьСебестоимостьНоменклатуры(Номенклатура), реализованую в конфигурации РТ, то мы совершим 2 ошибки:

  • Смешаем технические особенности написания кода при использовании ComConnector-а и требуемую логику работы
  • Разместим логику работы не в подходящем месте — вдали от нужных данных

Как сделать лучше?

А давайте функцию по получению себестоимости реализуем в конфигурации УТ, в области видимости для внешних соединений (пусть это будет модуль внешнего соединения).

Процедура ПолучитьСебестоимостьНоменклатуры(Номенклатура) Экспорт
     //Понятная всем реализация алгоритма получения себестоимости номенклатуры
     Возврат Себестоимость;
КонецПроцедуры

В свою очередь, в конфигурации РТ добавим общий модуль «МодульПроксиУТ», и все описанные ниже функции разместим в нем. Слово «Прокси» в названии общего модуля — это напоминание того как на самом деле все устроено.

Функция ПолучитьСебестоимостьНоменклатуры(Номенклатура, СоединениеУТ = Неопределено) Экспорт //прокси-функция
    //Соединямеся с УТ, если нам не передали соединение
    Если СоединениеУТ = Неопределено Тогда
        СоединениеУТ = ПолучитьСоединениеУТ();
    КонецЕсли;
    //Переводим входящие параметры в объекты понятные УТ
    НоменклатураУТ = ПолучитьСсылкуУТ(СоединениеУТ, Номенклатура);
    //Вызываем функцию, содержащую основную логику
    Себестоимость = СоединениеУТ.ПолучитьСебестоимостьНоменклатуры(НоменклатураУТ);
    //Обрабатываем результат и переводим в объекты понятные РТ, в данном примере этого не требуется
    Возврат Себестоимость;
КонецФункции

Процедура ПолучитьСоединениеУТ() Экспорт
     //Определяем данные для подключения к базе УТ и создаем соединение
     Соединитель = Новый COMObject("V82.COMConnector");
     Соединение = Соединитель.Connect(СтрокаПодключения);
     Возврат Соединение;
КонецПроцедуры

Функция ПолучитьУзелОбменаУТ()   
    //Можно придумать более изящный способ
    Возврат ПланыОбмена.ОбменУправлениеТорговлейРозничнаяТорговля.НайтиПоКоду("001");    
КонецФункции

Функция ПолучитьСсылкуУТ(СоединениеУТ, СсылкаРТ)
    Запрос = Новый Запрос();
    Запрос.Текст = "ВЫБРАТЬ
                   |    СоответствиеОбъектовДляОбмена.СобственнаяСсылка КАК СсылкаРТ,
                   |    СоответствиеОбъектовДляОбмена.СсылкаВДругойИБ КАК СтроковаяСсылкаУТ
                   |ИЗ
                   |    РегистрСведений.СоответствиеОбъектовДляОбмена КАК СоответствиеОбъектовДляОбмена
                   |ГДЕ
                   |    СоответствиеОбъектовДляОбмена.УзелОбмена = &УзелОбменаУТ
                   |    И СоответствиеОбъектовДляОбмена.СобственнаяСсылка = &СсылкаРТ";
    Запрос.УстановитьПараметр("СсылкаРТ", СсылкаРТ);
    Запрос.УстановитьПараметр("УзелОбменаУТ", ПолучитьУзелОбменаУТ());
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Возврат СоединениеУТ.ЗначениеИзСтрокиВнутр(Выборка.СтроковаяСсылкаУТ);
    Иначе
        ВызватьИсключение "Понятный текст исключения";
    КонецЕсли;   
КонецФункции

Как использовать?

Получение себестоимости номенклатуры в РТ станет красивым и понятным (про производительность и архитектурность я молчу).

В случае если нам нужно получить себестоимость по одной номенклатуре, то достаточно:

Себестоимость = МодульПроксиУТ.ПолучитьСебестоимостьНоменклатуры(Номенклатура);

В случае если нам нужно получить себестоимость сразу по нескольким номенклатурам, то прозрачность кода несколько теряется:

СоединениеУТ = МодульПроксиУТ.ПолучитьСоединениеУТ();
Себестоимость1 = МодульПроксиУТ.ПолучитьСебестоимостьНоменклатуры(Номенклатура1, СоединениеУТ);
Себестоимость2 = МодульПроксиУТ.ПолучитьСебестоимостьНоменклатуры(Номенклатура2, СоединениеУТ);

Особенности прокси-функции

  • Количество параметров в прокси-функции на 1 больше чем в реальной — последним параметром передается необязательный параметр соединения
  • Первый логический блок функции содержит код по установлению соединения, в случае, если его не установили ранее
  • Второй логический блок функции содержит код для перевода входящих параметров в понятные для УТ объекты
  • Третий логический блок функции содержит, собственно, вызов реальной функции.
  • Четвертый логический блок функции содержит код для перевода результата в понятные для РТ объекты и возвращает результат.

Особенности реализации примера

Справедливости ради нужно сказать, что текущий пример реализации не лишен недостатков. Например, при передаче пустых ссылок или ссылок на перечисления будут возникать проблемы. Так же в статье не описано, как реализовать четвертый логический блок код в прокси-функции, но в этом тоже нет ничего сложного. Наверняка есть и другие подводные камни, которые, я уверен, удастся всегда обойти.

Чего мы добились?

  • Разделили технические особенности при работе с ComConnector-ом и основную логику работы
  • Разместили код основной логики в правильном месте
  • Ну и, как следствие, получили более понятный и удобный для поддержки код

Заключение

Статья не о том как получить себестоимость номенклатуры в РТ по данным УТ, а о том как, используя идею прокси-функций, писать более «чистый» код. Я считаю, что описанный подход нужно по возможности использовать всегда при интеграции с другими системами, а не только при использовании ComConnector-a.

Спасибо за внимание!

 

 

has been added to your cart:
Оформление заказа