Генерация программного кода

 

Команды для генерации кода на языке Ada 95 содержит пункт Toots главного меню (рис. 17.33).

1. На компонентной диаграмме выделите оба компонента CourseOffering.

2. Выберите команду Tools:Ada95: Code Generation из главного меню.

Итоги генерации кода отображаются в окне Code Generation Status (рис. 17.34).

Все ошибки заносятся в log-окно.

3. Для завершения процесса генерации кода нажмите кнопку Close.

Рис. 17.33. Меню Tools: генерация кода на языке Ada 95

 

 

Рис. 17.34.Статус генерации кода

 

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

Просмотрим код, сгенерированный средой Rational Rose.

Фрагмент содержания .ads-файла, отражающего спецификацию класса CourseOffering,представлен на рис. 17.35. Отметим, что в программный текст добавлено то описание, которое было внесено в модель через окно документации. Более того, система Rational Rose подготавливает код к многократной итеративной модификации, защите выполняемых изменений. Стандартный раздел программного кода имеет вид

--##begin module.privateDeclarations preserve=yes

--##end module.privateDeclarations

Рис. 17.35.Код спецификации класса, сгенерированный средой Rational Rose

 

Запись module.privateDeclarations обозначает имя раздела. Элемент preserve=(yes/no) говорит системе, можно ли при повторной генерации кода этот раздел изменять или нельзя. После генерации кода программный текст добавляется между операторами ##begin и ##end.

Полный листинг сгенерированного кода спецификации выглядит так:

--##begin module.cp preserve=no

--##end module.cp

-- Specification CourseOffering (Package Specification)

-- Dir : C:\Program Files\Rational\Rose\ada95\source

-- File: courseoffering.ads

--##begin module.withs preserve=yes

--##end module.withs

package CourseOffering is

--##begin module.declarations preserve=no

--##end module.declarations

-- Class CourseOffering

-- Documentation:

-- CourseOffering is

-- Concurrency: Sequential

-- Persistence: Transient

-- Cardinality: n

type Object is tagged private;

type Handle is access Object'Class;

-- Array declarations

type Array_0f_0bject is

array (Positive range <>) of Object;

type Access_Array_Of_Object is

access Array_0f_0bject;

-- Standard Operations

function Create return Object;

function Copy (From : in Object) return Object;

procedure Free (This : in out Object);

function Create return Handle;

function Copy (From : in Handle) return Handle;

procedure Free (This : in out Handle);

-- Accessor Operations for Associations

function Get_The_Course (This : in Object)

return Course.Handle;

pragma Inline (Get_The_Course);

-- Association Operations

procedure Associate (This_Handle : in Handle;

This_Handle : in Handle);

procedure Associate (This_Handle : in Handle;

This_Array_Of_Handle : in Array_Of_Handle);

procedure Dissociate (This : in Handle);

procedure Dissociate (This : in Handle);

procedure Dissociate (This : in Array_Of_Handle);

-- Other Operations

function offeringOpen (This : in Object) return Integer;

--##begin module.additionalDeclarations preserve=yes

--##end module.additiona1Declarations

private

--##begin module.privateDeclarations preserve=yes

--##end module.privateDeclarations

type Object is tagged

record

-- Data Members for Class Attributes

numberStudents : Integer;

-- Data Members for Associations

The_Course : Course.Handle;

--##begin CourseOffering.private preserve=no

--##end CourseOffering.private

end record:

--##begin module.additionalPrivateDeclarations preserve=yes

--##end module.additionalPrivateDeclarations

end CourseOffering;

Соответственно, фрагмент содержания .adb-файла, отображающего тело класса CourseOffering, представлен на рис. 17.36.

Рис. 17.36.Код тела класса, сгенерированный Rational Rose

 

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

--##begin module.cp preserve=no

--##end module.cp

-- Body CourseOffering (Package Body)

-- Dir : C:\Program Files\Rationa1\Rose\ada95\source

-- File: courseoffering.adb

with Unchecked_Deallocation;

--##begin module.withs preserve=yes

--##end module.withs

package body CourseOffering is

--##begin module.declarations preserve=no

--##end module.declarations

-- Standard Operations

--##begin CourseOffering.CreatefcObject.documentation preserve=yes

--##end CourseOffering.Create%Object.documentation

function Create return Object is

--##begin CourseOffering.Create%Object.declarations preserve=no

--##end CourseOfferi ng.Create%Object.declarations

begin

--##begin CourseOffering.Create%Object.statements preserve=no

[statement]

--##end CourseOffering.Create%Object.statements

end Create;

--##begin CourseOffering.Copy%Object.documentation preserve=yes

--##end CourseOfferi ng.Copy%Object.documentation

function Copy (From : in Object) return Object is

--##begin CourseOffering.Copy%Object.declarations preserve=no

--##end CourseOffering.Copy%Object.declarations

begin

--##begin CourseOffering.Copy%Object.statements preserve=no

[statement]

--##end CourseOfferi ng.Copy%Object.statements

end Copy;

--##begin CourseOffering.Free%Object.documentation preserve=yes

--##end CourseOfferi ng.Free%Object.documentation

procedure Free (This : in out Object) is

--##begin CourseOffering.Free%Object.declarations preserve=yes

--##end CourseOfferi ng.Free%Object.decl arati ons

begin

--##begin CourseOffering.Free%Object.statements preserve=no

[statement]

--##end CourseOffering.Free%Object.statements

end Free;

--##beginCourseOffering. Create%Handle. documentati on preservers=yes

--##end CourseOffering.Create%Handle.documentation

function Create return Handle is

--##begin CourseOffering.Create%Handle.declarations preserve=no

--##end CourseOffering.Create%Handle.declarati ons

begin

--##begin CourseOffering.Create%Handle.statements preserve=no

[statement]

--##end CourseOfferi ng.Create%Handle.statements

end Create;

--##begi n CourseOffering.Copy%Handle.documentation preserve=yes

--##end CourseOffering.Copy%Handle.documentation

function Copy (From : in Handle) return Handle is

--##begin CourseOffering.Copy%Handle.declarations preserve=no

--##end CourseOfferi ng.Copy%Handle.declarations

begin

--##begin CourseOffering.Copy%Handle.statements preserve=no

[statement]

--##end CourseOfferi ng.Copy%Handle.statements

end Copy;

--##begin CourseOffering.Free%Handle.documentation preserve=yes

--##end CourseOfferi ng.Free%Handle.documentation

procedure Free (This : in out Handle) is

--##begin CourseOffering.Free%Handle.declarations preserve=yes

--##end CourseOffering. Free%Handle. declarations

begin

--##begin CourseOf feri ng.Free%Handle. statements preserve=no

[statement]

--##end CourseOffering.Free%Handle.statements

end Free:

-- Other Operations

--##begin CourseOffenng.offeringOpen%Object.940157546.documentati on preserve=yes

--##end CourseOfferi ng.offeringOpen%Object.940157546.documentation

function offeringOpen (This : in Object) return Integer is

--##begin CourseOfferi ng.offeri ngOpen%Object.940157546.declarations preserve=yes

--##end CourseOfferi ng.offeri ngOpen%Object.940157546.declarations

begin

--##begin CourseOfferi ng.offeri ngOpen%Object.940157546.statements preserve=yes

[statement]

--##end CourseOf feri ng. of f eri ngOpen%Object. 940157546. statements

end offeringOpen;

-- Accessor Operations for Associations

--##begin CourseOffering.Get_The_Course%Object.documentati on preserve=yes

--##end CourseOfferi ng. Get_The_Course%Object. documentati on

function Get_The_Course (This : in Object) return Course.Handle is

--##begi n CourseOfferi ng.Get_The_Course%Object.declarati ons preserve=no

--##end CourseOffering. Get__The_Course%Object. declarations

begin

--##begi n CourseOfferi ng.Get_The_Course%Object.statements preserve=no

return This.The_Course;

--##end CourseOfferi ng.Get_The_Course%Object.statements

end Get_Jhe_Course;

-- Association Operations

--##begin module.associations preserve=no

generic

type Role_Type is tagged private;

type Access_Role_Type is access Role_Type'Class;

type Index is range <>;

type Array _Of_Access_Role_Type is

array (Index range <>) of Access_Role_Type;

type Access_Array_Of_Access Role_Type is

access Array_Of_Access_Ro1e_Type;

package Generic_Tagged_Association is

procedure Set (This_Access_Array : in out

Access_Array_Of_Access_Role_Type;

This_Array : Array_Of_Access_Role_Type;

Limit : Positive := Positive

((Index'Last - Index'First) + 1));

function Is_Unique (This_Array : Array_Of_Access_Role_Type;

This : Access_Ro1e_Type) return Boolean;

function Unique (This_Array : in Array_Of_Access_Role_Type)

return Array_Of_Access_Role_Type;

pragma Inline (Set, Is_Unique, Unique);

end Generic_Tagged_Association;

package body Generic_Tagged_Association is

procedure Free is new Unchecked_Deallocation

( Array_Of_Access_Role_Type,

Access_Array_Of_Access_Role_Type);

procedure Set (This_Access_Array : in out

Access_Array_Of_Access_Role_Type;

This_Array : Array_Of_Access_Role_Type;

Limit : Positive := Positive

((Index'Last - Index'First) + 1)) is

Valid : Boolean;

Pos : Index := This_Array'First;

Last : constant Index := This_Array'Last;

Temp_Access_Array : Access_Array_Of_Access_Role_Type;

begin

if Positive(This_Array'Length) > Limit then

raise Constraint_Error;

end if;

if This_Access_Array - null then

-- Allocate entries.

This_Access_Array := new

Array_Of_Access_Role_Type'(This_Array);

return;

end if;

for I in This_Array'Range loop

Valid := Is_Unique (Th1s_Access_Array.all. This_Array (I));

pragma Assert (Valid);

end loop;

-- Reuse any empty slots.

for I in This_Access_Array'Range loop

if This_Access_Array (I) = null then

This_Access_Array (I) := This_Array (Pos);

Pos := Pos + 1;

if Pos > Last then return;

end if;

end if;

end loop;

if Positive(This_Access_Array'Length + (Last - Pos + 1)) > Limit then raise

Constraint_Error;

end if;

-- For any remaining entries, combine by reallocating.

Temp_Access_Array := new Array_Of_Access_Role_Type'

(This_Access_Array.all & This_Array (Pos .. Last));

Free (This_Access_Array);

This_Access_Array := Temp_Access_Array;

end Set;

function Is_Unique (This_Array : Array_Of_Access_Role_Type;

This : Access_Role_Type) return Boolean is

begin

if This = null then return False;

end if;

for I in This_Array'Range loop

if This_Array (I) = This then return False;

end if;

end loop;

return True;

end Is_Unique;

function Unique (This_Array : in Array_Of_Access_Role_Type)

return Array_Of_Access_Ro1e_Type is

First : constant Index := This_Array'First;

Count : Index := First;

Temp_Array : Array_Of_Access_Role_Type (This_Array'Range);

begin

for I in This_Array'Range loop

if Is_Unique (Temp_Array (First .. Count - 1).

This_Array (I)) then

Temp_Array (Count) := This_Array (I);

Count :- Count + 1;

end if;

end loop;

return Temp_Array (First .. Count - 1);

end Unique:

end Generic_Tagged_Association;

package Role_0bject is new Generic_Tagged_Association

(Object,

Handle,

Positive,

Array_Of_Handle,

Access_Array_Of_Hand1e);

--##end module.associations

procedure Associate (This_Handle : in Handle: This_Handle

: in Handle) is

--#begin Associate%38099E7D0190.declarations preserve=no

use Role_0bject;

--##end Associate%38099E7D0190.declarations

begin

--##begin Associate%38Q99E70Q190.statements preserve=no

pragma Assert (This_Hand1e /= null);

pragma Assert (This_Handle /= null);

pragma Assert (This_Handle.The_Course = null or

else This_Handle.The_Course = This_Handle);

This_Handle.The_Course := This_Handle;

Set (This_Handle.The_CourseOffering. Array_Of_Handle'(1 =>

This_Handle));

--##end Associate3%38099E7D0l90. statements

end Associate;

procedure Associate (This_Handle : in Handle;

This_Array_Of_Handle : in Array_Of_Handle) is

--##begin Associate%(1,N)38099E7D0190.declarations preserve=no

use Role_0bject;

Temp_Array_Of_Handle : constant Array_Of_Handle := Unique

(This_Array_Of_Handle):

--«end Associate%(l,N)38099E7D0190.declarations

begin

--##begin Associate%(l.N)38099E7D0190.statements preserve=no

pragma Assert (This_Handle /= null);

pragma Assert (Temp_Array_Of_Handle'Length > 0);

for I in Temp_Array_Of_Handle'Range loop

pragma Assert (Temp_Array_Of_Handle (I).The_Course = null or else

Temp_Array_Of_Handle (I).The_Course - This_Handle);

Temp_Array_Of_Handle (I).The_Course := This_Handle;

end loop;

Set (This_Handle.The_CourseOffering. Temp_Array_Of_Handle);

--##end Associate%(1,N)38099E7D0190.statements

end Associate;

procedure Dissociate (This : in Handle) is

--##begin Dissociate«38099E7D0190.declarations preserve=yes

--##end Dissociate«38099E7D0190.declarations

begin

--##begin Dissociate%38099E7D0190.statements preserve=no

pragma Assert (This /= null);

for I in This.The_CourseOffering'Range loop

if This.The_CourseOffering (I) /= null then

if This.The_CourseOffering (I).The_Course = This then

This.The_CourseOffering (I).The_Course := null;

This.The_CourseOffering (I) := null;

end if;

end if;

end loop;

--##end Dissociate%38099E7D0190.statements

end Dissociate;

procedure Dissociate (This := in Handle) is

--##begin Dissociate%38099E7D0190.declarations preserve=yes

--##end Dissociate%38099E7D0190.declarations

begin

--##begin Dissociate%38099E7D0190.statements preserve=no

pragma Assert (This /= null):

for I in This.The_Course.The_CourseOffering'Range loop

if This.The_Course.The_CourseOffering (I) = This then

This.The_Course.The_CourseOffering (I) :=null;

This.The_Course ;=null;

exit:

end if;

end loop;

--##end Dissociat%38099E7D0190.statements

end Dissociate;

procedure Dissociate (This : in Array_Of_Handle) is

--##begin Dissociate%(M)38099E7D0190.declarations preserve=yes

--##end Dissociate%(M)38099E7D0190.declarations

begin

--##begin Dissociate%(M)38099E7D0190.statements preserve=no

for I in This'Range loop

if This (I) /= null then

Dissociate (This (I));

end if;

end loop;

--##end Dissociate%(M)38099E7D0190.statements

end Dissociate;

--##begin module.additionalDeclarations preserve=yes

--##end module.additionalDec!arations

begin

--##begin module.statements preserve=no

null;

--##end module.statements

end CourseOffering;

 

Отметим, что в теле есть стандартные методы, которые не задавались в модели, — например, методы constructor, destructor и get/set. Их автоматическая генерация была задана настройкой среды — свойствами генерации. Система обеспечивает настройку параметров генерации для уровней класса, роли, свойства (атрибута) и проекта в целом. Более подробную информацию о свойствах генерации кода можно получить из help-файла.

Заключение

 

Современная программная инженерия (Software Engineering) — молодая и быстро развивающаяся область знаний и практик. Она ориентирована на комплексное решение задач, связанных с разработкой особой разновидности сложных систем — программных систем.

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

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

Впрочем, были времена, когда и другие «кланы» людей относились к «программе-рам» с большим подозрением: им мало платили, унижая материально, не находили для них ласковых слов (а употребляли большей частью ругательные). Где эти люди? И где их прежнее отношение?

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

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

Базис современной программной инженерии образуют следующие составляющие:

q процессы конструирования ПО;

q метрический аппарат, обеспечивающий измерения процессов и продуктов;

q аппарат формирования исходных требований к разработкам;

q аппарат анализа и проектирования ПО;

q аппарат визуального моделирования ПО;

q аппарат тестирования программных продуктов.

Все эти составляющие рассмотрены в данном учебнике. Конечно, многое осталось за кадром. Реорганизация (рефакторинг), особенности конструирования web-приложений, работа с базами данных — вот неполный перечень тем, обсудить которые не позволили ресурсные ограничения. Хотелось бы обратить внимание на новейшие постобъектные методологии — аспектно-ориентированное и многомерное проектирование и программирование. Они представляют собой новую высоту в стремительном полете в компьютерный космос. Но это — тема следующей работы. Впереди длинная и интересная дорога познаний. Как хочется подольше шагать по этой дороге.

В заключение «родился теплый лирический тост» — за программистов всех стран! А если серьезно, друзья, вы — строители целого виртуального мира, я верю в вас, я горжусь вами. Дерзайте, творите, разочаровывайтесь и очаровывайтесь! Я уверен, вы построите достойное информационное обеспечение человеческого общества!

Приложение А.