Паттерн Стратегия. Как он нам помогает

08.08.25

Разработка - Инструментарий разработчика

Как паттерн Стратегия упростил разработку сервиса взаимодействия. Решение позволило изолировать бизнес-логику, легко дорабатывать алгоритмы, соблюдая принципы SOLID, и упростило тестирование.

Паттерны - это проверенные решения; стандартизация кода; общий программистский словарь.

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

 

 

 

Наш опыт

 

У нас есть база IDM, которая находится в РФ, консолидирует информацию и управляет N-ным количеством других баз, называемых WE и находящиеся в других странах. По сути IDM агрегирует и управляет данными других баз. Эти базы могут быть разными — с разными версиями и бизнес-логикой. IDM выступает в роли центра, откуда приходят команды:

  • чтение данных
  • проверка доступности
  • обновление служебной информации
  • изменение данных
  • и т.д.

Раздумывая над возможными вариантами команд, мы пришли к выводу, что для выполнения любой команды из IDM базам WE нужно:

  • прочитать команду
  • понять что нужно сделать
  • выполнить команду
  • отправить ответ/результат

Звучит просто: IDM говорит “сделай”, а WE постоянно проверяют наличие команды и, в случае её наличия, выполняют команду. Для выполнения используют определенный алгоритм, нужный конкретной команде. При этом механизм чтения команды и отправки, по сути, не меняется. А алгоритмы могут сильно отличаться, меняться и зависеть от версии WE. Соответственно нужен подход, который позволит легко дополнять и менять алгоритмы выполнения команд, не меняя чтение и отправку. Именно здесь на помощь приходит паттерн Стратегия.

У нас есть МенеджерКоманд - он является Клиентом. В наших базах он постоянно читает кафку в поисках команд. Если находит подходящую, тогда использует свой метод Processor, передает в него Message, создает контекст, выясняет по Message, какую стратегию нужно использовать, помещает стратегию в контекст и запускает у контекста метод начала работы - Start().

 

 

Procedure Processor(Message) Export

	Headers = EnterpriseServiceBusClientServer.MessageHeadersInStructure(Message.Headers);

    // проверяем нужно ли выполнять эту команду
	If MessageForAnotherCountry(Headers) Then
		Return;
	EndIf;

    // создаем контекст
	Context = DataProcessors.IDM_Context.Create();

	// создаем стратегию
	Strategy = Strategy(Message.Value,
						Headers,
						StrategyBaseName(Headers.Strategy),
						Number(Headers.Version),
						Number(Headers.Downgrading));

	// Помещаем в контекст стратегию и запускаем работу контекста
	Context.SetStategy(Strategy).Start();

EndProcedure

 

Контекст в свою очередь получает какую-то Стратегию и вызывает у неё нужные методы в правильной последовательности, проверяет успешность их выполнения. Для подключения Стратегии к Контексту, внутри Стратегии нужно реализовать определенный интерфейс - иначе ничего работать не будет. 

 

 

Function Start() Export

	Result = Strategy.ProcessorRecipient();

	If Not Result.IsSuccess Then
		IDM_Common.SendError(Result);
	EndIf;

	Result = Strategy.ProcessorSender();

	If Not Result.IsSuccess Then
		IDM_Common.SendError(Result);
	EndIf;

	Return ThisObject;

EndFunction

 

Стратегии выполняют различные алгоритмы в зависимости от целей. Например, метод ProcessorRecipient() может: корректно расшифровывать сообщение, создать объекты в базе, выполнить запрос, или просто вернуть “успех” в контекст и ничего не делать. Затем Контекст вызывает ProcessorSender(), который собирает ответ, отправить его, чистит хвосты и тоже возвращает результат. Каждую стратегию мы можем настраивать отдельно - единственное требование: реализация наш Интерфейса (два упомянутых выше метода и структура ответа).

 

 

Function ProcessorRecipient() Export

	// Тут должна быть бизнес-логика. Или например:
	// ни чего не делаем возвращаем результат, что метод отработал корректно.
	Return IDM_Common.Result(True);

EndFunction

Function ProcessorSender() Export

	// Тут бизнес-логика

	// отправка сообщения обратна в кафку

	// возвращаем результат отправки метода
	Return Result;

EndFunction

 

Что мы получили?   

  1. Лёгкое масштабирование. Добавить новую команду - это просто создать новый объект, реализующий стандартный интерфейс Стратегии. Ни МенеджерКоманд, ни Контекст при этом менять не нужно. Мы соблюдаем SOLID, а именно принцип Открытости/Закрытости (OCP) - система открыта для расширения (добавление новых стратегий), но закрыта для модификации (основной код контекста и менеджера команд не меняется).
  2. Код стал чище и понятнее. Без паттерна и SOLID пришлось бы писать гигантские Если ... ИначеЕсли ... реализуя внутри одного метода выполнение всех типов команд. Стратегия разделяет это на отдельные объекты - так проще читать и поддерживать.
  3. Более спокойное изменение алгоритмов. Стратегия следует принципу единственной ответственности (SRP): изменение одной стратегии не влечет изменений в других частях системы. Это также отделяет бизнес-логику от работы с брокером сообщений, обработкой ошибок и логированием. Контекст работает с абстракциями (интерфейсом), а стратегии реализуют этот интерфейс, не зная, кто их использует — это принцип инверсии зависимостей (DIP).
  4. Проще тестировать. Конкретные стратегии - являются самостоятельными объектами с четким интерфейсом. Это дает возможность, подкидывать контекст и проверять ожидаемый результат. Спасибо коллегам из YAxUnit за удобный фреймворк.

Коллеги, Стратегия - это паттерн, который облегчает нам жизнь. Разработка становится проще. Попробуйте - вам понравится :)

 

Какие ещё интересные штуки мы используем и как они нам помогают, вы можете послушать на моем докладе, который я готовлю к Infostart 2025. Проголосовать и тем самым поддержать автора, можно тут: https://event.infostart.ru/2025/agenda/2443472/

Вступайте в нашу телеграмм-группу Инфостарт

Паттерн Стратегия SOLID

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

10000 руб.

02.09.2020    269036    1497    422    

1180

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Программист Руководитель проекта 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP, УНФ, КА и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы, интерфейс 8.5. Может выполнять свертку одновременно в несколько потоков, а также без непосредственного участия пользователя. Решение в Реестре отечественного ПО.

24900 руб.

20.08.2024    75468    381    170    

326

Пакетная печать Печатные формы Инструментарий разработчика Программист 1С:Предприятие 8 Платные (руб)

Расширение для создания и редактирования печатных форм в системе 1С:Предприятие 8.3. Благодаря конструктору можно значительно снизить затраты времени на разработку печатных форм, повысить качество и прозрачность разработки, а также навести порядок в многообразии корпоративных печатных форм. Обновление версии от 21.04.26

22570 руб.

06.10.2023    40320    115    54    

127

Инструментарий разработчика Нейросети Платные (руб)

Первые попытки разработки на 1С с использованием больших языковых моделей (LLM) могут разочаровать. LLMки сильно галлюцинируют, потому что не знают устройства конфигураций 1С, не знают нюансов синтаксиса. Но если дать им подсказки с помощью MCP, то результат получается кардинально лучше. Далее в публикации: MCP для поиска по метаданным 1С, справке синтакс-помощника и проверки синтаксиса.

15250 руб.

25.08.2025    64224    130    36    

139

Инструментарий разработчика Разработка Администрирование веб-серверов Системный администратор Программист Бизнес-аналитик Руководитель проекта 1С 8.3 Платные (руб)

Analyzer 1C сводит выгрузку 1С — основную конфигурацию и все расширения — в единый граф знаний. Любой запрос по связям за доли секунды, с пометками «Доб.» / «Заимств.» / «Переопределено». Новое в 2.0 — обновление поставки: сравнение и объединение версий деревом «как в Конфигураторе» с выгрузкой плана решений; поиск конфликтов из-за перехватов расширений и висячих ссылок; загрузка из бинарных .cf/.cfe; циклические зависимости. Плюс анализ влияния, запросы BSL, роли и RLS, граф вызовов. Минута на развёртывание через Docker без необходимости подключения к Интернет. Любая 1С:Предприятие 8.3+.

14000 руб.

17.04.2026    9115    39    50    

54

Инструменты администратора БД Инструментарий разработчика Роли и права Программист 1С:Предприятие 8 1C:Бухгалтерия Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

17000 руб.

10.11.2023    26518    98    46    

104

Информационная безопасность Инструменты администратора БД Инструментарий разработчика Учет документов Системный администратор Программист Бизнес-аналитик Бухгалтер Пользователь Руководитель проекта 1С 8.3 1С 8.5 Розничная и сетевая торговля (FMCG) Платные (руб)

Контроль ввода данных в 1С: проверка заполнения реквизитов, обязательные поля, контроль перед записью и проведением, запрет проведения документа. Позволяет настраивать любые проверки данных в 1С 8.3/8.5 от обязательных полей до сложных условий – без открытия конфигуратора и написания кода. Готовое расширение, которое подключается и работает сразу.

6000 руб.

15.04.2026    2704    6    0    

21

Инструментарий разработчика Программист 1С:Предприятие 8 Платные (руб)

Инструмент для написания и отладки кода в режиме «1С:Предприятие». Представляет собой консоль кода с возможностью пошаговой отладки, просмотра значений переменных любых типов, использования процедур и функций, просмотра стека вызовов, вычисления произвольных выражений на встроенном языке в контексте точки останова, синтаксического контроля и остановки по ошибке. В консоли используется удобный редактор кода с подсветкой, контекстной подсказкой, возможностью вызова конструкторов запроса и форматной строки. 1.3.11 Доработан механизм контекстной подсказки по метаданным

9500 руб.

17.05.2024    54900    188    63    

220
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ltfriend 12.08.25 11:55 Сейчас в теме
Извиняюсь за то, что не по теме (ой, извините, за off-topic), а почему комментарии в коде на русском?
2. Pavel791 3 12.08.25 12:02 Сейчас в теме
(1) Для статьи написал, в реальном модуле этих комментариев нет
3. kasper076 116 14.08.25 15:58 Сейчас в теме
Контекст это, видимо, обработка. Стратегия это, допустим, таблица значений. Но ведь выходит, что Если / ИначеЕсли просто переехали в метод создания Стратегии.
4. Pavel791 3 20.08.25 05:53 Сейчас в теме
(3) Стратегия - это тоже обработка. Не совсем Если / ИначеЕсли.

	StrategyName = StrategyBaseName + CurrentVersion;

	If Metadata.DataProcessors.Find(StrategyName) <> Undefined Then
		Return DataProcessors[StrategyName].CreateStrategy(Message, Headers);
	Else


Наш фабричный метод создает стратегию по определенному правилу. Если не получится, то отправит ошибку, что пришел запрос на неизвестную стратегию.

Внутри метода CreateStrategy() у каждой стратегии может быть свой алгоритм создания.
5. kasper076 116 22.08.25 09:22 Сейчас в теме
(4) Прикольно. Но это типа глобальные процессы так можно разделить. А вот другая ситуация. У меня есть обработка по загрузке справочников. Справочником несколько и делать под загрузку каждого из них обработку ну такое себе. И в итоге в коде довольно длинное Если/ИначеЕсли. А от этого цикломатическая сложность возрастает. Как в этой ситуации быть?
6. Pavel791 3 22.08.25 11:39 Сейчас в теме
(5) Почему делать загрузку каждого из них такое себе? У нас это универсальная обработка, кроме момента разбора, что это за справочник?
7. Pavel791 3 25.08.25 01:59 Сейчас в теме
(4) У нас это универсальная обработка, кроме момента разбора, которая определяет, что это за справочник?
Для отправки сообщения требуется регистрация/авторизация