Реинжениринг программного обеспечения

Цели

Цель настоящей главы — описание процесса peинжениринга, предполагающего повышение удобства эксплуатации программных систем. Прочитав главу, вы должны:

□ знать, почему реинжениринг часто является наиболее выгодным решением для развития компьютерных систем;

□ иметь представление о составляющих процесса реинжениринга;

□ понимать различие между реинженирингом программных систем и изменением системных данных, а также то, почему изменение данных является дорогостоящим процессом и требует много времени.

Содержание

28.1. Преобразование исходного кода программ

28.2. Анализ систем

28.3. Совершенствование структуры программ

28.4. Создание программных модулей

28.5. Изменение данных

В главах 26 и 27 дано описание наследуемых систем и различных стратегий развития программного обеспечения. Напомню, что наследуемой я называю старую систему, необходимую для поддержки текущей деловой активности организации, которая пока не мо­жет от нее отказаться. Организации во многом зависят от таких наследуемых систем, поэтому должны поддерживать их функционирование. В понятие эволюции наследуемой системы входят такие компоненты, как сопровождение, замена, архитектурная эволюция и реиижениринг, изучением которого мы займемся в этой главе.

Реинжениринг — это повторная реализация наследуемой системы в целях повышения удобства ее эксплуатации и сопровождения. В это понятие входят разные процессы, среди которых назовем повторное документирование системы, ее реорганизацию и реструктуризацию, перевод системы на один из более современных языков программирования, модификацию и модернизацию структуры и системных данных. При этом функциональность системы м ее архитектура остаются неизменными.

С технической точки зрения реинжениринг— это решение "второго сорта" проблемы системной эволюции. Если учесть, что архитектура системы не изменяется, то сделать централизованную систему распределенной представляется делом довольно сложным. Обычно нельзя изменить язык программирования старых систем на объектно-ориентированные языки (например, Java или C++). Эти ограничения вводятся для сохранения архитектуры системы.

Однако с коммерческой точки зрения реинжениринг часто принимается за единственный способ сохранения наследуемых систем в эксплуатации. Другие подходы к эволюции системы либо слишком дорогостоящие, либо рискованные. Чтобы понять причины такой позиции, следует рассмотреть проблемы, связанные с наследуемыми системами.

Код эксплуатируемых в настоящее время программных систем чрезвычайно огромен.

В 1990 году Улрич (Ulrich, [336]) насчитал 120 млрд. строк исходного кода эксплуатируемых в то время программ. При этом большинство программ были написаны на языке СOBOL, который лучше всего подходит для обработки данных в деловой сфере, и на языке FORTRAN. У этих языков достаточно ограниченные возможности в плане структуризации программ, a FORTRAN к тому же отличается ограниченной поддержкой структурированных данных.

Несмотря на постоянную замену подобных систем, многие из них все еще используются. С 1990 года отмечается резкое возрастание использования вычислительной техники в деловой сфере. При грубом подсчете можно говорить о 250 млрд. строк исходного кода, которые нуждаются в сопровождении. Большинство создано отнюдь не с помощью объектно-ориентированных языков программирования, многие из них функционируют все еще на мэйнфреймах.

Программных систем настолько много, что говорить о полной замене или радикальной реструктуризации их в большинстве организаций не приходится. Сопровождение старых систем действительно стоит дорого, однако реинжениринг может продлить время их существования. Как отмечалось в главе 26, реинжениринг систем выгоден в том случае, если система обладает определенной коммерческой ценностью, но дорога в сопровождении. С помощью реинжениринга совершенствуется системная структура, создается новая документация и облегчается сопровождение системы.

По сравнению с более радикальными подходами к совершенствованию систем реинениринг имеет два преимущества.

1. Снижение рисков. При повторной разработке ПО существуют большие риски — высока вероятность ошибок в системной спецификации и возникновения проблем во время разработки системы. Реинжениринг снижает эти риски.

2. Снижении затрат. (Себестоимость реинжениринга значительно ниже, чем разработка нового программного обеспечения. В статье [336] приводится пример системы, эксплуатируемой в коммерческой структуре, повторная разработка которой оценивалась в 50 млн. долларов. Для этой системы был успешно выполнен реинжениринг стоимостью всего 12 млн. долларов. Приведенные цифры типичны: считается, что реинжениринг в четыре раза дешевле, чем повторная разработка системы.

Реинжениринг ПО тесно связан с реинженирингом деловых процессов [153, 9*]. Последний означает преобразование бизнес-процессов для снижения количестиа излишних видов деятельности и повышения эффективности делового процесса. Обычно реинжениринг бизнес-процессов предполагает внедрение новых программ для поддержки деловых процессов или модификацию существующих программ, при этом наследуемые системы существенно зависят от делового процесса. Такую зависимость следует выявлять как можно раньше и устранять, прежде чем начнется планирование каких-либо изменений в самом бизнес-процессе. Поэтому решение о реинжениринге ПО может возникнуть, если исследуемую систему не удается адаптировать к новым деловым процессам путем изменений в обычном сопровождении системы.

Основное различие между реинженирингом и новой разработкой системы связано со стартовой точкой начала работы над системой. При реинжениринге вместо написания системной спецификации "с нуля" старая система служит основой для разработки спецификации новой системы. В статье [72] традиционная разработка ПО названа разработкой вперед (forward engineering), чтобы подчеркнуть различие между ней и реинженирингом Это различие проиллюстрировано на рис. 28.1. Традиционная разработка начинает» сэтапа создания системной спецификации, за которой следует проектирование и реализация новой системы. Реинжениринг основывается на существующей системе, которая разработчиками изучается и преобразуется в новую.

Рис. 28.1. Традиционная разработка и реинжениринг ПО

На рис. 28.2 показан возможный процесс реинжениринга. В начале этого процесса имеем наследуемую систему, а в результате— структурированную и заново скомпонованную версию той же системы. Перечислим основные этапы этого процесса.

1. Перевод исходного кода. Конвертирование программы со старого языка программирования на современную версию того же языка либо на другой язык.

2. Анализ программ. Документирование структуры и функциональных возможностей программ на основе их анализа.

3. Модификация структуры программ. Анализируется и модифицируется управляющая структура программ с целью сделать их более простыми и понятными

4. Разбиение на модули. Взаимосвязанные части программ группируются в модули; там, где ВОЗМОЖНО, устраняется избыточность. В некоторых случаях изменяется струк­тура системы.

5. Изменение системных данных. Данные, с которыми работает программа, изменяются с тем, чтобы соответствовать нововведениям.

Рис. 28.2. Процесс реинжениринга

При реинжениринге программ необязательно проходить все стадии, показанные на рис. 28.2. Например, не всегда нужно переводить исходный код, если язык программирования, на котором написана программа, все еще поддерживается разработчиком компиля­тора. Если реинжениринг проводится с помощью автоматизированных средств, то не обязательно восстанавливать документацию на программу. Изменение системных данных необходимо, если в результате реинжениринга изменяется их структура. Однако реструк­туризация данных в процессе реинжениринга требуется всегда.

Стоимость реинжениринга обычно определяется объемом выполненных работ. На рис. 28.3 показано несколько различных подходов к процессу реинжениринга и динамика изменения стоимости работ для этих подходов.

Рис. 28.3. Стоимость реинжениринга

Кроме объема выполняемых работ, есть и другие факторы, обусловливающие необходимость реинжениринга.

1. Качество программного обеспечения, которое подвергается рейхженирингу. Чем ниже качество программ и их документации (если она есть в наличии), тем выше стоимость реинжениринга.

2. Наличие средств поддержки процесса реинжениринга. Обычно реинжениринг эконочески выгоден, если применяются CASE-средства для автоматизированного внесения изменений в программы.

3. Объем необходимого преобразования данных. Стоимость процесса реинжениринга
растет при увеличении объема преобразуемых данных.

4. Наличие необходимых специалистов. Если персонал, который занимается сопровождением системы, не может выполнить реинжениринг, это также может стать причиной повышения стоимости процесса. Вновь привлеченные специалисты потратят много времени на изучение системы.

Основным недостатком реинжениринга принято считать то, что с его помощью систему можно улучшить только до определенной степени. Например, с помощью реинжениринга невозможно функционально-ориентированную систему сделать объектно - ориентированной. Основные архитектурные изменения или полную реструктуризацию программ невозможно выполнить автоматически, что также увеличивает стоимость реинжиниринга. И, несмотря на то что реинжениринг поможет улучшить сопровождение < и мы, все равно она будет намного хуже в сопровождении, чем новая, созданная г ПОМО1 современных методов инженерии ПО.

28.1. Преобразование исходного кода программ

Самый простой способ реинжениринга программ— это автоматический перевод исходного кода с одного языка программирования на другой, более современный. При этом структура и организация программ остаются неизменными. Программа может переводи как на обновленную версию исходного языка (например, с языка COBOL-74 на язык COBOL 85), так и на другой "не родственный" язык (например, с языка FORTRAN на С).

Причины перевода на другой язык могут быть следующие.

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

2. Недостаток квалифицированного персонала. Бывает, что для сопровождения программ на исходном языке невозможно найти достаточно квалифицированный персонал, особенно это касается программ, написанных на специфических языках, давно вышедших из употребления.

3. Изменения политики организации. Организация может принять решение о переходе на общий стандартный язык программирования, чтобы снизить затраты на сопровождение программных систем, поскольку сопровождение большого количества версий старых компиляторов невыгодно.

4. Нвдостаточно средств поддержки старого ПО. Поставщик компиляторов для старого языка программирования может уйти с рынка программных продуктов или прекра­тить поддержку своего продукта.

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

Рис. 28.4. Процесс преобразования программ

И некоторых случаях автоматизированный перевод становится невозможным. Структурные компоненты исходного кода могут не иметь соответствия в новом языке. Одна из причин этого в том, что исходный язык может содержать встроенные условные команды компиляции, которые не поддерживаются в новом языке. В такой ситуации придется настраивать и совершенствовать создаваемую систему вручную.

28.2. Анализ систем

Цель такого анализа — восстановление структуры и спецификации системы. Этот процесс не подразумевает изменения программ. Входными данными процесса анализа обыч­но служит исходный код системы. Однако зачастую даже он недоступен, тогда процесс анализа начинается с исполняемой программы.

Анализ систем не тождественен реинженирингу систем. Целью анализа является определение архитектуры и спецификации системы на основе ее исходного кода. Целью реинжениринга можно назвать создание усовершенствованной и удобной в сопровождении системы. Но, как показано на рис. 28.2, анализ системы может быть составной частью процесса реинжениринга.

Схема процесса анализа системы приведена на рис. 28.5. Вначале с помощью автоматизированных средств проводится анализ структуры системы. В большинстве случаев этого недоста­точно для воссоздания системной архитектуры. Требуется дополнительная работа с исходным кодом системы и с моделью ее структуры. Эта дополнительная информация сравнивается с данными, собранными во время автоматического анализа системы, и представляется в виде ориентированного графа, отображающего связи в исходном коде программ.

Рис. 28.5. Процесс анализа систем

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

В процессе анализа полезны разные средства просмотра программ, которые представляют различные системы представления программ и позволяют легко перемещатся по исходному коду. Например, с их помощью можно найти определения данных, а затем переместиться по коду к месту их использования. Описание некоторых подобных систем просмотра программ можно найти в [73, 263, 257].

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

28.3. Совершенствование структуры программ

Если в процессе эксплуатации наследуемой системы возникла необходимость оптимизировать использование памяти и имеются проблемы с пониманием того, как она работает, это означает, что система плохо структурирована. Управляющая структура наследуемых систем обычно значительно усложнена множеством безусловных переходов и некой ЛОГИКОЙ программного кода. Регулярное сопровождение системы также способствует сохранению системной структуры. После частых изменений некоторые фрагменты кода становятся неиспользуемыми, однако это можно обнаружить только после тщательного анализа программы.

В листинге 28.1 показан пример того, как усложненная логика управления может сделать трудной для понимания достаточно простую программу. Программа написана на языке, подобном FORTRAN, который часто использовался для создания программ таково рода. Программа не стала понятнее даже после того, как я дал переменным осмысленные имена. Это программа управления обогревателем. Панельный переключатель имеет положения On (Включено), Off (Выключено) и Controlled (Регулирование). Если система находится в режиме регулирования, она включается или выключается в зависимости от термореле и установок таймера. Если обогреватель включен, переключатель Switch-hoi выключает его, и наоборот.

Как правило, такая сложная логическая структура, как в коде листинга 28.1, образуется после внесения изменений в процессе сопровождения. Реализуя новые условия или связанные с ними действия, забывают об изменении структуры программы. Не задумываясь о перспективе, этот путь можно назвать кратчайшим и менее рискованным, так как он снижает вероятность возникновения большого количества ошибок в системе. Если же подумать о будущем, это решение приведет к трудному для понимания коду. Сложная структура кода может также появиться от желания программистов избежать дублирования кода. Ра­нее, когда на программы накладывалось требование ограничения памяти, это было обязательным условием.

Листинг 28.1. Программа с нечеткой логикой

Start: Get (Time-on, Time-off, Time, Setting, Temp, Switch)

if Switch = off goto off

if Switch = on goto on

goto Cntrld

off: if Heating-status = on goto Sw-off

goto loop

on: if Heating-status = off goto Sw-on

goto loop

Cntrld: if Time = Time-on goto on

if Time = Time-off goto off

if Time < Time-on goto Start

if Time > Time-off goto Start

if Temp > Setting then goto off

if Temp < Setting then goto on Sw-off: Heating-status:= off

goto Switch

Sw on: Heating-status:= on Switch: Switch-heating loop: goto Start

В листинге 28.2 приведена та же самая программа, переписанная мной с использованием структурированных управляющих конструкций. Три положения переключателя (On, Off и Controlled) четко определены и связаны с соответствующим кодом. Язык Java не был и. пользован при написании этой программы потому, что исходная программа не являлась объектно-ориентированной.

Листинг 28.2. Структурированная программа


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: