Содержание к диссертации
Введение
CLASS Глава 1. Автоматизированный перевод в задаче реинжиниринга программного обеспечения CLASS 12
1.1 Сопровождение программного обеспечения 12
1.1.1 Сопровождение в жизненном цикле ПО 12
1.1.2 Виды деятельности при сопровождении программного обеспечения 15
1.1.3 Проблемы старых систем в процессе сопровождения 16
1.2 Реинжиниринг как решение проблем сопровождения старых систем 18
1.2.1 Определения реинжиниринга 18
1.2.2 Применимость и риски реинжиниринга 20
1.2.3 Эффективность применения реинжиниринга 22
1.2.4 Альтернативы реинжинирингу 24
1.3 Автоматизированный перевод в процессе реинжиниринга 25
1.3.1 Применение и задачи перевода 25
1.3.2 Сравнение автоматизированного перевода и компиляции 26
1.3.3 Подходы к автоматизированному переводу 28
1.3.4 Перевод уровня реализации 30
1.3.5 Перевод уровня абстракций 32
1.3.6 Проблемы автоматизированного перевода 33
1.3.7 Существующие подходы к преодолению проблем перевода 35
1.4 Межъязыковые преобразования 35
1.5 Реструктуризация 37
1.6 Использование объектно-ориентированной технологии 39
1.6.1 Создание новой объектно-ориентированной модели 41
1.6.2 Идентификация существующих объектов в реализации 42
1.7 Рефакторинг и шаблоны реинжиниринга 45
1.8 Смежные вопросы 47
1.8.1 Подходы к пониманию программ 47
1.8.2 Метод "заворачивания" 47
Заключение 48
Глава 2 Конкретизация научной работы 50
2.1 Контекст научной работы 50
2.2 Обзор контекста системы автоматизированного перевода 53
2.1.1 Старый язык Кобол 53
2.1.2 Джава-новый язык и платформа 54
2.1.3 Другие входные и выходные языки 55
2.1.4 Трудности перевода 56
Заключение 56
Глава 3. Автоматизированный перевод 57
3.1 Методология предложенного подхода 57
3.1.1 Предложенный подход к получению результатов перевода 57
3.1.2 Предыдущие результаты исследования проблемы перевода 58
3.1.3 Применённый подход к автоматизированному переводу 63
3.2 Предложенное преобразование элементарных типов данных и операций над ними 69
3.3 Создание классов 74
3.3.1 Основной подход 74
3.3.2 Предложенный метод перевода разделяемых модулей описаний структур данных76
3.3.3 Стратегия создания классов из каждой записи 78
3.3.4 Предложенная стратегия создания классов с сокрытием реализации 81
3.4 Поддержка постепенного перевода 84
3.4.1 Поддержка метода "заворачивания" 84
3.4.2 Предложенный метод поддержки изменения кода, связанного с внешней средой. 86
3.5 Тестирование результатов перевода 91
3.5.1 Поддержка тестирования результатов перевода методом "чёрного" ящика 91
3.5.2 Предложенная модификация метода "чёрного" ящика для тестирования интерактивных приложений 93
3.6 Дальнейший рефакторинг результатов перевода 94
3.7 Применение подходов и методов для других языков 96
3.7.1 Преобразование элементарных типов данных и операций над ними 96
3.7.2 Метод перевода разделяемых модулей описаний структур данных 96
3.7.3 Стратегия создания классов с сокрытием реализации 97
3.7.4 Метод поддержки изменения кода, связанного с внешней средой 97
Заключение 97
Глава 4. Апробация 99
4.1 Перевод с использованием ранней версии системы перевода 99
4.2 Перевод с использованием последней версии 101
4.3 Производительность результатов перевода 103
Заключение 107
Заключение 109
Литература
- Виды деятельности при сопровождении программного обеспечения
- Обзор контекста системы автоматизированного перевода
- Предыдущие результаты исследования проблемы перевода
- Перевод с использованием последней версии
Введение к работе
Актуальность проблемы
Существует значительное количество программ, с момента написания которых прошли десятилетия, но они до настоящего времени находятся в эксплуатации. Для них издержки после выпуска достигают от 50 до 80 % всех затрат [62,63,89,95], а чем они становятся старше, тем их труднее поддерживать [41]. На настоящий момент затраты на сопровождение старого ("унаследованного") программного обеспечения (ПО) в мировом масштабе превысили затраты на создание нового ПО [59], что даёт основание утверждать некоторым исследователям о том, что разработка ПО является специальным случаем его сопровождения [96]. Зачастую среда выполнения старых систем (аппаратная платформа, операционная система, база данных и др.) становится слишком дорогой в поддержке или выходит из строя. Поддержка старого программного обеспечения усложняется использованием языков, которые не являются широко распространёнными (до 40% всего программного обеспечения по оценке [48]), поэтому часть проблем сопровождения связана с недостатком квалифицированного персонала.
Хотя существуют революционные варианты решения проблем старых систем, а именно, заменять их новыми или современными существующими, для их практической реализации требуются большие затраты на создание новых или адаптацию существующих систем. Наибольшей проблемой для вышеприведённых подходов является то, что для их осуществления необходимы знания об области применения и бизнес-правилах старой системы, а зачастую их единственным источником является она сама. Поскольку, как правило, старые системы обладают большим размером, то попытки извлечения данных знаний посредством понимания приложений нередко оказываются неудачными [95].
По данной причине получили широкое развитие эволюционные методологии, которые постепенно преобразуют существующую систему для целей облегчения её дальнейшего сопровождения.
Одним из подходов данного направления является реинжиниринг старой системы на другие языки и платформы посредством автоматизированного перевода. Перенос существующей системы в другую целевую среду заманчив, поскольку он может позволить использовать для решения проблем сопровождения достоинства целевой среды, а именно: большую доступность аппаратных платформ, программистов, средств разработки с поддержкой структурных преобразований с сохранением функциональности (рефакторинга [32]) и новых возможностей. Перевод между родственными средами является сравнительно
хорошо изученной задачей [43,55,85,92], с другой стороны, при реинжиниринге старых приложений на новые языки и платформы присутствует значительный разрыв между исходной и целевой средой. В последнем случае существующие подходы к переводу [125] жертвуют качеством его результатов ради автоматизации процесса, либо достигают высокого качества за счёт низкой автоматизации. Таким образом, применимость перевода для реинжиниринга старых приложений значительно ограничена односторонней направленностью существующих подходов к переводу.
Краткая история развития объекта исследования
Процесс автоматизированного перевода концептуально аналогичен компиляции [110], но, в отличие от последней, его результаты используются человеком, что определяет значительное различие в используемых подходах и исследуемых проблемах. В частности, кросс-компиляцию можно было бы считать видом перевода приложений на другие языки и платформы, поскольку она осуществляет трансляцию программы в машинный код другой архитектуры. С другой стороны, для целей переноса приложений на другую платформу вышеупомянутый подход не применим, поскольку он не решает проблему больших издержек на сопровождение текстов исходного приложения.
Первым практическим методом автоматизированного перевода стал подход прямолинейного перевода текстов программ (transliteration), который осуществляется путём прямолинейного соответствия конструкций исходного языка целевому языку. Особенностью применения данного метода заключается в том, что его применение не позволяет получить качественные результаты, а именно, программа выглядит в новом языке подобием старой и, как правило, хуже по сравнению с той программой, которая может быть написана программистом на целевом языке. Кроме того, при значительном различии исходного и целевого языка вышеупомянутый метод впрямую не применим, поскольку целевой язык может не обладать эквивалентами для определённых конструкций исходного языка [37].
Следующим предложенным методом стал подход, который состоит из двух этапов, а именно, построения модели переводимого фрагмента на более высоком уровне абстракции (abstraction) методом возвратного проектирования и создания новой реализации (reimplementation) на основании полученной модели [100]. Вышеописанный метод позволяет получать высококачественные результаты, поскольку он осуществляет перевод с использованием "смысла" оригинального фрагмента. С другой стороны, типичное применение метода может требовать больших затрат времени на понимание приложения в силу следующих причин:
• значительные вариации представления различных абстракций:
• необходимость учёта абстракций, специфичных для конкретного приложения;
• множество вариантов перехода от абстракций к результатам перевода.
В силу вышеперечисленных причин реализация метода требуют значительного участия пользователя, позволяя достичь невысокой автоматизации процесса, что делает трудным применение данного метода к реальным приложениям большого размера.
Как противоположность методам «белого» ящика, применение которых осуществляет преобразование реализации старой системы, был предложен метод «заворачивания» ("wrapping") [80], который вносит в новую среду видимость системы, полностью скрывая её старую реализацию. Данный метод осуществляет перенос образа старой системы, позволяя решить часть её проблем при ограниченных затратах времени, а именно, проблемы использования старой функциональности в новой среде. Кроме того, вышеописанный метод позволяет произвести постепенное изменение или замену приложения [79], поскольку клиенты в новой среде зависят от предоставленного интерфейса. С другой стороны, использование метода «заворачивания» оставляет открытым вопрос снижения затрат сопровождения.
На настоящий момент наиболее распространённым способом использования новой среды для старых приложений является метод «заворачивания», а полный перевод приложения, как правило, не рассматривается в силу огромной сложности и трудности. Одной из причин неприменимости полного перевода является существенная разница старых и современных языков программирования [92], которая не позволяет получать результаты высокого качества с достижением значительной автоматизации процесса и функциональной эквивалентности результатов перевода исходным текстам.
Цели и задачи диссертационной работы
Целью данной диссертационной работы является исследование подходов автоматизированного перевода для реинжиниринга старых приложений на новые языки и платформы. Решения этой задачи имеют большое значение для облегчения сопровождения старых программных систем. В рамках достижения вышеупомянутой цели были поставлены следующие задачи:
• Исследование существующих методов автоматизированных преобразований.
• Разработка новых подходов для решения проблем языкового перевода и улучшения качества результатов при различных сценариях реинжиниринга.
• Реализация предложенных подходов на практике.
Поскольку задача перевода старых систем на новые платформы зачастую связана со значительным различием старой и новой сред, а вьшолнение требования высокого качества результатов критично для достижения целей применения перевода, то существует необходимость научного исследования предмета автоматизированного перевода в указанном контексте.
Исходя из вышеизложенного, научная проблема диссертационного исследования формулируется следующим образом. Разработать метод автоматизированного перевода старых систем на новые языки и платформы для получения результатов с заданными свойствами, а именно: высоким функциональным соответствием результатов перевода исходным текстам и получением результатов высокого качества. Для исследования решений данной проблемы предложены следующие направления исследований:
• получение качественных результатов перевода при различных вариантах сохранения функциональности устаревших приложений;
• поддержка управления пользователем различных видов преобразований в процессе перевода;
• обеспечение управляемой зависимости результатов перевода от исходной и целевой среды;
• поддержка трансляции приложения, состоящего из многих программных модулей.
Тезисы, выносимые на защиту
1. Системный анализ существующих конструктивных решений в области применения автоматизированного перевода для реинжиниринга программного обеспечения, систематизация методов перевода, а также путей повышения их качества на основе практики известных исследований и проведенных автором натурных испытаний.
2. Подход к получению высококачественных результатов перевода, который состоит из следующих этапов:
• автоматическое получение результирующих текстов с высокой степенью функционального соответствия исходным текстам, удовлетворяющих критерию легкой читаемости;
• ручные модификации ограниченного объёма результирующих текстов по предлагаемой автором методике для реализации кода, зависимого от внешней среды;
• рефакторинг отдельных фрагментов результирующих текстов в обоснованных автором направлениях для улучшения структуры приложения.
3. Подход к преодолению трудностей языковых преобразований при переводе элементарных типов и операций над ними, который заключается в разделении их поддержки на интерфейсную и реализационную части, с целью использования встроенных типов данных целевого языка для перевода без потери функционального поведения.
4. Стратегия создания классов на основе преобразования иерархии структурных описаний данных для инкапсуляции в одном классе связанных по реализации объявлений, что позволяет существенно улучшить такие характеристики результатов перевода, как локальность реализации поддержки полей и длину ссылок на переменные.
5. Метод перевода разделяемых описаний структур данных, который состоит из следующих этапов:
• создание оптимизированных образов разделяемых описаний при трансляции отдельных программ;
• семантически управляемое слияние оптимизированных образов посредством использования реализации, корректной для всех использований.
Данный метод обеспечивает повторное использование высококачественных результатов перевода разделяемых описаний структур данных при независимой трансляции использующих их программных объектов.
6. Метод управления зависимостью результатов перевода от внешней среды в процессе перевода и их дальнейшего сопровождения, который состоит из следующих этапов:
• создание дескрипторов зависимых частей приложения;
• написание порождающих код преобразований;
• внедрение порождённого кода в существующее приложение.
Данный метод позволяет уменьшить усилия по ручной модификации кода, зависимого от внешней среды. Все основные результаты диссертационной работы являются новыми.
Аннотация диссертационной работы по главам
В первой главе диссертационной работы рассмотрены теоретические основы автоматизированного перевода в задаче реинжиниринга программного обеспечения. Произведён анализ предмета сопровождения в контексте жизненного цикла ПО, рассмотрен реинжиниринг как средство преодоления проблем сопровождения, показана роль автоматизированного перевода как основного средства выполнения реинжиниринга. Отдельно рассмотрены методы автоматизированного перевода, их достоинства и недостатки.
Вторая глава посвящена контексту выполненного исследования, описан научный контекст разработки средства автоматизированного реинжиниринга, в рамках которого происходили исследования и апробация данной работы. Приведен обзор типичного сценария автоматизированного перевода старой системы на языке Кобол в новый язык и платформу Джаву, перечислены другие входные и выходные языки, использованные для апробации, продемонстрированы конкретные трудности перевода. Особое внимание уделено научному контексту разработки средства автоматизированного реинжиниринга, в рамках которого происходили исследования и апробация данной работы.
Третья глава посвящена собственно описанию реализации перевода старых приложений, написанных на языке Кобол в язык Джаву. Продемонстрированы предложенные подходы к получению результатов высокого качества со значительной автоматизацией. Приведено описание разработанного метода управления автоматизированным преобразованием и поддержки внесения изменений при последующем адаптивном сопровождении результатов перевода. Описаны подходы тестирования и направления рефакторинга результатов перевода. Приведено описание применимости и апробации предложенных решений для других входных и выходных языков.
Четвертая глава посвящена промышленной апробации построенной реализации автоматизированного перевода. Описаны результаты использования предложенного метода на реальных приложениях. Приведены данные тестирования производительности результатов перевода.
В заключении приведена общая характеристика диссертационной работы и основные выводы по её результатам.
Благодарности
Я выражаю свою глубокую признательность следующим людям, без которых эта работа не увидела бы свет, а её промышленная апробация была бы невозможна:
• Моему научному руководителю Терехову А.Н.
• Терехову А.А. за огромную помощь в рецензировании промежуточных результатов.
• Исследования и апробация данной работы происходила как составная часть реализации средства автоматизированного реинжиниринга Modernization Workbench, поэтому автор выражает свою глубокую благодарность всем сотрудникам компании "Ланит-Терком", участвовавшим в разработке. В частности, руководству, направлявшему этот процесс: В. Оносовскому, Т. Поповой, А. Тиуновой, А. Апрелеву. Группе генерации, в которой собственно происходило воплощение идей работы: О. Смирнову, О. Хащанскому, Д.
Антонову, А. Оносовской, Е. Вергизовой, А. Губанову, М. Попову, В. Атлыгину, К. Лямову, В. Уфнаровскому, Б. Казанскому. Группе синтаксического анализа, без которой никаких результатов просто не было бы: В. Гордееву, В. Богданову. Группе BRE, помогавшей улучшить результаты генерации: А. Друнину, С. Трошину, Д. Шапорёнкову. Группам ПЛ1 и Натурал, помогавшим использовать генерацию для других входных языков, в частности Л. Григорьевой, Г. Тереховой, О. Миговской, Ю. Губанову, А. Симановскому. Группе консалтинга, в частности А. Голодной, М. Рубичевой, А. Тихонову, с которыми мы использовали систему на промышленных проектах. Группе тестирования, в частности, Г. Потаповой, Т. Серебряковой, Н. Кошкиной, И. Комарову, помогавших повысить качество продукта и группе визуальных интерфейсов, в частности, М. Бульонкову, Л. Рухлину, за организацию взаимодействия с пользователем. • Жене с дочкой и родителям за любовь, поддержку и терпение.
Виды деятельности при сопровождении программного обеспечения
Первоисточник проблем сопровождения больших систем скрывается в некоторых особенностях их разработки. В работе [5] авторами на основе анализа данных, собранных при разработке нескольких больших систем в течение нескольких выпусков, отмечены следующие эмпирические "законы эволюции": Закон постоянного изменения используемой программы. Используемая программа должна адаптироваться к изменениям в среде и функциональным потребностям, иначе она становится прогрессивно неудовлетворительной. Если не предпринимать каких-либо мер, то с развитием программы её сложность увеличивается.
Таким образом, если большая система останавливается в своей активной эволюции, то она переходит в фазу обслуживания, если не предпринимать никаких активных действий по устранению указанного эффекта, она начинает быстро терять способность к функциональной адекватности и эффективному сопровождению. Поскольку обычным для фазы обслуживания является недостаток квалифицированного персонала для осуществления более крупных изменений, все изменения приобретают локальный характер: детали реализации не затрагиваются, функциональность изменяется на входе и выходе. Как отмечено в работе [41], многочисленные мелкие исправления медленно разрушают структуру приложения, что приводит к существенному увеличению расходов на сопровождение. Система может стать не сопровождаемой, поскольку её энтропия достигла значительной величины.
Кроме того, типичным способом внесения изменений при недостаточной способности к изменению и отсутствии высокоуровневой архитектурной информации становится копирование кода, поскольку последний подход является самым лёгким способом повторного использования. Если после изменения копии код остаётся эквивалентным (осуществляет аналогичное действие), то при внесении изменений в одну копию необходимо внести изменения и в остальные копии. Но для нахождения данных мест необходим просмотр всего приложения, что делает этот просмотр непрактичным в силу его дороговизны. Указанная причина, а также отсутствие сокрытия информации, приводит к волнообразному эффекту изменений при дальнейшем сопровождении, поскольку изменение в одном месте приводит к большому количеству изменений в других местах [97], а, кроме того, с большой вероятностью исправление приводит к возникновению новых ошибок. По вышеперечисленным причинам старые системы плохо расширяемы и модифицируемы.
Большой возраст старых систем и вышеупомянутый подход к их модификации приводит к тому, что они имеют огромный размер, как правило, миллионы строк, что дополнительно накладывает ограничения на действия, осуществимые с ними в процессе обычного сопровождения [97]. Кроме того, старые системы зачастую работают на старом оборудовании и системном обеспечении, которые сами нуждаются в сопровождении.
Другой особенностью процесса сопровождения является то, что люди нередко уходят с этой работы, поскольку она однообразна и тяжела. Последнее явление представляет собой большую потерю для сопровождения конкретной системы, поскольку существенная часть информации о системе находится в виде неформальных знаний сотрудников сопровождения. Использование новых сотрудников осложняется тем, что проходит какое-то время, прежде чем они смогут быть полезными (время необходимо для построения ментальной модели сопровождаемой части). Им необходимо время, чтобы понять систему. Кроме того, достаточно непросто находить персонал, обученный старым технологиям и имеющий опыт сопровождения.
В силу ограниченности количества, квалификации и частой смены персонала старые системы нередко плохо документированы и имеют различные стили написания отдельных частей, что делает трудным их понимание. Для некоторых программ исходные тексты отсутствуют, либо они не используются.
Существенной частью процесса сопровождения является выполнение запросов пользователей для улучшения и расширения функций (сопровождение совершенствования). Видом данной активности является повторное использование уже существующей функциональности. Важным случаем указанного сценария является использование старых систем в контексте новых систем. Деятельность по повторному использованию трудно выполнима в рамках традиционного установившегося сопровождения, поскольку приложение трудно модифицируемо.
Для целей успешного обслуживания старых систем организации вводят инфраструктуру поддержки сопровождения, которая реализует определённый процесс сопровождения, в частности, контролируемые исправления происходят по запросу [82], с обязательным регрессионным тестированием. Использование инфраструктуры поддержки сопровождения позволяет частично разрешить или замедлить проявления многих из вышеперечисленных проблем.
Обзор контекста системы автоматизированного перевода
Язык Кобол (COBOL, COmmon Business Oriented Language, общий коммерческий язык) [99,118] появился в декабре 1959 года на основе языка FLOW-MATIC, разработанного Грейс Хоппер из компании UNIVAC. Еще в 1953 г она выдвинула идею о том, что, в отличие от математических программ, написанных с помощью математических обозначений, программы обработки данных следует писать на английском языке. Со временем последняя идея прижилась в руководстве компании и привела к созданию языка прообраза, а затем он покорил официальное собрание, посвященное универсальному языку для коммерческих приложений. Использование английского языка должно было расширить круг тех, кто может программировать на компьютере, кроме того, предполагалось, что менеджеры смогут читать программы. В 1968, 1974 и 1985 годах язык был стандартизован Национальным институтом стандартизации США (ANSI).
Эволюция языка протекала постепенно, по этой причине язык по-прежнему обладает многими возможностями, специфичными для момента своего появления. В частности, присутствуют низкоуровневые конструкции изменения потока управления: операторы безусловного перехода (GO ТО) и вызова параграфа (PERFORM) - поименованного блока кода. Другой характерной особенностью языка Кобол является один элементарный тип данных, определяемый форматной строкой (PICTURE) и классом хранения (USAGE). Кроме того, ряд конструкций связаны с представлением физической памяти, в частности, переопределения (RENAMES, REDEFINES), пересылки (MOVE, STRING), вырезки (Reference modification). Также в языке присутствует большой набор операторов работы с файлами и отчётами.
Особенностью старых приложений на языке Кобол является значительное использование возможностей среды выполнения: операционных систем, транзакционного монитора и базы данных. На уровне исходных текстов зависимость проявляется в виде включения вставок на других языках (CICS, SQL, IMS) или вызовов системных программ, кроме того, исходные тексты системы неоднородны, отдельно от программных модулей присутствуют и другие модули: экранные формы (BMS, DPS), планирования программ (JCL, ECL), соответствия логических имён физическим (РСТ, FCT) и др.
Кроме того, в силу своего долгого развития и особенностей сопровождения, приложения на язьпсе Кобол обладают большим размером: тысячи и десятки тысяч строк, а повторное использование кода между программами приложения заключается в использовании общих файлов включения (COPYBOOK).
В 1990 году компания Sun Mycrosystems пришла к выводу, что С и C++ не подходят для программирования встроенных бытовых устройств, таких как интерактивные телевизионные системы, поскольку они не удовлетворяют требованиям простоты и надёжности. Разработку нового языка возглавил Джейс Гослинг. На волне роста популярности Web язык сменил название и ориентацию и стал полезным инструментом для программирования в Интернет. Немало к популярности этого языка добавила и свободнораспространяемая среда разработки. Одной из важных областей применения является программирование для серверов в сети Интернет.
Джава - простой, но мощный объектно-ориентированный язык, использование которого может обеспечить меньшее количество проблем сопровождения для больших программных систем в силу наличия в языке абстракций, модульности и сокрытия информации.
Предшественники языка Джава языки С и C++ [124] в своём определении содержат много особенностей элементов языка, которые зависят от конкретной реализации и платформы. В частности, размеры типов данных зависят от платформы, работа с потоками зависит от реализации и т.д. Язык Джава жертвует более высокой эффективностью в пользу простоты, надёжности и независимости от платформы, что проявляется в следующих особенностях языка: примитивные типы определены фиксированным образом (byte, short, int, long, char, void); указатели заменены типизированными объектными ссылками; поддержка многопоточности встроена в язык; явное управление динамической памятью убрано из языка (неиспользованные фрагменты памяти собираются "сборкой мусора"); оператор безусловного перехода убран, но оставлена поддержка его структурных вариантов, связанных с выходом из цикла (break) или началом новой итерации (continue); осуществляются различные проверки корректности действий программы на этапе выполнения (выход за границу массива, приведение к несовместимому типу и т.д.);
В силу своей независимости от платформы, язык Джава способствовал подходу программирования, который ориентировался на независимость приложения от конкретных сторонних библиотек и производителей. Примером может служить поддержка Джавой открытых промышленных стандартов (TCP/IP, CORBA, XML, SOAP и др.)
Стремление к независимости от платформы и коммерческого программного обеспечения можно аргументировать попыткой предвосхитить многочисленные проблемы адаптивного сопровождения приложения в будущем, что является особенно актуальным для старых систем, которые привязаны к конкретной платформе и/или производителю ПО. По данной причине Джаву рекомендуют как альтернативу для новых разработок для организаций, использующих другие программные языки.
Растущая популярность Джавы ведёт к более широкому принятию модульного тестирования и рефакторинга. На практике применение указанных подходов может привести к упрощению сопровождения, поскольку, как обсуждалось в теоретической части работы, их использование позволяет совершать изменения постепенно с сохранением функциональности.
Важной особенностью Джавы является обширная библиотека классов, готовых к использованию. Эта особенность, а также наличие большого числа средств разработки приводит к большей скорости создания и модифицирования приложений.
Джаве обучают в подавляющем большинстве университетов во всём мире, поэтому существенно легче найти программистов, обладающих знанием данного языка и платформы, по сравнению со специалистами, владеющими языком Кобол и прочими старыми технологиями.
Предыдущие результаты исследования проблемы перевода
Одна из наиболее важных задач при преобразовании из одного языка в другие языки заключается в переводе типов данных и операций над ними. В процессе разработки системы перевода было осуществлено обширное исследование проблемы и реализовано решение, которое описано ниже.
В языке Кобол элементарные переменные описываются форматной строкой (PICTURE маска), которая определяет разрешённый диапазон значений, и типом размещения (USAGE конструкцией), который определяет представление значений в памяти. Несмотря на то, что документация определяет несколько комбинаций вышеупомянутых атрибутов, практически все разновидности переменных в Коболе имеют семантику фиксированного символьного размера, а именно: дополнение или отбрасывание значения во время присваивания происходит в зависимости от соотношения количества символов в значении и форматной строке. Таким образом, необходимо поддерживать упомянутые типы данных подобно строкам фиксированной длины, что затруднительно сделать прямолинейно, поскольку современные языки не имеют встроенных возможностей для указанной цели. Кроме того, данное свойство необходимо поддерживать вместе с остальными видами операций (арифметические операции и др.), но они зачастую не сводимы к операциям над строками. Наконец, семантика некоторых конструкций языка Кобол зависит от представления значения переменной в памяти и во время преобразования необходимо позаботиться об указанной особенности.
Для преодоления вышеупомянутых сложностей представление значения переменной (количество символов, отсутствие знака или хранимой точки в числовом представлении и другие детали реализации) конкретного типа отделено от его операций, следовательно, переменная представлена экземпляром абстрактного типа данных. На следующем этапе были идентифицированы встроенные типы данных Джавы, которые могут поддерживать необходимые операции (подход встроенных типов данных [120]), что привело к следующим правилам отображения:
Числовые типы без десятичной точки переводятся в int или long (в зависимости от точности) и их операции.
Типы с десятичной точкой было решено переводить в BigDecimal, класс стандартной библиотеки, реализующий поддержку десятичной арифметики, поскольку точность арифметики является очень важной особенностью для области применения языка Кобол [40]. Последующее тестирование производительности результатов показало, что данный подход связан с существенными накладными расходами в процессе выполнения. В качестве компромиссного варианта для типов с невысокой точностью было предложено использовать встроенный тип с плавающей точкой, что позволило достичь высокой производительности при достаточной точности в наиболее практически значимых случаях. Типы с плавающей точкой переводятся в float или double. Все остальные примитивные типы становятся char или String.
Для сокрытия реализации переменной выбранного типа (хранение значения в выстроенном виде, отсутствие знака и др.) создаются пара методов доступа для чтения (get) и записи (set) значения, как показано ниже: private String info; String getlnfoO { return info; } void setInfo(String value) { info = BasicSupport.format( value, 80 ); } а все использования переменной заменяются вызовами этих методов.
Использованная при переводе идиома свойства очень естественна для современных языков программирования. Кроме того, может быть необходимым сгенерировать несколько других методов, когда обычных методов доступа недостаточно для перевода некоторых операций, например, в следующем примере для поддержки использования числовых переменных в виде строчек создаётся метод getCounterFormatted(), static final int COUNTER = -1; final String getCounterFormattedO { return RWSupport. format(COUNTER, "S9"); } который необходим в ряде контекстов использования данных переменных (перевод операторов STRING, DISPLAY и др.).
Какая именно реализация методов доступа будет сгенерирована для конкретной переменной, зависит от ответов на следующие вопросы: Разделено ли представление этой переменной с другими или нет? Последняя ситуация происходит, если переменная явно или неявно переопределена или участвует в неструктурных групповых операциях. Важно ли сохранять полную двоичную совместимость с оригинальной версией или нет? Этот вопрос актуален, поскольку Кобол поддерживает несколько машинно-зависимых типов, например, переменные с типом размещения СОМР2 Нужно ли поддерживать точный диапазон значений? Например, разрешено ли для переменной с форматом РІС XX содержать больше или меньше чем два символа. Ответ на первый вопрос может быть дан автоматически, поскольку он выводим из синтаксиса исходного языка. В указанной ситуации реализация свойства изменяется, а именно, явное поле заменено классом поддержки выстроенного представления, как продемонстрировано далее.
Перевод с использованием последней версии
В процессе развития системы перевода была идентифицирована необходимость поддержки ею различных конфигураций целевой среды, различных видов пользовательского интерфейса, различных подходов к постоянству данных и т.д. С другой стороны, при обеспечении этой поддержки возникает похожая проблема модификации кода, зависимого от внешней среды, после автоматизированной фазы перевода. Например, указанная проблема возникает в процессе постепенного перевода приложения, поскольку код, зависимый от внешней среды может меняться несколько раз, после миграции данных необходимо изменить код доступа к ним. Ещё одной ситуацией, связанной с модификацией кода, зависимого от внешней среды, является адаптивное сопровождение приложения в процессе изменения окружающей среды.
Для обеспечения настройки результатов перевода на конкретную среду автором предложен подход управления кодом, зависящим от внешней среды. Кроме того, созданная система перевода позволяет изменять скрытую реализацию кода, зависимого от внешней среды, после окончания автоматизированного этапа перевода. Последняя возможность даёт возможность значительно облегчить проведение постепенного перевода и последующего адаптивного сопровождения, поскольку вышеупомянутый код может быть изменён по необходимости.
Разработанная система управления кодом, зависимым от внешней среды, функционирует следующим образом (Рисунок 22). На первом этапе в процессе перевода система перевода порождает документы XML [106], которые описывают зависимость от среды. Рисунок 23 содержит фрагмент подобного документа, описьшающий зависимость приложения от реляционной базы данных.
На втором этапе создаются файлы трансформаций XSLT [107], которые сгенерируют необходимый код взаимодействия со средой после обработки документов, порождённых на первом этапе. Для дальнейшей иллюстрации предьщущего примера, на Рисунке 24 приведён верхнеуровневый фрагмент кода трансформации, который создаёт код работы с базой данных.
Каждый раз, когда необходимо осуществить изменение кода, взаимодействующего со средой, происходит итерация цикла управления, который состоит из следующих шагов:
Опциональное изменение файлов трансформационных преобразований. Указанная модификация необходима для отражения изменений в реализации среды. Возвращаясь к предыдущему примеру, этот этап необходим в случае, если необходимо поменять драйвер базы данных в процессе сопровождения или осуществить модификацию доступа к базе данных в процессе постепенной миграции.
Возможная модификация XML документов для отражения в изменении интерфейса среды или данных, которые взаимодействуют с последней. Это изменение необходимо при изменении структуры или класса, взаимодействующего со средой.
Применение XSLT трансформаций к XML документам, используя традиционные XSLT процессоры. Для иллюстрации данного этапа Рисунок 25 содержит фрагмент кода, являющегося результатом применения трансформаций Рисунка 24 к документу описания Рисунка 23.
Возможное внедрение полученного кода в существующее приложение. Например, фрагмент кода на Рисунке 25, внедрён в реализацию метода класса на Рисунке 26.
Созданный код взаимодействия со средой может состоять из отдельных классов или модулей, в этом случае его использование не представляет существенных трудностей. В некоторых сценариях желательно, чтобы только часть модуля или класса являлось реализацией, зависимой от среды, например, метод read на Рисунке 26. Для поддержки вышеописанной возможности система перевода применяет специальный компонент, который замещает старый код новым, если он был или внедряет новый код в противном случае. Последняя операция осуществляется аналогично реализации АОП [50].