© Новичков А.Н., Interface Ltd., 2000
"С кем подружился... так тебе и надо...",
- способы внедрения CASE технологий....
В создании статей самое трудное написание продолжения первой части. Особенно трудно это потому, что за промежуток времени прошедший с момента написания первой, автор успевает разглядеть все недостатки предыдущей и начинает сомневаться в необходимости дальнейшего продолжения. Однако, на сей раз мне как автору даже не дали усомниться в написании продолжения, поскольку число отзывов, последовавших после выхода первой, заставляло постоянно возвращаться к обдумыванию новых вариантов продолжений.
Теперь вашему вниманию предлагается следующая часть статьи по Rational Rose, которая, как и прежде, целиком ориентированна на разработчиков, использующих в своей повседневной жизни язык С++. Дабы сильно не затягивать вступление расскажу о чем пойдет речь на этот раз.
В данной статье рассмотрено: обратное проектирование (попытаемся проанализировать имеющийся код и преобразовать его в модель на розе). проектирование сложного класса (для начала), рассмотрим некоторые моменты в настройках Rose для эффективной кодогенерации. Попробуем рассмотреть линки для иных (отличных от С++) языков программирования.
Так первую часть мы целиком посвещаем обратному проектированию.
Одно из неоспоримых преимуществ Rational Rose - обратное проектирование, поскольку разработчику и проектировщику важно увидеть перед изменениями уже работающую систему в нормальном графическом представлении. Как правило визуально-графический ряд оказывает куда большее воздействие нежели пролистывание технических заданий и программных текстов. Тем более что, проект, подвергшийся обратному проектированию может быть доработан и вновь сгенерирован (а впоследствии и скомпилирован). Rational Rose предоставляет для этого все необходимые средства.
Для осуществления обратного проектирования, в Rational Rose предусмотрен мощный модуль - Analyzer, чье основное предназначение, вытекающее из названия, анализ программ, написанных на С и С++. Данный модуль способен проанализировать имеющийся файл на одном из вышеупомянутых языков, и преобразовать его в визуальную модель, присвоив выходному файлу расширение mdl. Далее файл можно спокойно открыть для модификации из Rational Rose уже в визуальном режиме.
Analyzer представляет собой отдельный программный файл, вызываемый как из самой Rose, так и обычным способом. Модуль входит не во все поставки Rational Rose, а только в Enterprise, Professional и RealTime. В поставку Data Modeler данный модуль не входит, поскольку специфика поставки не предусматривает генерации кода и обратного проектирования.
Дальнейшая часть статьи будет посвящена как раз обратному проектированию, мы рассмотрим на конкретных прмерах, что разработчик получит от Rational Rose, применяя ее в качестве инструмента визуального ОО-проектирования.
Примеры будут содержать различные конструкции на языке С++ и результат их преобразования в модель. Также постараемся уделить достаточное время деталям трансляции кода программы в модель.
Для правильного преобразования кода в модель необходимо провести несколько настроек, о которых мы и поговорим.
Рис.1
На рисунке 1 показан внешний вид программы в стандартных настройках и с не загроможденным экраном.
Основные поля, подлежащие обязательному заполнению (на первом этапе) это:
Caption. | Имя проекта. В последствии имя модели будет определено по имени проекта. |
Directories. | Путь к исходящей директории. По умолчанию, Rose использует для хранения исходящих модельных файлов директорию С++\Source из домашней директории, что в некоторых случаях может приносить некоторые неудобства. |
Extensions. | Типы используемых расширений. Здесь можно настроить систему так, чтобы она распознавала только опредделенные виды расширений. |
Bases. | Место сохранения текущего проекта. |
Files. | Списсок из файлов, подлежащих генерации. |
Для проведения правильного реинжениринга необходимо заполнить вышеописанные поля. Все файлы, подлежащие реинженирингу указываются в поле "Files". Следует учитывать, что при реинжениринге вы получаете визуальную модель взаимодействия классов и структур, стало быть не идет ни какой речи о том, чтобы на визуальной модели отразился существующий код системы. Далее: все нестандартные конструкции не будут выведены в модель (анализатор их просто проигнорирует), это значит, что любое отклонение от заранее известных конструкций приводит к тому, что в изначальном варианте Rose не сможет правильно проанализировать код. Этот факт не является недостатком, поскольку в арсенале Analyser'а есть инструменты тонкой настройки, позволяющие настроить все таким образом, чтобы специфика конкретного проекты была бы полностью учтена.
Процесс реинжениринга делится на два этапа: анализ и генерация модели.
На первом этапе производятся все подготовительные операции по анализу текста программы на отсутствие синтаксических ошибок. Второй этап - это преобразование кода в модель.
Все операции выполняются независимо, что дает больший маневр для разработчика, который, например, хочет провести только синтаксический разбор теста, без генерации модели.
Соответственно, при отсутствии ошибок в файле можно приступить к генерации модели. В целях оптимизации времени генерации в Rose предусмотрено три способа проведения реинжениринга, каждый из которых может охватить и превосходно выполнить определенный сегмент работ. Если пользователю по каким либо причинам не подходит не один из трех предустановленных способов, то Rose допускает создание собственного реверсинжениринга.
Поговорим подробнее о трех стандартных способах :
FirstLook. | Приближенная пробежка по телу программы |
DetailedAnalysis. | Детальный анализ проекта. |
RoundTrip. | Комбинация двух вышеперечисленных способов. Позволяет безболезненно строить и перестраивать разрабатываемые приложения по принципу круговой разработки. |
Все настройки могут быть изменены пользователем по усмотрению. При сохранении изменений возможно указать новое имя шаблона или перезаписать уже существующее, что позволит при частом использовании обратного проектирования не терять времени на установку нужного пункта. Как и все под этим небом, выбор соответствующего пункта обязательно сказывается на скорости анализа, чем больше - тем дольше. Еще хочется отметить такую особенность модуля Analyzer: после анализа создается не только модель но и лог файл с сообщениями, возникшими в результате сканирования программы. Лог может содержать как предупреждения так и ошибки. А особенность генерации модели состоит в том, что она состоится несмотря ни на что, то есть, невзирая на ошибки в тексте программы. Естественно никакой речи нет о какой-либо правильной модели! Эту особенность следует учитывать и внимательно анализировать файл отчета после генерации модели.
Еще одна немаловажная ремарка. Как правило обратному проектированию подвергается полноценный проектный файл, содержащий в себе и директивы #INCLUDE для определений, и комментарии... а также прочие сопроводительные инструкции. И естественно разработчику хочется иметь такой инструмент, который адекватно будет реагировать на все составляющие. Спешу обрадовать: модуль Analyzer в режиме (DetailedAnalysis) обеспечивает следующее:
Теперь от общих фраз перейдем к практике (как говаривал незабвенный сын турцкоподданого: "ближе к телу... сведения будут оплачены..."). Для начала попытаемся проделать обратное проектирование с языка С без использования объектов. Нашей целью будет получение графической модели из структуры на языке программирования. Почему структуры? Данный тип данных все еще широко используется программистами на языке С, сбрасывать со счетов, который несколько преждевременно!
Итак проект для реверсинжениринга представляет собой только заголовочный файл с объявлением следующей структуры:
//It's main structure struct struct_main{ char *string; //Structure's pointer int buffer[100]; //Temporary buffer char name[10]={"Massiv"};//Name of data int a; //Integer int b; //Integer };
Как видите структура достаточно тривиальна. Без излишеств. Особо хочется еще раз обратить внимание на комментарии. Каждая строка снабжена комментарием, который несет некую смысловую нагрузку. Смысл любого реверсинжениринга состоит не только в том, чтобы корректно нарисовать модель, но и для правильного описания спецификации каждой составляющей класса/структуры.
После проведения всех стандартных манипуляций по созданию проекта и его анализу получается вот такая модель в розе (рис 2):
Рис. 2
Рис. 3
Рис.4
Рисунки 2, 3 и 4 показывают отдельные спецификации.
2 - модель структуры, полученной в результате обратного проектирования
3 - список атрибутов класса/структуры. Здесь перечислены все переменные структуры.
4 - генеральная информация о структуре. Как видно из рисунка, комментарий без каких бы то ни было ограничений перешел в разряд документации, что позволит использовать его на дальнейшем этапе дополнения атрибутов, документирования и создания отчетов
Как видим, конечный результат достоин внимания, поскольку модель ничего не теряет в результате обратного проектирования, в то же время само обратное проектирование представляет мощныхй механизм анализа эффективности существующих программных наработок нажатием на одну-две кнопки.
И еще... в качестве частного случая рассмотрим объявление подструктуры в соответствии с нижеприведенным листингом:
//It's main structure struct struct_main{ char *string; //Structure's pointer int buffer[100]; //Temporary buffer char name[10]={"Massiv"};//Name of data int a; //Integer int b; //Integer struct struct_in{ int m,st; }; };
На этот раз без комментариев и занудства. На выходе получим (стр 5) следующую модель:
Рис.5
Как видим все ясно и понятно. Скромно, но очень информативно. К сожалению, если дело касается структур, то никакие связи в модели не генерятся!
Теперь перейдем к более тяжелым материям в виде классов С++. Хотя язык С и остается достаточно мощным структурным языком, все же его "изобразительных" средств в плане построения крупных информационных систем явно недостаточно. Мы не будем углубляться в полемику о том почему на больших проектах С++ смотрится выигрышней, также не будем мы затрагивать самой концепции ООП - все это тема отдельной статьи (может и не одной) или книги... хотя вряд ли стоит ее писать... подобных трудов да от именитых авторов бессчетное множество. Нас интересует достаточно приземленная проблема: как классы из чистого текста можно преобразовать в наглядную модель с обеспечением всех графических связей...
Как и ранее, попробуем проделать реверсинжениринг используя простой класс. За основу программы перепишем (подстроим) структуру под класс. Получим в итоге нечто похожее на следующий листинг:
//It's main class class string{ public: char *string; //Structure's pointer int buffer[100]; //Temporary buffer char name[10]={"Massiv"}; //Name of data int a; //Integer int b; //Integer void string(void); //constructor void ~string(void); //destructor char StringCopy(char *, //Buffer char *, //source1 char *); //source2 private: int tmp_a; int tmp_b; };
Результат обратного проектирования:
Рис.6
Рис.7
Рисунок 6 показывает модель класса "string". А на рисунке 7 отображается вкладка, описывающая функции класса. Как и в случае с переменными имена функций отображаются на экране. Также доступен вход в спецификации конкретной функции. Если еще раз вернуться к листингу, то можно обратить внимание на декларацию функции "StringCopy", в которой входные параметры дотошно документированы. Так вот, если был применен подобный подход к документированию, то комментарий каждого параметра перенесется в качестве описательного комментария в соответствующую часть атрибута модели класса. То есть, получается, очень выгодно подвергать обработке исходные тексты написанные по всем правилам программирования.
С простым классом все просто - со сложным - немного сложнее. Ниже вашему вниманию представлен листинг трех классов и их визуальная модель. Пример иллюстрирует изобразительные возможности Rose в плане прорисовки связей между классами.
//It's main class class string{ public: char *string; //Structure's pointer int buffer[100]; //Temporary buffer char name[10]={"Massiv"}; //Name of data int a; //Integer int b; //Integer void string(void); //constructor void ~string(void); //destructor char StringCopy(char *, //Buffer char *, //source1 char *); //source2 private: int tmp_a; int tmp_b; }; //It's my string class MyString: public string{ public: int s,m,r; private: char ms, mss; }; //Super string class NewString: public string, MyString { public: int z; };
Рис.9
Как видно из рисунка 9, после операции обратного проектирования сразу станет видно дерево наследования, что позволит разработчику узнать всю иерархию, а затем оптимизировать приложение под собственные нужды, избавившись от ненужной (неэффективной) ветви.
Вашему вниманию было предложено несколько примеров по использованию функций обратного проектирования. Можно предположить, что Rational Rose придется по душе не только аналитикам, но и проектировщика и разработчикам, поскольку ее выразительные средства визуального проектирования и анализа делают ее незаменим инструментом при создании крупных информационных систем. Особенно полно Rose раскрывает свои возможности при анализе эффективности не новой системы, а уже существующей. Вышеуказанные примеры дают представление о том, что даст инструмент при анализе проекта с целью повышение его эффективности. Данная проблема не является надуманной, поскольку подобный анализ очень нужен компаниям переводящим, например, старое программное обеспечение на новые платформы и новые технологии.
Казалось, что можно придумать еще в дополнение к сказанному. Что еще может содержать и без того мощный инструмент... Ан нет! Про Rose можно еще говорить и говорить. Rational Rose имеет в своем арсенале возможность прямого и обратного проектирования на: ADA, Java, C++, COM, DDL, Basic, XML, схемы Oracle и Sql srv... Но как быть тем, кто использует языки отсутствующие в списке поддержки? К сожалению компания Ratoinl не стремится расширять список поддерживаемых языков за свой счет, отдав на откуп третьим фирмам возможность заполнения языковых ниш. Это возможно по той простой причине, что Rose имеет открытое, хорошо документированное API, позволяющее любому человеку создать дополнительный модуль (мост) для любого языка! Подчеркиваю: ДЛЯ ЛЮБОГО. Естественно, при этом человек должен досканально знать UML и синтаксис языка-источника и какое-то время на данную реализацию. Пока на сегодняшний день Rose уникальный продукт в плане открытости архитектуры.
На данный момент существуют несколько компаний, например, EnsembleSystems (www.ensemble-systems.com), занимающихся написанием подобных линков. Уже есть линки к Delphi, ErWin, Jbuilder, VisualCafe, Jdeveloper, VisualAge SmallTalk...
Согласитесь, список внушает оптимизм и вселяет надежду, что рано или поздно будет полностью покрыт весь языковой спектр и Роза начнет понимать все, включая человеческую речь!
Продолжение следует...