Объектно ориентированный взгляд на программирование в 1С

Данная статья изначально была размещена на Infostart. Получила много положительных отзывов.
Я уже несколько лет плотно работаю с 1С и поэтому знаком с сильными и слабыми сторонами этой системы. Одной из таких слабых сторон я считаю отсутствие полноценного ООП (а не кириллица, как считают многие программисты не работающие с 1С :))
В этой заметке я постарался пропагандировать объектный подход к программированию в 1С. Надеюсь удалось.

Первое что меня поразило при знакомстве с 1С – это отсутствие ООП. Никаких описание классов, наследований, закрытых методов. А ведь любой код должен быть логически структурирован. А классы это то, что позволят это сделать с наименьшими нервами.
Потом, поработав с 1С, понял, что объекты конечно есть. Одни предопределенные (вроде «Документы», «Регистр сведений»), а другие зависят от фантазии программиста («Обработки»). Конечно, нет полиморфизма, нет наследования, но объектную модель построить можно.

Только другая проблема: большинство 1С-программистов все пишут в «процедурном стиле». Язык сам по себе толкает создать общий модуль. Потом поместить в этот модуль кучу процедур для обработки данных и поддерживать все это «спагетти» из вызова процедур.

Похожая проблема наблюдается в Delphi. Там тоже программист может ничего не знать про ООП и писать приложения. Никакого разделения на классы, весь код зачастую помещалась в модуль формы. Но плюс Delphi в том, что с опытом все приходит т.к. в книжках объектная модель пропагандируется.

Рассмотрим 1С в объектно-ориентированном подходе. Предопределенные объекты (Документ, Регистр,..) содержат код 3-х типов:

  • «Модуль объекта» — Код отвечает за конкретный экземпляр объекта, а вернее обработку данных этого объекта.
  • «Модуль формы» — Код отвечает за обработку действий пользователя.
  • «Модуль менеджера» — Код отвечает за операции над определенным типом объекта, без привязки к конкретному экземпляру. В обычных языках это зовется «статические методы» 

Все процедуры и функции в этих модулях, можно воспринимать как методы класса. Область видимости процедур или функция регламентируется  ключевым словом «Экспорт» (здравствуй инкапсуляция). Правда, реквизиты нельзя сделать закрытыми, но это обходиться созданием глобальных переменных в самом модуле.

А существование «модуля формы» — это вообще фишка 1С, которой можно гордится. Этот модуль позволяет отделить код отвечающий за обработку действий пользователя и код который обрабатывает данные (Не дать не взять MVC).

Только проблема в том, что большинство разработчиков в модуль формы «суют» код отвечающий за общую логику работы с данными. Сам грешен. По-моему, разработчикам платформы 1С не мешает в «модуль формы»  добавить быстрый вызов «модуля объекта» (например через контекстное меню).

Теперь про объекты созданные самим программистом. На infostart встречал различные статьи о эмуляции объектно ориентированной модели. Но согласитесь, манипуляция  со  структурами для хранения данных – занятие муторное и не интуитивное. Я считаю, что лучшее решение, это воспринимать «обработки»  как описание собственных классов.

Наглядный пример. В «Списке значений» мне не нравится диалог, вызываемый методом «ОтметитьЭлементы». Не хватает кнопок, которые выделяли (или снимали выделение) со всех пунктов. И вот обработка СписокЗначенийРас как раз и дает такой диалог. Добавляем обработку в конфигуратор, а потом вызываем:

СписокЗначенийРас = Обработки.СписокЗначенийРас.Создать();
СписокЗначенийРас.Добавить("Пример1");
СписокЗначенийРас.Добавить("Пример2");
Если
СписокЗначенийРас.ОтметитьЭлементы() тогда
   
СписокЗначенийРас.Данные.ОтметитьЭлементы(); // а это стандартный диалог
КонецЕсли;

К сожалению наследования в 1С нет. Поэтому методы и свойства которые есть у СпискаЗначений  надо либо дублировать в обработке или обращаться к реквизиту который хранит оригинальный список значений (в моем случае это  СписокЗначенийРас.Данные)

Теперь переходим в конфигуратор. Находим обработку  СписокЗначенийРас и вызвав на нем контекстное меню, переходим в «модуль менеджера». Добавляем следующую функцию.

// Устанавливает или снимает (интерактивно) пометки у элементов списка значений.
// Заголовок - Заголовок окна диалога
// РабочиеДанные - список значений
Функция ОтметитьЭлементы(Заголовок=Неопределено, РабочиеДанные) Экспорт
   
Результат = Ложь;

    ФормаОЭ = ПолучитьФорму("ФормаОтметитьЭлементы");
   
ФормаОЭ.ПрочитатьДанные(РабочиеДанные);
   
ФормаОЭ.ЧитатьДанныеПриОткрытие = Ложь;
    Если
Заголовок <> Неопределено тогда
       
ФормаОЭ.Заголовок = Заголовок;
    КонецЕсли;

    РезультатФормы = ФормаОЭ.ОткрытьМодально();
   
Результат = (РезультатФормы = КодВозвратаДиалога.ОК);

    Возврат Результат;
КонецФункции

Теперь мы можем вызвать диалог еще проще.

сзДанные = Новый СписокЗначений;
сзДанные.Добавить("Пример_1");
сзДанные.Добавить("Пример_2");
Обработки.СписокЗначенийРас.ОтметитьЭлементы("Заголовок",сзДанные);

Чем не статический класс?
В подходе использования обработок как классов есть несколько недостатков.

  • Нет наследования. Хочется возможности указывать родителем хотя бы простейшие типы (СписокЗначений, ТаблицаЗначений, Дата, Строка…)
  • Класс-обработка показывается в общем списке обработок. Хотелось бы отдельный тип объектов.

На этом пока все. Надеюсь, заметка позволила вам разглядеть в 1С зачатки ООП 🙂

Объектно ориентированный взгляд на программирование в 1С: 2 комментария

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *