Реинжиниринг
Особый интерес вызывает вопрос, когда же следует прекращать сопровождение. На этот вопрос отвечает известная диаграмма:
увеличить изображение
Здесь по горизонтали растет важность программы для бизнеса компании, а по вертикали – сложность внесения исправлений. Так вот, если исправлять несложно, но и важность – небольшая, то надо просто сопровождать, исправляя ошибки (corrective fixing), если же программа важна для компании, то можно и улучшать ее (adaptive fixing). Если исправлять сложно, а важность – небольшая, то легче программу выкинуть, если же программа важна, содержит определенные знания бизнес-процессов, но сопровождать ее трудно, например, потому, что авторы программы покинули компанию или компания вынуждена сменить платформу, то программу следует подвергнуть реинжинирингу [15].
Попросту говоря, реинжиниринг – это перевод программы со старых языков (Кобол, ПЛ1, Адабас-Натурал и т.п.) на новые, такие как Java, Visual Basic, C++. На самом деле, все гораздо сложнее. Смена операционной системы, используемой базы данных, стиля организации диалога с пользователем – каждая из этих задач весьма нетривиальна. Если же добавить естественное желание реструктурировать программу, выкинуть отмершие части, перейти к объектно-ориентированной организации программы и т.д., да еще вспомнить, что все эти задачи требуют перебора и анализа путей в графе управления программы, число которых растет экспоненциально относительно числа вершин, то задача вообще выглядит нерешаемой. Мы потратили на нее много лет по заказу компании Relativity technologies (США, Северная Каролина) и создали продукт Rescueware, который известная консалтинговая компания Gartner Group уже дважды признала лучшим в мире в области legacy understanding и legacy transformation. Забавно, что сначала американцы обратились в несколько известных университетов США, но отовсюду получили ответ, объясняющий невозможность решения. На наше счастье, среди заказчиков был выходец из СССР (Лен Эрлих), который посоветовал обратиться к русским математикам, справедливо утверждая, что русские могут сделать то, чего американцы не могут.
Совершенно случайно ГП "Терком" оказался в числе трех российских компаний, к которым обратились американцы. Опыта общения с иностранными заказчиками у нас не было, как определять цену работы, мы не знали. Кстати, с этим вопросом связана забавная, но поучительная история. Принимал я американцев в своем кабинете, наскоро переделанном из обычной аудитории. На полу в линолеуме была большая дырка, на которую мы не обращали внимания. Через много лет я узнал, что эта дырка уменьшила стоимость самого первого американского заказа ровно в два раза.
Мы долго ломали голову, как подступиться к этой задаче. Мы все были математиками, поэтому хорошо понимали, почему американские ученые отказались от нее. Но потом сообразили, что в большинстве случаев нам и не нужен полный перебор путей в графе, а в тех случаях, когда без него не обойтись, можно за один перебор решить сразу несколько задач или одну задачу, но сразу для многих переменных. На тему реинжиниринга у нас опубликовано множество работ, все они выложены на сайте кафедры системного программирования.
Чтобы дать хоть какое-то представление о системе Rescueware, перечислим некоторые ее возможности:
- Инвентаризация. Осуществляется так называемый ослабленный синтаксический анализ (точный анализ затруднен из-за огромного числа диалектов старых языков), какие файлы включения используются, кто кого вызывает, что из этого есть в наличии. Случая не было, чтобы заказчик выдал все сразу, не забыв ни одного файла. На основании различных метрик оценивается сложность работы, трудоемкость и приблизительная стоимость.
- Строится дерево синтаксического разбора (видонезависимый и видозависимый анализы), пользователю в диалоговом режиме предоставляется возможность дополнительного изучения исходного приложения, представленного в виде гипертекста – на экране одновременно в разных окнах видны дерево разбора и исходный тест. Если пользователь смещается по дереву, автоматически перемещается и курсор в исходном тексте, и наоборот. Гипертекст, как и другие программы визуализации, был разработан группой М.
Бульонкова в Академгородке (г. Новосибирск), много лет работающей в тесном контакте с нами [16]. - По оригинальным алгоритмам исходное приложение преобразуется таким образом, чтобы уменьшить или вообще свести к нулю число операторов goto, разбить приложение на процедуры или на объекты (напоминаю, что в языке Кобол вообще не было понятия "процедура"), удалить ставшие со временем недостижимыми участки кода; реализуются различные методы глобальной оптимизации. Здесь следует отметить, что в отличие от обычной компиляции, в которой главным требованием является семантическое соответствие объектного кода исходному, (при этом сам объектный код никто не читает), в процессе реинжиниринга создается новый исходный код на другом языке, который будет сопровождаться этими же или другими программистами, поэтому на первый план выходят такие странные для компиляции вопросы как "естественность" представления программы, структурное подобие исходному приложению, наглядное форматирование текста и т.п.
- Генерация нового исходного текста на целевом языке с учетом только что перечисленных требований.
- Особого упоминания заслуживает BRE – Business Rules Extraction – выделение бизнес-правил. Представьте себе, что у Вас есть приложение (как обычно, написанное на разных языках), которое выполняет 10 функций. 7 из них уже безнадежно устарели, оставшиеся 3 очень важны для вашего бизнеса. Приложение старое, описания исходных алгоритмов уже не сохранились или сильно отстали от реальной программы, авторы давно разбежались кто куда. Таким образом, единственным носителем актуального знания осталась работающая программа, но ее сопровождение обходится очень дорого, поэтому хотелось бы выделить из текста только те описания и операторы, которые задействованы в нужных трех функциях, а весь остальной текст выкинуть. Скорее всего, получившаяся программа будет больше чем 30% от исходного текста, но все-таки намного меньше, чем вся исходная программа, поэтому сопровождать ее будет проще и дешевле.
Идея BRE очень проста – находите в конце графа программы узлы, где возникают конечные значения нужных функций, и двигаетесь назад, выбирая только те узлы и ребра, которые влияют на промежуточные вычисления уже помеченные, как нужные.
Можно и наоборот – если известно, что из 100 входных данных интересными остаются только 40, а остальными 60 можно пренебречь, можно пройтись по графу программы слева направо аналогичным образом.
Разумеется, на практике все гораздо сложнее — чего стоят одни массивы, в которых разные элементы влияют на разные функции. Тем не менее, нам удалось добиться практически значимых результатов.