При разработке сложных интеграционных решений на платформе 1С часто возникает задача: нужно описать структуру данных из внешнего API (например, развесистый JSON с десятком вложенных сущностей), обеспечить связи между ними и выполнять обработку в памяти, не создавая при этом реальные справочники или документы в дереве метаданных. Создание «временных» объектов метаданных замусоривает конфигурацию, усложняет обновление и замедляет работу. В этой статье мы разберем несколько профессиональных подходов к реализации объектной модели «в коде».
XDTO (XML Data Transfer Objects) — это, пожалуй, самый мощный механизм для создания строгой объектной модели без привязки к таблицам базы данных. Несмотря на название, современные версии платформы позволяют легко конвертировать XDTO в JSON и обратно.
Преимущества подхода:
Рассмотрим пример создания объекта через XDTO и его сериализацию. Для этого сначала создадим XDTO-пакет в конфигураторе (это не создает таблиц в БД), а затем используем программный код:
// Создание объекта на основании типа из XDTO-пакета
ТипПользователь = ФабрикаXDTO.Тип("http://my-integration-api", "User");
НовыйПользователь = ФабрикаXDTO.Создать(ТипПользователь);
НовыйПользователь.ID = "123";
НовыйПользователь.Name = "Иван Иванов";
// Если нужно передать в JSON для API
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ФабрикаXDTO.ЗаписатьJSON(ЗаписьJSON, НовыйПользователь);
РезультатJSON = ЗаписьJSON.Закрыть();
Для десериализации ответа от API мы можем написать универсальную функцию, которая избавит нас от ручного разбора полей:
Функция ПрочитатьОтветВМодель(СтрокаJSON, ИмяТипа) Экспорт
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
ТипОбъекта = ФабрикаXDTO.Тип("http://my-integration-api", ИмяТипа);
Возврат ФабрикаXDTO.ПрочитатьJSON(ЧтениеJSON, ТипОбъекта);
КонецФункции
Если API часто меняется или модель слишком проста для XDTO, логично использовать стандартные коллекции 1С: Структура и Соответствие. Это наиболее «легкий» способ, который идеально сочетается с нативной поддержкой JSON в платформе 8.3.
Рассмотрим ситуацию, когда нам нужно имитировать «классы» и «конструкторы», чтобы избежать дублирования кода (boilerplate). Мы можем создать общий модуль МоделиДанных:
Функция СоздатьМодельВеткиФорума() Экспорт
Модель = Новый Структура;
Модель.Вставить("Идентификатор", "");
Модель.Вставить("Заголовок", "");
Модель.Вставить("Автор", Неопределено); // Ссылка на другую структуру (Пользователь)
Модель.Вставить("Сообщения", Новый Массив); // Список структур
Возврат Модель;
КонецФункции
Проблема локализации: Часто API возвращает английские имена полей (first_name), а в коде 1С мы хотим работать с русскими (Имя). Для этого проанализируем подход с «картой соответствия». Мы создаем функцию-маппер, которая при получении данных перекладывает их в нашу структуру с удобными именами. Это позволяет изолировать логику интеграции от бизнес-логики.
Когда данных много (тысячи объектов) и между ними нужны сложные связи (например, многие-ко-многим), структуры становятся неудобными. В этом случае проанализируем использование ТаблицыЗначений.
Как реализовать связи в ТЗ:
ТЗ_Пользователи и ТЗ_Заказы).ТЗ_Заказы добавляем колонку ID_Пользователя.НайтиСтроки() или индексацию колонок.Важный момент: чтобы модель была «человечной», мы можем хранить в колонке таблицы не просто ID, а прямую ссылку на строку другой таблицы. Рассмотрим, как это выглядит в памяти:
// Предположим, ТЗ_Авторы уже заполнена
ПараметрыПоиска = Новый Структура("ID", ТекущийIDАвтора);
НайденныеСтроки = ТЗ_Авторы.НайтиСтроки(ПараметрыПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
НоваяВетка = ТЗ_Ветки.Добавить();
НоваяВетка.Автор = НайденныеСтроки[0]; // Храним ссылку на строку другой ТЗ
КонецЕсли;
Этот подход позволяет обращаться к данным через точку: ТекущаяВетка.Автор.Имя, что максимально приближает нас к поведению стандартных объектов 1С.
Если вашей модели нужно не только хранить данные, но и обладать поведением (методами), рассмотрим использование внешних обработок или объектов конфигурации типа Обработка.
Каждый экземпляр обработки может представлять собой один объект модели. Реализация:
Модель_Пользователь.ПроверитьЗаполнение() или ОтправитьНаСервер().Работа с такой моделью будет выглядеть так:
Пользователь = Обработки.Модель_Пользователь.Создать();
Пользователь.Имя = "Алексей";
Пользователь.Валидация();
Выясним, какой метод выбрать в зависимости от условий задачи:
Важный совет: Для решения проблемы отображения на форме (когда у нас есть массив структур, а нужно показать таблицу), используем метод ЗаполнитьЗначенияСвойств в цикле. Чтобы не писать это каждый раз вручную, проанализируем возможность создания универсального механизма «Маппера», который по именам колонок ТЗ будет автоматически вычитывать данные из массива структур.
Разберем пример такого универсального заполнения:
Процедура ЗаполнитьТЗИзМассиваСтруктур(ТЗ, МассивДанных) Экспорт
ТЗ.Очистить();
Для Каждого ДанныеОбъекта Из МассивДанных Цикл
НоваяСтрока = ТЗ.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ДанныеОбъекта);
КонецЦикла;
КонецПроцедуры
Используя эти подходы, мы можем строить эффективные и чистые объектные модели в 1С, сохраняя высокую скорость работы системы и удобство поддержки кода.