Содержание к диссертации
Введение
1 Методы разработки эволюционно-расширяемых программ 16
1.1 Разделение систем программирования по парадигмам 16
1.2 Анализ характеристик, определяющих разработку эволюционно расширяемых программ 21
1.3 Факторы, определяющие построение расширяемых программ 22
1.3.1 Модули с инициализирующими блоками 24
1.3.2 Пространства имен, размещаемые в нескольких единицах компиляции 27
1.3.3 Классы, содержащие конструкторы и деструкторы 27
1.3.4 Технология вертикального слоения 28
1.3.5 Наследование и виртуализация 29
1.3.6 Технология вспомогательных классов 30
1.3.7 Метапрограммирование 31
1.3.8 Аспект ориентированное программирование 32
1.3.9 Субъектно-ориентированное программирование 33
1.3.10 Связывание через интерфейсы 34
1.4 Моделирование методов формирования процедурно-параметрических отношений 35
1.4.1 Алгоритмы, базирующиеся на объектно-ориентированной парадигме 36
1.4.2 Использование процедурного подхода для построения эволюционно расширяемых мультиметодов .. 37
1.4.3 Сравнение объектно-ориентированной и процедурно-параметрической реализаций полиморфизма 39
1.5 Перспективы развития инструментальных средств разработки эволюционно расширяемых программ 42
1.6 Выводы по главе 1 43
2 Методы организации программных объектов, поддерживающих процедурно-параметрическое программирование 45
2.1 Используемые понятия и определения 46
2.1.1 Данные обрабатываемые программой 46
2.1.2 Значения данных 47
2.1.3 Процедуры, используемые для обработки программных объектов 48
2.1.4 Вызовы процедур 50
2.2 Задача эволюционного расширения мультиметодов 51
2.3 Эволюционное расширение мультиметодов в различных парадигмах программирования 52
2.3.1 Расширение мультиметодов при процедурном подходе 53
2.3.2 Расширение мультиметодов при объектно-ориентированном подходе 54
2.3.3 Проблемы существующих подходов эволюционной разработки мультиметодов 56
2.4 Основные понятия процедурно-параметрического программирования 57
2.4.1 Организация параметрических обобщений 58
2.4.2 Организация обобщающих параметрических процедур 60
2.4.3 Организация обработчиков параметрических специализаций 61
2.4.4 Экземпляр параметрического обобщения 62
2.4.5 Вызовы параметрических процедур 63
2.5 Классификация механизмов параметрического обобщения 63
2.5.1 Способы построения параметрических обобщений 64
2.5.2 Методы включения специализаций в параметрическое обобщение 68
2.5.3 Методы конструирования обобщений 69
2.5.4 Способы построения параметрических отношений и их отображение на обобщающие и специализированные параметрические процедуры 73
2.5.5 Способы формирования тел обработчиков специализаций 76
2.5.6 Способы связывания комбинаций специализаций с конкретным обработчиком 77
2.5.7 Фазы формирования параметрических обобщений 77
2.6 Выводы по главе 2 80
3 Описание синтаксиса языка программирования с поддержкой процедурно-параметрического полиморфизма 82
3.1 Языковые конструкции, поддерживающие процедурно-параметрическое программирование 82
3.1.1 Организация параметрических обобщений 83
3.1.2 Указатели на параметрические обобщения и специализации 86
3.1.3 Обобщенные переменные 86
3.1.4 Обобщающие процедуры и обработчики специализаций 87
3.1.5 Вызовы обобщающих процедур 89
3.1.6 Оператор WITH 90
3.2 Организация трансляции процедурно-параметрических программ 91
3.3 Использование языка для решения задачи эволюционного расширения 94
3.3.1 Разработка основной части программы 94
3.3.2 Проявление полиморфизма в клиентском модуле 101
3.4 Выводы по главе 3 104
4 Инструментальная поддержка процедурно-параметрической парадигмы программирования 105
4.1 Оценка эффективности реализации поддержки процедурно-параметрической парадигмы программирования 105
4.2 Методы повышения эффективности реализации ППП 108
4.3 Инструменты процедурно-параметрического программирования 109
4.3.1 Транслятор сязыка 110
4.3.2 Компоновщик параметрических отношений 111
4.3.3 Сборщик проектов 113
4.3.4 Оболочка пользователя 115
4.3 Выводы по главе 4 117
Заключение 118
Список использованных источников 120
- Использование процедурного подхода для построения эволюционно расширяемых мультиметодов
- Эволюционное расширение мультиметодов в различных парадигмах программирования
- Обобщающие процедуры и обработчики специализаций
- Инструменты процедурно-параметрического программирования
Введение к работе
Повышение сложности программных систем приводит к необходимости применения более эффективных методов разработки программного обеспечения. Эффективность разработки определяется удобством сопровождения, возможностью безболезненного наращивания программного кода, возможностью повторного использования разрабатываемых программных объектов. В настоящее время наибольшее распространение получила объектно-ориентированная методология (ООМ), во многом соответствующая предъявляемым требованиям. Составной частью ООМ является объектно-ориентированное программирование (ООП). Развитие ООП практически полностью вытеснило процедурное программирование из областей, связанных с разработкой сложных программных систем, за счет возможностей обнаружения ряда ошибок на более ранних этапах построения программы. Это обусловлено расширенными возможностями статической проверки состояний объектов и их типов языками и инструментальными средствами, поддерживающими ООП [21, 79]. Поддержка расширенной работы с типами на уровне языковых и инструментальных средств явилась решающим фактором, приведшим к вытеснению процедурного программирования, несмотря на возможность моделирования объектной парадигмы средствами процедурных языков.
Тем не менее, практическое использование ОО подхода позволило выявить ряд недостатков [16, 55], в частности, сложности при реализации мультиметодов [55, 64]. Преодоление данных недостатков осуществляется путем моделирования при помощи языковых средств объектов, решающих проблемы, связанные с использованием объектно-ориентированных средств. В качестве примера подобного решения можно привести разработку
образцов проектирования [37]. Однако, использование моделирования вновь сдвигает процесс обнаружения ошибок на более поздние этапы.
Одним из возможных путей преодоления недостатков объектно-ориентированной методологии является применение процедурно-параметрической парадигмы программирования [54, 55, 57, 59, 60, 67]. Опираясь на процедурный подход, данная парадигма расширяет его механизмом, поддерживающим полиморфную обработку альтернативных данных без их явного описания в теле процедуры. Этот механизм похож на полиморфизм классов, используемый в ООП. Применение данного механизма обеспечивает как эволюционное расширение программ совместно с повторным использованием написанного ранее полиморфного кода [67], так и возможность использования старых процедурных подпрограмм путем их объединения в обобщенные процедуры, обрабатывающие полиморфные типы данных [70].
Использование программных объектов, поддерживающих процедурно-параметрическое программирование, позволяет расширить функциональные возможности существующих процедурных языков, сделать их более приспособленными для разработки больших программных систем. Процедурно-параметрическую парадигму можно использовать как в качестве альтернативы объектно-ориентированному подходу, так и совместно с ООП [55].
Полноценное использование возможностей процедурно-
параметрического полиморфизма (111111) возможно только при наличии поддержки ППП на уровне языка программирования [56, 58], что позволяет организовать проверку корректности связей между программными объектами на ранних этапах построения программы.
Необходимость исследования возможностей процедурно-параметрической парадигмы обуславливает актуальность задачи создания
систем программирования, поддерживающих процедурно-параметрический полиморфизм. При создании нового языка появляется возможность оценки эффективности различных способов написания программ [91, 103, 104], как с позиций необходимости генерации эффективного исполняемого кода, так и удобства использования процедурно-параметрических языковых конструкций программистом.
Цель работы состоит в исследовании методов эволюционной разработки программ на основе процедурно-параметрической парадигмы и разработке языковых конструкций, поддерживающих процедурно-параметрический полиморфизм.
Для достижения указанной цели в работе решаются следующие основные задачи:
Проведение сравнительного анализа методов построения эволюционно расширяемых программ. Исследование парадигм, обеспечивающих поддержку множественного полиморфизма.
Исследование и сравнительный анализ методов программной реализации для различных способов поддержки процедурно-параметрического полиморфизма.
Разработка языковых конструкций, поддерживающих процедурно-параметрическую парадигму программирования. Рассмотрение возможности использования данных конструкций в существующих языках программирования.
Исследование возможностей применения разработанных языковых конструкций при создании эволюционно-расширяемых программ.
Методы исследования. В диссертационной работе использовались методы дискретной математики, теории алгоритмов, теории языков и формальных грамматик, теории разработки трансляторов. Для описания синтаксиса языка программирования использовались расширенные формы
Бэкуса-Наура. При разработке языка программирования применялись методы синтаксического анализа и компиляции, методы объектно-ориентированного и процедурно-параметрического программирования.
В работе получены следующие научные результаты:
Сделан вывод о перспективах использования процедурно-параметрической парадигмы программирования для реализации множественного полиморфизма на основании анализа методов эволюционной разработки программного обеспечения.
Предложена классификация методов поддержки параметрического полиморфизма, на основании которой проанализированы различные способы реализации программных объектов» поддерживающих процедурно-параметрическую парадигму программирования.
Разработаны языковые конструкции, поддерживающие различные способы реализации процедурно-параметрической парадигмы программирования.
Предложены методы программирования с использованием новых языковых конструкций, обеспечивающие разработку эволюционно расширяемых программ.
К практическим результатам работы следует отнести:
Проведенные автором исследования позволили создать инструментальные средства языковой поддержки процедурно-параметрической парадигмы программирования.
Данные инструментальные средства обеспечили проведение практических экспериментов и дополнительный анализ методов построения процедурно-параметрических программ.
Полученные научные и практические результаты использованы в учебном процессе по дисциплине «Технология программирования»
в Красноярском государственном техническом университете и Красноярском государственном университете. Достоверность и обоснованность результатов диссертации подтверждаются:
Исследованием современного состояния методологий программирования.
Исследованием существующих инструментальных средств поддержки различных парадигм программирования.
Опытом применения разработанного инструментария для написания программ в процедурно-параметрическом стиле.
Публикации и личный вклад в решение проблемы. По теме диссертации опубликовано 12 печатных работ, из которых 8 статей, 4 тезисов докладов.
Диссертация основана на теоретических, методологических и экспериментальных исследованиях, выполненных в лаборатории каф. НейроЭВМ КГТУ. Основные теоретические и практические результаты, изложенные в работе, получены либо непосредственно автором, либо с его участием. Автором разработана структура комплекса инструментальных средств, реализована поддержка основных методик процедурно-параметрического полиморфизма, проведены исследования возможных способов реализации ПП методологии, разработан комплекс программных средств для трансляции программ, написанных с применением исследуемых методик.
Апробация работы.
Основные положения диссертации докладывались и обсуждались на:
межвузовских научных конференциях студентов, аспирантов и молодых ученых, Красноярск (2000,2001);
межвузовской научной конференции, Красноярск (2002);
IV Всероссийской конференции молодых ученых по математическому моделированию и информационным технологиям, Красноярск (2003);
3-ей школе-семинаре «Распределенные и кластерные вычисления», Красноярск (2003).
международной конференции «Перспективы систем информатики» (рабочий семинар «Наукоемкое программное обеспечение»), Новосибирск, 2003;
конференции «Технологии Microsoft в информатике и программировании», Новосибирск (2004).
Структура диссертации.
Диссертация состоит из введения, 4 глав, заключения, списка литературы и двух приложений.
Во введении представлены цели и задачи исследования, раскрывается актуальность, новизна полученных результатов, практическая значимость. Приводится перечень вопросов, выносящихся на защиту.
В первой главе представлен обзор методов, используемых для
разработки эволюционно расширяемых программ. Рассмотрены следующие
подходы: модули с инициализирующими блоками; пространства имен,
размещаемые в нескольких единицах компиляции; технология вертикального
слоения; классы, содержащие конструкторы и деструкторы; наследование и
виртуализация; технология вспомогательных классов; шаблоны; аспектно-
ориентированное программирование; субъектно-ориентированное
программирование; связывание через интерфейсы.
Проведен анализ применения различных подходов для определения области использования методов эволюционного расширения. Показано, что механизмы эволюционного расширения применяются в широком диапазоне, обеспечивая формирование окончательного кода как на стадиях обработки
текста программы, так и во время ее выполнения. Выделяется связывание добавляемых фрагментов: до начала трансляции (этап препроцессорной обработки); во время трансляции; в ходе компоновки; в момент начальной загрузки программы; в процессе выполнения программы. Выделены подходы, обеспечивающие использование полиморфизма. При этом рассмотрена возможность эволюционного расширения ранее написанного кода. Отмечено, что процедурный стиль программирования, обеспечивающий самые простые и понятные методы реализации полиморфизма, не имеет инструментальной поддержки для эволюционного расширения этих отношений. Объектно-ориентированный стиль обеспечивает поддержку для эволюционного расширения одинарного полиморфизма, но не позволяет расширять код, построенный на основе множественного полиморфизма (например, мультиметодов).
Выделяются условия применения эволюционного расширения мультиметодов, что позволяет конкретизировать задачу исследования, определить недостатки процедурного и объектно-ориентированного подходов при их использовании в рассмотренном контексте. Постановка задачи позволила сделать вывод об использовании дополнительных механизмов инструментальной поддержки эволюционного расширения мультиметодов.
Во второй главе проводится исследование методов организации программных объектов, поддерживающих процедурно-параметрический полиморфизм. Выделяются основные понятия, характеризующие процедурно-параметрическую парадигму программирования.
Предлагается классификация методов поддержки параметрического полиморфизма, позволяющая оценить возможные способы реализации и связанные с этим затраты на обработку данных. Существует ряд параметров,
специфика организации которых ведет к различным способам реализации процедурно-параметрического механизма, К ним относятся:
способы построения параметрических обобщений;
методы включения специализаций в параметрическое обобщение;
методы конструирования обобщений;
способы построения параметрических отношений и их отображение на обобщающие и специализированные параметрические процедуры;
способы формирования тел обработчиков специализаций и тел обобщающих процедур;
способы связывания комбинаций специализаций с конкретным обработчиком;
фазы формирования параметрических обобщений.
Приводятся подробные характеристики каждого из представленных критериев классификации. Помимо этого дается общая оценка различных способов реализации программных объектов, поддерживающих процедурно-параметрическое программирование.
В третьей главе предлагаются языковые конструкции, расширяющие традиционный процедурный язык программирования средствами поддержки процедурно-параметрической парадигмы. Предлагаемый в результате язык назван 02М и является расширением языка программирования Оберон-2.
В конце главы приведены примеры, показывающие возможности языка при эволюционной разработке программы, использующей мультиметоды. Показано, что даже в случае хаотичного добавления новых типов данных и процедур, язык обеспечивает эффективную поддержку эволюционного расширения программы.
В четвертой главе описаны реализованные инструментальные средства обеспечивающие инструментальную поддержку процедурно-
параметрического программирования. К ним относятся: компилятор с языка программирования 02М; компоновщик параметрических отношений; утилита генерации файла проекта, используемого для сборки исполняемого модуля из файлов, полученных после трансляции и компоновки параметрических отношений; оболочка пользователя.
Приложение А содержит описание синтаксиса процедурно-параметрического языка программирования 02М.
В Приложении В приводятся исходные тексты программ, рассмотренных в диссертации.
В заключении перечислены полученные результаты, обоснована перспектива их применения и развития, сформулированы выводы по диссертационной работе.
Работа содержит 131 страницу текста, 9 рисунков и 2 таблицы. Список литературы включает 113 наименований.
Использование процедурного подхода для построения эволюционно расширяемых мультиметодов
Однако, в связи с тем, что использование мультиметодов постоянно встречалось на практике, стали разрабатываться алгоритмические приемы, обеспечивающие приемлемую поддержку. Методом, обеспечивающим быстрый вызов обработчика специализации, зависящего от нескольких аргументов (по сравнению с использованием вложенных проверок типов объектов), является множественная диспетчеризация [112]. Однако ее непосредственное использование не поддерживает эволюционного расширения программы. В связи с этим многие работы посвящены эволюционному расширению мультиметодов. Следует отметить, что в большинстве случаев используется смешанный подход к программированию, опирающийся как на объектную, так и процедурную парадигмы.
Для исправления недостатков диспетчеризации, присущих объектно-ориентированной реализации алгоритма в работе [78] предложен метод, сочетающий ассоциативные массивы, проверку типов во время выполнения и внешние процедуры. Таким способом делается попытка смоделировать механизмы, имитирующие таблицу виртуальных функций объектно-ориентированных систем. Однако использование ассоциативных массивов вместо прямого доступа замедляет обработку данных. Помимо этого остаются проблемы, связанные с добавлением новых методов и мультиметодов в уже выстроенную иерархию классов. В работе [21] предложена модифицированная схема, базирующаяся на использовании библиотеки шаблонов. Автоматическая генерация методов классов обеспечивает гибкое формирование их описания. Реализации специализаций может осуществляться в независимых файлах. Набольшая модификация связано только с изменением списка регистрируемых классов, добавляемых в систему. Однако данный метод обладает аналогичными, по сравнению с предыдущим, недостатками, связанными с проблематичным добавлением новых методов.
Для повышения гибкости и ускорения вычислений в работе [63] предлагается использовать ранжирование классов. Эволюционное добавление новых классов осуществляется по пирамидальной схеме, когда каждый новый класс использует информацию о своих предшественниках и ничего не знает о классах, добавляемых позднее. Предложены три варианта метода, базирующиеся как на проверке типов во время выполнения, так и на использовании только диспетчеризации. Несмотря на ускорение вычислений, использование подобных приемов эффективно только при заданном порядке добавления классов. Поэтому, вряд ли данный прием можно использовать в более разнообразных ситуациях.
Большинство из рассмотренных подходов базировались на совместном использовании нескольких парадигм программирование. В работе [100] предлагается динамическое наращивание мультиметодов в рамках обьектно-ориентированного подхода. Несмотря на достаточную гибкость предложенный подход, базирующийся на ассоциативных методах доступа, ведет к серьезному снижению скорости вычислений.
Несмотря на то, что ОО подход может поддерживать эволюционную разработку программ, следует отметить, что используемые при этом приемы ведут к появлению жесткой связи между добавляемыми классами и к увеличению размера интерфейсов у потомков. Сохраняется также основной недостаток ОО подхода: появление новых методов (и мультиметодов) изменяет всю иерархию уже созданных классов. Процедурная реализация в целом выглядит более естественной. Вызов мультиметода по форме и содержанию эквивалентен вызову любой другой процедуры.
Специфика эволюционного расширения мультиметодов при процедурном подходе проявляется в независимости данных от функций. Это позволяет использовать волнообразное расширение методов, связанное с добавлением новых типов данных [64]. В работе [64] предложено два метода. Первый из них использует индексацию в статическом многомерном массиве, формируемом после получения информации обо всех аргументах. Он является достаточно простым и может использоваться для связывания эволюционно расширяемых программных объектов на этапе статической компоновки. Невозможность использования данного подхода для реализации динамического связывания обуславливается наличием ранжирования типов данных, при котором ранги аргументов используются в качестве индексов многомерной таблицы, обеспечивающей выбор нужного обработчика специализации
Вместе с тем, динамическое связывание программных объектов позволяет окончательно выстроить параметрические отношения на этапе выполнения программы. В этой же работе предложен алгоритм, основанный на автоматическом формировании ранга объекта, используемого в качестве полиморфного аргумента мультиметода.
Реализация и отладка рассмотренных методов, позволила определить подходы, используемые для построения необходимых параметрических отношений в инструментальных средствах, поддерживающих процедурно-параметрическое программирование.
Эволюционное расширение мультиметодов в различных парадигмах программирования
Системы программирования, поддерживающие процедурный подход разрабатывались в тот период, когда речь о необходимости эволюционного наращивания кода не стояла. При проектировании в основном использовалась каскадная модель жизненного цикла [32,48],
Разработка обобщений чаще всего осуществляется с применением вариантных структур данных, например, вариантных записей в языках программирования Паскаль [33] или Модула-2 [34, 35]. В языках программирования С [46], Ада [47] используются объединения. Применение этих конструкций ведет к централизации обобщения и необходимости его изменения при добавлении каждой новой специализации.
Обобщающие процедуры строятся на основе условных операторов и переключателей, осуществляющих анализ комбинаций признаков всех обобщений, являющихся аргументами. Обработка обобщений при этом рассматривается как процесс построения кода, эквивалентного используемым вариантным типам данных [33, 35]. Каждой комбинации соответствует свой обработчик специализации. Возможен также вариант, осуществляющий обработку по умолчанию. Для оптимизации разбора признаков чаще всего используется их иерархический анализ на основе вложенных операторов селекции. Как и в случае с обобщением, полученный фрагмент кода является централизованным и не допускает эволюционного расширения. Добавление новой специализации связано с изменением уже написанного кода, анализирующего комбинации специализаций [55]. Ситуация характерна как для мультиметода, так и для монометода, для которых при процедурном подходе отсутствует разница по организации инструментальной поддержки.
Не существует принципиальных трудностей в реализации эволюционно расширяемых обобщений. В ряде языков программирования, например, С, для этого можно использовать указатели на структуры, задающие специализации, состоящие из признака и используемого понятия [55, 56]. В языке программирования Оберон [20] для построения подобных специализаций используется механизм наследования. Подобным же образом можно использовать и структуры языка программирования C++ [90]. Однако и в этом случае остаются проблемы, связанные с эволюционным расширением обобщающих процедур.
Вместе с тем, следует отметить, что процедурный подход весьма успешно справляется с добавлением новых обобщающих процедур, что обусловлено их независимостью от данных. Поэтому, эволюционное расширение программы, связанное с добавлением новой функциональности, не вызывает каких-либо проблем.
Имеющиеся ограничения обуславливаются историческими причинами и практически не позволяют использовать процедурные языки для эволюционного программирования. Дальнейшее падение интереса к этому стилю, связанное с ростом популярности объектно-ориентированного подхода, не позволило создать на базе них системы программирования, обеспечивающие необходимую инструментальную поддержку. ООП предоставляет инструментальную поддержку, которая, в ряде случаев, обеспечивает гибкое эволюционное наращивание кода. Для построения обобщений используется механизм наследования. В качестве самого обобщения при этом выступает базовый класс. Производные классы используются в качестве специализаций, признаками которых являются типы классов. Инструментальная поддержка механизма виртуальных функций обеспечивает эволюционное построение обобщающих процедур для монометода, т.е., когда сам класс играет роль полиморфного аргумента. В этом случае любой производный класс, сопоставляемый со ссылкой или указателем на базовый класс, может вызвать свой обработчик специализации. Добавление новой специализации позволяет порождать связанные с ней методы, которые, при наличии соответствующей инструментальной поддержки, описываются как в самом классе-специализации [81, 90], так и вне его, например, в виде связных процедур [15]. Вместе с тем, следует отметить, что использование объектно-ориентированного подхода не обеспечивает эволюционного расширения мультиметодов. Применяемая в этом случае диспетчеризация [78] ведет к постоянной модификации всех классов, включая и базовый класс, в случае добавлении новых специализаций. Проблемы, обуславливаемые необходимостью изменять интерфейс класса, возникают и при добавлении новых обобщающих процедур. Они возникают даже в тех языках, где процедуры отделены от данных [15], что во многом обусловлено методом поддержки полиморфизма с использованием таблиц виртуальных функций [91].
Попытки преодоления указанных проблем решаются в ООП с помощью образцов (паттернов) проектирования [2, 5, 37], обобщающих типичные ситуации и вырабатывающие конкретные решения для преодоления возникающих проблем. Зачастую подобные ситуации являются частными случаями мультиметодов, позволяющими, при временной фиксации ряда обобщаемых параметров, свести разработку программы к последовательному использованию монометодов. Применение такого подхода поставило во главу процесса проектирования использование эволюционных приемов написания программ вместо непосредственной разработки модели предметной области. В начале рекомендуется подобрать необходимые образцы проектирования, а лишь затем приступать к окончательной разработке структуры программы. Наблюдается даже появление специалистов по разработке образцов [37].
Для эволюционного расширения мультиметодов можно также использовать специальные приемы. В работе [78] предлагается имитация таблиц виртуальных функций с использованием ассоциативных массивов. Однако при этом приходится использовать процедурные приемы программирования. Ряд схем, связанных с пирамидальным добавлением новых специализаций, представлен в работе [63]. В ней также предлагается решение, использующее только таблицу виртуальных функций. Однако предложенные варианты накладывают ограничения на порядок разработки и ранжирования специализаций, что ведет к потере гибкости и ограничивает повторное использование. Во всех этих подходах практически не решена задача безболезненного добавления новых процедур классов.
Обобщающие процедуры и обработчики специализаций
Применение процедурно-параметрического полиморфизма (как и любого метода высокоуровневого программирования) приводит к снижению эффективности программ, использующих данный метод, связанному с необходимостью выполнения специального кода, отвечающего за поддержку полиморфизма программных объектов. Это выражается в уменьшении быстродействия и увеличении объема исполняемого кода, получаемого в результате трансляции процедурно-параметрических программ.
В случае языка 02М наиболее критичным ко времени исполнения является вызов обработчика параметрической специализации через обобщающую процедуру, т.к. в этом случае необходимо осуществить поиск в таблице обработчиков обобщающей процедуры. В общем случае таблица обработчиков является многомерной.
В таблице 4.1 приведены основные способы реализации таблицы обработчиков параметрических специализаций. В колонке "ООП минусами отмечены методы реализации, неприменимые при классическом объектно-ориентированном подходе.
В текущей версии транслятора 02М выбор обработчика параметрической специализации осуществляется генерацией одноуровневого оператора выбора (switch), проверяющего требуемые сочетания типов параметров для каждого обработчика. Данный способ выбран благодаря простоте в реализации. Точные временные характеристики не указывались, т.к. на них оказывают значительное влияние архитектура машины, настройки и версии компилятора. Результаты различались на сопоставимых по скорости процессорах Athlon ХР 1500+ с частотой 1,3 ГГц и Pentium 4 с частотой 1,5 ГГц., а также при использовании различных настроек оптимизации компилятора C++ (использовался компилятор Microsoft Visual C++ 6.0).
При сравнении скорости поиска обработчика в случае одного обобщающего параметра (что соответствует поиску в таблице виртуальных функций) со скоростью работы объектно-ориентированной программы, были получены практически одинаковые результаты.
Повышение быстродействия исполняемого кода может достигаться реализацией нескольких альтернативных механизмов выбора обработчика параметрической специализации на основании комбинации типов входных параметров обобщающей процедуры. Например, в случае большого количества входных параметров обобщенной процедуры и/или большого количества типов, включаемых в обобщение, использование таблицы в виде разреженного списка указателей приведет к увеличению быстродействия при малом количестве обработчиков (см. таблицу 4.1). Выбор используемого механизма может задаваться программистом в настройках проекта, или выбираться транслятором на основании результатов анализа программы. Также повышения быстродействия можно добиться путем включения механизма выбора обработчика непосредственно в точку вызова обобщающей процедуры [77, 78, 91]. Снижение объема исполняемого кода может достигаться вынесением механизма выбора обработчика в отдельную подпрограмму, обращение к данной подпрограмме помещается в точку вызова обобщающей процедуры. Уменьшение количества различных механизмов выбора обработчика в рамках одного проекта также приведет к снижению объема исполняемого кода. Следует отметить, что параметризация процедурно-параметрических подпрограмм несколькими типами не обязательно приводит к дублированию кода, как при использовании шаблонных классов [79, 90]. Возможно применение различных стратегий трансляции процедурно-параметрической программы, направленных на повышение быстродействия, снижение объема исполняемого кода или баланс между быстродействием и размерами программы. Разработка транслятора обеспечила практическую поддержку экспериментов, связанных с исследованием процедурно-параметрического полиморфизма. Полученные результаты показали возможность эволюционного расширения программ без существенных потерь в эффективности. 4.3 Инструменты процедурно-параметрического программирован ия Для проведения практических экспериментов с методами процедурно-параметрического программирования разработаны необходимые инструментальные средства [66, 70]. В их состав вошли: - транслятор с языка программирования 02М; - компоновщик параметрических отношений; - сборщик проектов; - оболочка пользователя; Использование данных инструментов повысило эффективность процесса разработки процедурно-параметрических программ. Транслятор предназначен для компиляции программ на языке 02М в объектный код. В качестве объектного кода был выбран язык ANSI C++, что позволило в качестве генератора кода использовать любой компилятор ANSI C++. Подобная схема является общепринятой [91] при создании новых языков, т.к. позволяет упростить разработку транслятора.
Кроме объектного кода, транслятор формирует файл ( .2ml), содержащий информацию о процедурно-параметрических программных объектах, таких как обобщения, обобщающие процедуры, обработчики параметрических специализаций, использованных в обрабатываемом модуле на языке 02М. В дальнейшем данная информация используется компоновщиком параметрических отношений для генерации дополнительных связей между программными объектами, поддерживающими параметрический полиморфизм. В качестве формата для хранения полученной информации используется XML [88] благодаря его гибкости и универсальности. Подобная схема позволяет сделать компоновщик параметрических специализаций мало зависимым от изменений, вносимых в транслятор, что является немаловажным, так как язык и система в целом находятся в стадии развития.
Также транслятором формируется файл описания интерфейса обработанного модуля ( .dfh), в котором описываются все типы и переменные, экспортируемые модулем. Данная информация необходима для организации раздельной компиляции программ на языке 02М.
Инструменты процедурно-параметрического программирования
Утилита Маке2М формирует скрипт для запуска внешнего компилятора C++ с передачей ему всех параметров, необходимых для генерации исполняемого модуля. Подобный механизм введен для отвязки транслятора 02М от особенностей конкретных компиляторов C++.
В текущей версии Маке2М создает скрипты в формате makefile для Microsoft Visual C++ 6.0 и GNU C++. Скрипт может быть использован для генерации как консольного приложения, так и для генерации приложения, использующего графический интерфейс Windows. Вид исполняемого модуля определяется тем, какой из модулей (Console, Win и т.д.) был импортирован в главном файле проекта. В текущей версии поддерживается генерация консольного приложения (совместимо с операционными системами семейств Linux и Windows), консольного приложения Windows (поддерживаются возможности работы с устройствами ввода-вывода, предоставляемые консолью Windows), приложения, использующего графический интерфейс Windows (в настоящий момент находится в состоянии отладки). Схема работы сборщика проектов показана на рисунке 4.6.
Оболочка пользователя транслятора 02М (рис. 4.7) разработана для упрощения работы с транслятором и проектами 02М. Использование Рго2М не является обязательным, т.к. транслятор 02М является консольным приложением и может быть запущен через командную строку.
Графический пользовательский интерфейс выполнен в виде приложения Рго2М, предназначенного для работы в операционных системах Windows 95/98/NT/2000/XP. Приложение Рго2М обеспечивает функции настойки и компиляции проектов 02М. Поддерживается работа с проектами 02М ( .рго), запуск компилятора 02М, компоновщика параметрических отношений Link2M, утилиты Маке2М, внешнего компилятора C++ и запуск полученного в результате компиляции исполняемого файла на выполнение. В качестве внешнего компилятора могут использоваться Microsoft Visual C++ 6.0, MinGW 2.95 (использование данных компиляторов поддерживается по умолчанию) или другой ANSI C++ совместимый компилятор (требуются дополнительные настройки). 1. Для проведения практических экспериментов с множественным полиморфизмом разработан язык программирования 02М, который поддерживает процедурно параметрическое программирование, позволяющее гибко наращивать программу в ходе сопровождения, 2. Реализация параметрической парадигмы в языке, поддерживающем объектно-ориентированный стиль, позволила проводить исследования и сравнительный анализ различных методов эволюционного расширения программ. 3. Разработка дополнительных инструментальных средства и утилит обеспечила повышение эффективности разработки программ. 4. Показана эффективность поддержки множественного и одиночного полиморфизма в системах процедурно-параметрического программирования. Получены следующие научные и практические результаты работы: 1. Проведен анализ методов эволюционной разработки программного обеспечения, на основании которого сделан вывод о перспективности использования процедурно-параметрической парадигмы программирования для реализации множественного полиморфизма и необходимости её инструментальной поддержки. 2. Предложена классификация методов процедурно-параметрического программирования, опирающаяся на различные способы реализации программных объектов, поддерживающих процедурно-параметрический полиморфизм. Проведен анализ методов реализации программных объектов обеспечивающих построение процедурно-параметрических эволюционно расширяемых программ. 3. Разработаны языковые конструкции, поддерживающие процедурно-параметрическую парадигму программирования. На основе проведенного анализа сделан вывод о возможности использования данных конструкций для разработки эволюционно наращиваемых программ. 4. Разработаны инструментальные программные средства, обеспечивающие поддержку процесса создания процедурно-параметрических программ и включающие: - компилятор, обеспечивающий трансляцию исходных текстов процедурно-параметрических программ в объектный код; - компоновщик параметрических отношений, обеспечивающий организацию дополнительных связей программных объектов, поддерживающих процедурно-параметрический полиморфизм; - сборщик проектов, обеспечивающий генерацию скрипта для обработки объектного кода и сборки исполняемого файла; - оболочку пользователя, предназначенную для упрощения работы с инструментальными средствами. 5. Разработанные языковые и инструментальные средства позволили провести апробацию предложенных методов эволюционного программирования.