Имя: Пароль:
1C
 
Мой гений дарит вам ООП для 1С 8.0
, ,
0 Гений_ОдинЭса
 
04.11.04
09:22
К великому нашему прискорбию в 1С 8.0 не включено объектно-ориентированное программирование. Не будем обсуждать в данной статье почему разработчики решили обойтись без него.

В семерке тоже не было ООП. Некоторые умельцы реализовывали ООП с помощью внешних обработок. Мы пойдем другим путем – документированным.

Как говорится, если нельзя, но очень хочется, то можно.
Вы увидите, что основная парадигма ООП реализуется штатными средствами 1С 8.0.

---------------------------
Что такое объект в понятиях ООП?

Объект состоит из свойств и методов.
Объект может наследовать методы и свойства от другого объекта – предка.

---------------------------
Реализация в 1С 8.0

Для моделирования свойств объектов прекрасно подойдет объект типа «Структура», где можно хранить любые свойства любого типа.

Для реализации методов объектов будем использовать общие модули, по одному на каждый объект. В этих модулях будем описывать методы объекта в виде функций с именами ТипОбъекта_ИмяМетода. Хотелось бы конечно писать просто Об.ИмяМетода(Параметры), но придется писать примерно вот так: Метод(Об, ИмяМетода, Параметры).

Для передачи параметров опять же будем использовать только один параметр типа структура, который может содержать в себе любое количество параметров. К сожалению 1С не поддерживает вызов процедур с произвольным количеством и порядком вызова параметров.

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

Если метод не найден у объекта, он ищется у предка. Тип предка определяется через вызов у объекта метода Предок, если метод определен.

Если вызываемый метод не определен, система ничего не делает.

В методе можно вызвать метод предка, примерно так Предок(Об, ИмяМетода, Параметры).
Свойства можно назначать непосредственно, но для обеспечения контроля над свойствами лучше использовать функции Установить(Об, Свойство, Зн) и Получить(Об, Свойство).

Можно написать перехватчики событий установки-чтения свойств. Они носят имя ТипОбъекта_Установить и ТипОбъекта_Получить. Если ТипОбъекта_Установить возвращает истину, то свойство устанавливается, если ложь, то нет (этот обработчик может уже установить значения свойства и повторно его ставить не надо или запретить изменение свойства).

Конструктор объекта описывается в функции ТипОбъекта_Создать.

Деструктор объекта описывается в функции ТипОбъекта_Удалить. К сожалению, все вызовы деструкторов нужно вызывать явно, т.к. в 1С 8.0 нельзя отследить момент удаления локальной переменной.


Таким образом для реализации ООП достаточно 6 функций:
Создать
Метод
Предок
Установить
Получить
Удалить

---------------------------
Пример обработки.

Невероятно, но факт.

В принципе, объекты 1С 8.0 (документы, справочники и т.п.) можно рассматривать уже как готовые объекты. Действительно, у них можно получить тип. Кроме того, они обладают набором свойств. Таким образом, можно унифицировать работу с объектами через вышеуказанные шесть методов.

И если завтра вместо документа вы решите использовать справочник возможно в коде ничего не придется менять.


---------------------------
Резюме.

Как я показал, ООП в 1С 8.0 можно реализовать легко и красиво, добавив только  6 функций.

Зачем это нужно?

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

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

И все же, если в очередном релизе появится метод ВыполнитьФункцию(Имя Функции, Параметры), все ограничения по скорости будут сняты и ООП восторжествует. Видите, как для этого мало надо!

Кроме того, если использовать функцию Шаблон и вместо Структуры Список значений, то подобное ООП можно реализовать и в 7.7, правда вся реализация методов должна быть в одном глобальном модуле (в семерке нельзя реализовать несколько модулей).

Ну конечно бы хотелось, чтобы для всех 6 методов были введены операторы, но это уже от лукавого. Аминь!

---------------------------
Приложение.
Здесь я порекомендую разработчикам 1С 8.0 операторы для функций.

Создать = СоздатьОбъект ТипОбъекта
Метод = Об.Метод(Параметры)
Предок = Об::Метод(Параметры)
Установить = Об.Свойство=Зн;
Получить = Об.Свойство=Получить;
Удалить = УдалитьОбъект Об.

---------------------------
//Реализация объекта 1
Функция Объект1_Создать(Прм="")
КонецФункции


Функция Объект1_Печать(Я, Прм="")
   Сообщить("Я объект 1");
   Возврат 1;
КонецФункции


Функция Объект1_Известить(Я, Прм="")
   Сообщить(Получить(Я, "Информация"));
   Возврат 1;
КонецФункции

---------------------------
//Реализация объекта 2
Функция Объект2_Создать(Прм="")
КонецФункции

Функция Объект2_Предок(Я, Прм="")
   Возврат "Объект1";
КонецФункции

Функция Объект2_Известить(Я, Прм="")
   Сообщить("1С 8.0 - объектно-ориентированная среда!!! "+Прм);
КонецФункции

---------------------------
//Реализация объекта 3
Функция Объект3_Создать(Прм="")
КонецФункции

Функция Объект3_Предок(Я, Прм="")
   Возврат "Объект2";
КонецФункции

Функция Объект3_Печать(Я, Прм="")
   Сообщить("Я объект 3");
   Предок(Я, "Известить", "Верите?");
   Возврат 3;
КонецФункции


---------------------------
//// ФУНКЦИИ, РЕАЛИЗУЮЩИЕ ООП В 1С 8.0 /////
---------------------------

//Вызывает функцию, определенную в предке
Функция Предок(Об, Метод, Прм="", Сработал=ложь)
   Перем Результат, Тип, Предок;
   
   //Получаем тип объекта
   Тип=Об.Тип;

   Сработал=истина;
   Попытка
       Предок=Вычислить(Тип+"_Предок(Об, Прм)");        
       Попытка
           Результат=Вычислить(Предок+"_"+Метод+"(Об, Прм)");        
           Возврат Результат;
       Исключение
       КонецПопытки;
   Исключение
   КонецПопытки;
   Сработал=ложь;
   Возврат Неопределено;
КонецФункции

---------------------------
Функция Метод(Об, Метод, Прм="", Сработал=ложь)
   Перем Тип;
   
   Сработал=истина;
   
   //Получаем тип объекта
   Тип=Об.Тип;
   
   //Сначала пробуем просто вызвать метод самого объекта
   Попытка
       Возврат Вычислить(Тип+"_"+Метод+"(Об, Прм)");        
   Исключение
   КонецПопытки;
   
   Сработал=ложь;
   //Затем пробуем вызвать метод у предка объекта
   Возврат Предок(Об, Метод, Прм);
КонецФункции

---------------------------
//Создает объект
Функция Создать(Тип, Прм="")
   Об=Новый Структура;
   Об.Вставить("Тип",Тип);
   Метод(Об, "Создать", Прм);
   Возврат Об;
КонецФункции

---------------------------
Функция Установить(Об, Свойство, Зн)
   Перем Сработал, Рез;
   Прм=Новый Структура;
   Прм.Вставить("Свойство", Свойство);
   Прм.Вставить("Значение", Зн);
   Рез=Метод(Об, "Установить", Прм, Сработал);
   Если (Не Сработал) ИЛИ (Рез=Истина) Тогда
       Об.Вставить(Свойство, Зн);
   КонецЕсли;
   Возврат Зн;
КонецФункции

---------------------------
Функция Получить(Об, Свойство)
   Перем Сработал, Зн;
   Прм=Новый Структура;
   Прм.Вставить("Свойство", Свойство);
   Зн=Метод(Об, "Получить", Прм, Сработал);
   Если Не Сработал Тогда
       Если Не Об.Свойство(Свойство, Зн) Тогда
           Зн=Неопределено;
       КонецЕсли;
   КонецЕсли;
   Возврат Зн;
КонецФункции

---------------------------
Процедура Сформировать(Элемент)
   // Вставить содержимое обработчика.
   Об1=Создать("Объект1");
   Об2=Создать("Объект2");
   Об3=Создать("Объект3");
   Рез1=Метод(Об1, "Печать");
   Рез2=Метод(Об2, "Печать");
   Рез3=Метод(Об3, "Печать");
   Сообщить("Результаты: "+Рез1+" "+Рез2+" "+Рез3);
   Сообщить("Сначала информации нет:"+Получить(Об1, "Информация"));
   Установить(Об1, "Информация", "Я храню некую информацию");
   Сообщить("Потом мы ее устанавливаем:"+Получить(Об1, "Информация"));
КонецПроцедуры
---------------------------

Обработку можно скачать отсюда:
http://1c.proclub.ru/modules/mydownloads/personal.php?cid=120&lid=4252
1 borland, майкрософт
 
04.11.04
09:25
и Строустрап

мы отдыхаем...
2 Vozhd
 
04.11.04
10:18
(0) А не путаете ли Вы ООП с компонентным программированием?
3 vasinok
 
04.11.04
10:33
(0) Насколько я знаю, существуют как минимум две модели ООЯ: первая на основе прототипов, вторая на основе классов. Если я правильно понял, то язык 1С относится к первой. Прошу поправить, если я ошибаюсь.
4 Строустрап
 
04.11.04
12:38
3
ООП - это судьба
2 + 2 = 3.9999999999999999999999999999999...