Перейти к содержанию

Dependency Inversion Principle (DIP)

DIP требует, чтобы высокоуровневая логика зависела от абстракций, а не от конкретных деталей инфраструктуры.

Что означает в 1С

Бизнес-сервису лучше знать про контракт поставщика курсов, уведомлений или оплаты, чем напрямую зависеть от конкретного HTTP-клиента, банка или внешней системы.

В 1С это часто проявляется в двух очень практических местах.

  • При работе с внешними компонентами прикладной код стараются завязывать не на конкретный COM-объект или бинарную компоненту, а на общий модуль или подсистему-обертку.
  • В механизмах печати роль стабильной границы часто играет ТабличныйДокумент: прикладной код зависит от факта, что на выходе есть готовое табличное представление, а не от конкретного устройства печати, формата файла или способа показа пользователю.

То есть DIP в 1С не всегда выглядит как "классический интерфейс" в коде. Иногда роль абстракции выполняет:

  • общий модуль с контрактом поверх внешней компоненты;
  • подсистема, которая централизует подключение внешнего кода;
  • промежуточное представление вроде ТабличныйДокумент.

Это хорошо видно в: - #std548: Формирование печатных форм и #std789: Разработка печатных форм с учетом возможного внесения изменений в макет пользователем по сути закрепляют разделение между получением данных и выводом печатной формы.

Пример на 1С

Var Gateway;

Procedure SetGateway(Gateway_) Export

    Gateway = Gateway_;

EndProcedure

Procedure Pay(InvoiceRef, Amount) Export

    Gateway.Pay(InvoiceRef, Amount);

EndProcedure
Procedure Pay(InvoiceRef, Amount) Export

    // Specific bank integration.

EndProcedure

Частый пример с печатью

В печатных механизмах DIP часто выглядит так: прикладной код подготавливает ТабличныйДокумент, а уже другой слой решает, показать его, распечатать, сохранить или отправить дальше.

В этом смысле ТабличныйДокумент выступает как инвертирующая граница между бизнес-логикой подготовки печати и конкретным способом вывода.

Функция СформироватьПечатнуюФорму(ДокументСсылка) Экспорт

    ТабДок = Новый ТабличныйДокумент;
    // Заполнение областей и вывод данных.
    Возврат ТабДок;

КонецФункции

Процедура Печать(ДокументСсылка) Экспорт

    ТабДок = СформироватьПечатнуюФорму(ДокументСсылка);
    ТабДок.Показать();

КонецПроцедуры

Если позже форма будет не показываться на экране, а, например, сохраняться в файл или уходить во внешний сервис печати, высокоуровневый код, который отвечает за состав печатной формы, можно оставить прежним.

Где полезен

  • в интеграциях с банками, API и внешними сервисами;
  • при работе с внешними компонентами через обертки и подсистемы;
  • в механизмах печати, где ТабличныйДокумент служит стабильным контрактом;
  • в прикладных сервисах, которые должны переживать смену провайдера;
  • в тестируемой бизнес-логике.

Когда применяют неправильно

  • когда абстракции вводятся без реальной точки изменения;
  • когда высокий уровень по-прежнему знает слишком много о деталях;
  • когда простую зависимость усложняют ради формального следования принципу.