Принципы ООП в 1С (pattern Iterator)

12.07.18

Разработка - Рефакторинг и качество кода

Iterator или курсор, один из паттернов который реально применяю в повседневной жизни.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Принципы ООП в 1С (pattern Iterator): Пример реализации
.zip 7,76Kb
4 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

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

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

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

Для Каждого Стр Из Таб Цикл
	// Выполняем какие-то действия с Стр
КонецЦикла;

Ок написали цикл и все хорошо, через какое-то время появляется необходимость в алгоритме получить номер строки (элемента если у нас массив), что мы делаем, добавляем счетчик

Счетчик = 0;
Для Каждого Стр Из Таб Цикл
  // Выполняем какие-то действия с Стр
  Счетчик = Счетчик +1;
КонецЦикла;

Можно конечно и так

Для а = 0 По Таб.Количество()-1 Цикл
  // Выполняем какие-то действия
КонецЦикла;

но тогда нам нужно по всему телу цикла менять Стр на Таб[а] или в начале объявлять  Стр = Таб[а]; т.е. обеспечивать совместимость изменений со старой реализацией. 

И в первом примере с объявлением переменной счетчик и во втором с Стр = Таб[а]; обе переменные избыточные, вы вынуждены были их ввести т.к. изменился алгоритм. 

В первом примере, на какие грабли мы можем наступить, ну к примеру у нас тело цикла достаточно большое, где-то в середине мы (или другой разработчик) пишем Продолжить;, и все, нам эта строка поломала всю логику. 

А если нам нужно коллекцию перебрать в обратной последовательности? А если нужно сортировать массив? Начинаем городить огород и причем этот огород в каждом месте нашего проекта, где потребовалось, там и сделали. 

Эти все проблемы решает паттерн курсор.

Курсор = Обработки.КурсорТаблицаЗначений.Создать().Конструктор(Таб).Имплементация("КурсорИнтерфейс");
Пока Курсор.Следующий() Цикл
  // Выполняем какие-то действия
КонецЦикла;

Обращение к текущему элементу Курсор.ТекущийЭлемент(), обращение к индексу Курсор.ТекущийИндекс(), хотите делаете метод Сортировать(), хотите делаете сеттер а-ля  Курсор.ОбратныйПеребор(Истина) и бог его знает что вы еще добавите в курсор и эта ваша фишка будет доступна для любых коллекций, таблица значений, массив, структура и прочие. Единственное будут меняться реализации курсора, например

Курсор = Обработки.КурсорМассив.Создать().Конструктор(МойМассив).Имплементация("КурсорИнтерфейс");
Пока Курсор.Следующий() Цикл
  // Выполняем какие-то действия
КонецЦикла;

 

Если свою реализацию положить на диаграмму классов получим.

т.е. из классической схемы убран агрегатор в квази ООП он кажется избыточным.

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

ООП pattern Iterator Iterator GoF pattern ООП в 1С

См. также

Инструментарий разработчика Рефакторинг и качество кода Программист 1С 8.3 Абонемент ($m)

Обработка читает исходники других внешних обработок и отчётов прямо из базы и отвечает на два вопроса: с какой из них начинать смотреть и что именно в ней смотреть. На выходе HTML-отчёт: индекс качества от 0 до 100, светофор, оценка технического долга в минутах и находки с номером строки, фрагментом кода и подсветкой синтаксиса. Двадцать восемь правил: запрос в цикле, транзакция без отката, небезопасное выполнение строки, тяжёлые схемы компоновки. Считается всё на чистом BSL, без интернета, внешних компонент и отдельного сервиса рядом, поэтому анализируемый код не покидает машину. Прогон по двум десяткам обработок выстраивает их по индексу качества, худшие сверху, и сразу видно, с чего начинать разбор.

10 стартмани

20.08.2026    242    1    nedomolkov.ivan    2    

2

Рефакторинг и качество кода Программист 1С 8.3 Бесплатно (free)

Библиотека из 6 слоев анализа, от внешней обработки до готового отчёта. Каталог из двадцати восьми правил, у каждого свой уровень и вес. И всё это крутится на чистом BSL, без Java, без git, без какого-то внешнего сервера анализа и без отправки чужого кода наружу. Разбираю, как устроен этот анализатор внешних обработок и по каким признакам он решает, что код плохой. Почему запрос в цикле получает шестьдесят баллов, как правило вообще проходит фильтр перед релизом и почему часть правил у меня помечена как сломанные. Проверял я его на себе: взял семнадцать своих обработок, которые лежат на площадке и продаются. Получил 239 замечаний и пятнадцать рабочих дней технического долга. У самой худшей индекс качества - 20 из 100 и красный светофор. А ещё расскажу, где у инструмента границы, за которые он не заходит, и про грабли - самая дорогая из них молчала.

20.08.2026    318    nedomolkov.ivan    0    

1

Рефакторинг и качество кода Программист 1С 8.3 Бесплатно (free)

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

20.08.2026    383    n_mezentsev    10    

2

Рефакторинг и качество кода Нейросети Программист Бесплатно (free)

Передача двух модулей BSL в Cursor AI для классического сравнения без использования искусственного интеллекта (ИИ) и для проведения code review с помощью ИИ.

12.08.2026    2416    ScaNNer    0    

5

Рефакторинг и качество кода Обновление 1С Программист 1С 8.3 1С:ERP. Управление холдингом Бесплатно (free)

К нам на проект сложного обновления пришла конфигурация «1С:ERP УХ» с доработанным отчетом, построенным на базе типового «Задолженность поставщикам по срокам». После обновления целевая форма открывалась без учета переданных данных.

05.08.2026    776    1c-izh    4    

4

Инструментарий разработчика Рефакторинг и качество кода Программист 1С 8.3 1С 8.5 1С:Документооборот 1С:Бухгалтерия 3.0 1С:Управление нашей фирмой 3.0 Россия Абонемент ($m)

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

2 стартмани

08.07.2026    847    8    NikolayMaerov    0    

4

Рефакторинг и качество кода Обновление 1С Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Бесплатно (free)

На проекте сложного обновления 1С:ERP 2.4.14.181 до версии 2.5.22.106 нам было нужно уложить обновление в технологическое окно 48 часов (выходные). Исходный замер, с учетом промежуточных релизов 2.5.8.443, 2.5.12.270, 2.5.17.234, 2.5.22.106, показал требуемое время в 659 часов…

07.07.2026    5198    1c-izh    20    

21

Рефакторинг и качество кода Обновление 1С Программист 1С 8.3 Бесплатно (free)

Обновление ролей в расширении 1С отличается от аналогичного процесса в основной конфигурации. Ситуация осложняется, когда доработки вносятся не в «обычное», а в поставляемое расширение.

26.06.2026    2249    1c-izh    3    

5
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. PerlAmutor 162 12.07.18 20:59 Сейчас в теме
Под пиво покатит.
На продакшене, увидев подобное я бы погрузился в древнерусскую тоску.

Практически новый метод обфусцировать код. Спасибо за труды.
talych; monkbest; sbcode; Gorus; dimzfresh; Dragonim; palsergeich; triviumfan; pm74; wbazil; RainyAugust22; LexaSH; json; +13 Ответить
2. lazarenko 243 13.07.18 09:52 Сейчас в теме
(1)
я бы погрузился в древнерусскую тоску.

почему? )))
9. Vladimir Litvinenko 2944 13.07.18 14:12 Сейчас в теме
(2) Потому что мы не привыкли мыслить концепциями ООП и платформа не дает для этого удобных инструментов. Применение ООП фактически идет против сложившейся культуры разработки и, как правило, избегается. По той же причине последние версии БСП кажутся сложными. Как Вы замечали в предыдущих публикациях, там ряд подходов ООП реализован, но с помощью тех возможностей процедурного программирования, которые дает платформа. Поэтому код действительно запутан, а в для реализации позднего связывания часто применяется оператор "Выполнить", усложняющий отладку.

Публикации на самом деле интересные. Применение паттернов в 1С скорее всего усложнит код в случае решения простых задач. Но в случае решения сложных задач или написании библиотек может помочь и сделать решение более гибким. Или даже упростить решение. Непривычность кода тогда можно преодолеть через его документирование и комментирование.

Надеюсь продолжите публикации на эту тему.
talych; babys; CyberCerber; Volfy; lazarenko; +5 Ответить
10. brr 184 13.07.18 15:57 Сейчас в теме
(9) Может разработчики 1С посмотрят на творящийся ужас и скажут: "давай дадим им ООП"
vano-ekt; thevist; talych; CyberCerber; json; +5 Ответить
16. Vladimir Litvinenko 2944 13.07.18 21:18 Сейчас в теме
(10) Кажется, что сейчас у них в приоритете EDT и развитие GUI. Еще судя по партнерскому форуму из планов не убирают переход на микросервисную архитектуру 8.4 и переписывания кучи кода серверной части на Java. Из этого направления пока что только RAS, RAC и система взаимодействия живыми вышли ))

На развитие самого языка скорее всего ресурсов не хватает, и оно идет в основном по пути переноса ряда функций БСП на уровень платформы. Да и появление ООП в платформе было бы спорным решением для российского рынка. Текущие позиции на рынке держатся во многом за счет простоты языка. Если только борьба за международный рынок заставит над развитием языка в этом направлении поработать, как сейчас заставляет работать над EDT.
18. boln 1044 15.07.18 04:24 Сейчас в теме
(16)
Текущие позиции на рынке держатся во многом за счет простоты языка.
Крайне сомнительно. На 1С программируют уже давно не "домохозяйки".
thevist; babys; Gesperid; brr; CyberCerber; +5 Ответить
21. brr 184 16.07.18 12:00 Сейчас в теме
(16)Простота языка уже мешает, сложность конфигураций выросла, язык должен соответствовать.
sergiy8888; pfilyk; boln; talych; Gesperid; +5 1 Ответить
34. babys 91 18.07.18 12:11 Сейчас в теме
(21) Ну тут надо ориентироваться скорее на то, что язык прикладной и насыщать его бизнес функциями как VB for Office, а не тупо гнать в универсальность, не важно с ООП или без оного.
А как пример функциональной простоты С-- можно глянуть :)
3. Synoecium 793 13.07.18 11:07 Сейчас в теме
Ок написали цикл и все хорошо, через какое-то время появляется необходимость в алгоритме получить номер строки (элемента если у нас массив)

используйте тогда метод Индекс(), он почти во всех коллекциях есть
5. lazarenko 243 13.07.18 11:18 Сейчас в теме
(3) ну как же, в самой очевидной коллекции - массив, нету.
6. Synoecium 793 13.07.18 11:33 Сейчас в теме
(5) есть метод, подходящий для массива уникальных значений: Найти(<Значение>)
7. lazarenko 243 13.07.18 11:51 Сейчас в теме
(6) и Вы считаете это не костыль?
8. Synoecium 793 13.07.18 12:23 Сейчас в теме
(7) костыль, по сути это поиск по значению, что медленнее обращения к переменной с индексом. Не умаляя достоинств вашего решения, я вспомнил пару решений, не описанных в статье, как без него обойтись.
4. Synoecium 793 13.07.18 11:12 Сейчас в теме
В первом примере, на какие грабли мы можем наступить, ну к примеру у нас тело цикла достаточно большое, где-то в середине мы (или другой разработчик) пишем Продолжить;, и все, нам эта строка поломала всю логику.

а тут можно просто инкрементировать счетчик в самом начале цикла - просто начинать не с 0, а с -1, либо уменьшать на 1 при получении элемента по индексу
rinat_alp2; +1 Ответить
11. sommid 13.07.18 16:06 Сейчас в теме
минус в том, что это не получится использовать везде, т.к. &НаКлиенте в УФ это не взлетит.. и там все равно будете писать как обычно, и только на сервере продвинуто )
а так идея интересная
вопрос еще в накладных расходах на лишний объект
monkbest; lazarenko; +2 Ответить
13. lazarenko 243 13.07.18 17:52 Сейчас в теме
12. Сурикат 410 13.07.18 16:11 Сейчас в теме
Подскажите, а зачем нам такие накрутки с имплементация , наследованием...?
Ведь на самом деле мы договариваемся, что наш класс должен содержать определенные методы и поля.

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

На мой взгляд наша цель дополнительно зафиксировать соглашения, что в красивом виде платформа сделать не позволяет.
И подобный стиль написания кода тоже.

Но статьи хорошие
Спасибо вам!
l1ike; brr; +2 Ответить
14. lazarenko 243 13.07.18 18:06 Сейчас в теме
(12) Платформа это сделает уже при выполнении, скажет не внятное что-то типа "метод объекта не обнаружен", тут мы себя защищаем от такого и приводим к одному типу "интерфейс".
Вот два примера
1. Если мы заходим например динамически подсовывать обработки, например как в статье про observer (https://infostart.ru/public/858073) мы по хорошему тут же должны проверить сопоставима обработка с интерфейсом или нет.
2. Это удобно для случаев когда нам нужно привести к одному типу, например как в статье про pattern Chain of responsibility (https://infostart.ru/public/851798), там Handler приведен к типу интерфейса. К тому же если рассматривать текущий пример, допустим мы уберем имплементацию и напишем 2 курсора для массива и ТЗ, в одном из курсоров не захотим/забудем реализовать какой-то объект, например сортировку, т.к. он конкретно в нашей задаче не нужен, в целом не страшно, но уже теряется унификация, получится как сейчас у платформы, у какой-то коллекции есть метод Индекс() у какой-то нет. А вообще это ж пример как можно, понятно что можно и без интерфейса, можно вообще и без обработок.
32. lazarenko 243 18.07.18 08:59 Сейчас в теме
(14)
какой-то объект

какой-то метод*
24. l1ike 17.07.18 07:18 Сейчас в теме
(12) Чего только люди не придумают, чтобы не писать тесты.
26. starik-2005 3301 17.07.18 14:31 Сейчас в теме
(24) в Боинге тесты заменили ревизией кода - повысили производительность труда в 8 раз (Макконнелл, "Совершенный код").
27. l1ike 17.07.18 14:50 Сейчас в теме
(26) А если на хаскеле писать, то если скомпилировалось - значит нет ошибок )))
28. starik-2005 3301 17.07.18 15:06 Сейчас в теме
(27)
значит нет ошибок
Не факт. Если нет ошибок в типах, то это не значит, что их вообще нет:
Отличительная черта языка — серьёзное отношение к типизации; во многом в связи с этим язык назван в честь исследователя теории типов и изобретателя комбинаторной логики Хаскелла Карри.
29. l1ike 17.07.18 15:39 Сейчас в теме
(28) Остальные ошибки, как правило, проще отлавливаются приемочными тестами, либо при сдаче работ заказчику.
30. starik-2005 3301 17.07.18 16:11 Сейчас в теме
(29)
Остальные ошибки, как правило, проще отлавливаются приемочными тестами, либо при сдаче работ заказчику.
Не совсем так. В ходе исследований, на которые ссылается Макконнелл, выяснилось, что тесты обычно выявляют не более 30% ошибок, при этом ревью кода выявляет до 70%, что сопоставимо с парным программированием. В тестировании пользователями бета-версий выявляется до 97% ошибок, остальные 3% ошибок могут достаточно долго жить в проекте и не быть обнаруженными, что, понятное дело, влечет за собой риски от правильности результатов работы системы до уровня защищенности данных от атак хаккеров.
31. l1ike 17.07.18 16:58 Сейчас в теме
(30) Возможно, это конечно специфика именно конкретной предметной области и состояния конкретного проекта. На предыдущем месте работы я 2 года занимался именно ревью кода подрядчиков, и самый большой объем работы это работа вместо компилятора по контролю типов. На соответствие требованиям у нас проверяли аналитики, и ошибки когда считается не правильно были намного менее критичны чем когда на 40 заводах отгрузка встает из за того что где-то в общем модуле добавили Документ.Подразделение, а в каких-то документах подразделения нет.
15. boln 1044 13.07.18 20:45 Сейчас в теме
Всячески приветствую исследования автора в применении паттернов GoF к 1С. Сам имею такие наклонности :)

Но в данном кейсе, ИМХО, все же есть момент "паттерн ради паттерна". Выгода для программиста весьма туманна, согласен с комментариями. Все-таки паттерны изобретаются не ради самих паттернов.
admin; talych; Gesperid; Tavalik; CSiER; +5 Ответить
17. nicxxx 257 14.07.18 11:25 Сейчас в теме
Расскажите, кто-нибудь, автору про запятые. "т.е. из классической схемы убран агрегатор в квази ООП он кажется избыточным."
33. lazarenko 243 18.07.18 09:00 Сейчас в теме
19. nomadon 369 16.07.18 09:31 Сейчас в теме
Решение интересное, подойдет скорее для oscript, подбешивает писать в кавычках без автодополнения
20. CyberCerber 906 16.07.18 11:41 Сейчас в теме
Многих, наверное, пугает, вот эта страшная строка:
Курсор = Обработки.КурсорТаблицаЗначений.Создать().Конструктор(Таб).Имплементация("КурсорИнтерфейс");

А нельзя, может, и с потерей принципов, сделать такую реализацию?
Курсор = Курсоры.Создать(Таб);

Здесь Курсоры - это общий модуль. В метод Создать передаем нужную коллекцию, и, в зависимости от типа, возвращается та или иная обработка со своими реализациями методов работы с коллекциями.
Но у данной методики остается такой же недостаток, а именно отсутствие контекстной подсказки по методам. Решить это можно следующим образом:
Курсор = Обработки.КурсорИнтерфейс.Создать();
Курсор.Конструктор(Таб);

Тогда в переменной Курсор будет Объект.Обработка и все экспортные методы будут подсказываться.
Реализацию для каждого типа коллекций придется сделать не через наследование, а через агрегацию. Т.е. при вызове метода Конструктор в зависимости от типа переданной коллекции, в реквизит обработки, например, Реализация кладется та или иная обработка. И все методы обработки КурсорИнтерфейс будут выглядит так:
Функция Следующий() Экспорт
    Возврат Реализация.Следующий();
КонецФункции;

Т.е. обработка КурсорИнтерфейс будет что-то типа абстрактного класса с виртуальными методами.

P.S. Автор, хочу выразить благодарность за статьи по такой хорошей тематике и пожелать развития темы.
Eremkin; Артано; +2 Ответить
22. brr 184 16.07.18 12:02 Сейчас в теме
(20)Хехе, паттерн фабрика
23. starik-2005 3301 16.07.18 13:55 Сейчас в теме
25. pun4er 17.07.18 08:38 Сейчас в теме
Интересно, спасибо
35. babys 91 18.07.18 12:25 Сейчас в теме
Это 4 или 5, которые мне попадались, попытка загнать 1С в рамки "классического" ООП :)

Пока всё остаётся на уровне "мне было надо, я сделал кусок".
Для отправки сообщения требуется регистрация/авторизация