Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Медведев_С++_CLI_C#_Java_J#.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
5.17 Mб
Скачать

7.3Диаграмма последовательности

Если диаграмма классов представляла модель нашей программы статически, то диаграмма последовательности (sequence diagram) на рис. 7.3.1 отобразит функционирование объектов динамически, во времени.

Начинает действия стилизованный человечек - актант. Направленные от него стрелки к объекту :CInf требуют ввода или вывода данных. По этим требованиям объект :CInf оживает, превращая свою пунктирную линию жизни в вытянутые по времени вниз прямоугольники. Прямоугольниками представлено выполнение открьггых функций Enter() и Show() объекта :CInf .

Функция Clnf::Enter() создает (new) объект :CData класса CData, заполняет его введёнными данными (CData::Enter) и присоединяет (include) этот объект к списку объектов типа CData.

Функция CInf::Show() иcпoльзyeт oбъeкты:CData списка, которые уже созданы объектом :CInf, заполнены данными и связаны друг с другом.

Функция CInf::Show() просматривает список объектов класса CData и выводит находящуюся в них информацию, воспользовавшись функцией CData::Show() для каждого из этих объектов.

При завершении (exit) актантом приложения объекты уничтожаются.

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

Рис. 7.3.1. Диаграмма последовательности Inf-приложения

7.4Диаграмма видов деятельности

Диаграмма видов деятельности (activity diagram) описывает алгоритм выполнения функций применительно к используемым объектам.

В качестве примера рассмотрим диаграмму видов деятельности применительно к функции CInf::Enter(). Диаграмма (рис. 7.4.1) состоит из прямоугольников с округленными левой и правой сторонами, в которых указываются действия. Линии со стрелками связывают эти элементы в требуемой последовательности выполнения, допуская ветвления и слияния. Около разветвления помещаются условия в квадратных скобках. Начинается диаграмма с закрашенного кружка, а кончается в виде "глазка".

Согласно нашей диаграмме, вначале создаётся (create) и заполняется (input) информацией объект :CData. Затем следует ветвление. Если список (list) пустой (empty), то этот элемент подсоединяется непосредственно к указателю списка, иначе (isn't empty) - к последнему элементу списка. Итак, первый или очередной элемент включён в список и его адрес также зафиксирован в указателе pLast.

Хотелось бы добавить, что язык UML содержит нотацию и для представления параллельных действий в диаграмме видов деятельности.

Рис. 7.4.1. Диаграмма видов деятельности Inf-приложения для функции Enter() класса CInf

7.5Поэтапная разработка Inf-приложения на языке C++/CLI

Самое неразумное решение - это после получения диаграммы классов и других диаграмм языка UML, отображающих многогранно статическую и динамическую стороны нашей программы, приступить к полному написанию её программного кода, а затем к тестированию. Взгляните на диаграмму классов нашего Inf-приложения нарис.7.2.3. Какой бы сложности не была программа, её код должен создаваться и наращиваться поэтапно. Особенностью объектно-ориентированной поэтапной разработки программы является то, что наращиваемый код определяется реализуемым на текущем этапе классом, или группой классов, отдельное использование которых неуместно. Здесь класс или группа классов является кирпичиком или блоком, из которых строится программный код.

Возникает вопрос - какие классы диаграммы реализовывать в этапах, и в какой последовательности? Если внимательно взглянуть на диаграмму классов, то можно увидеть её явную древовидную структуру, в корне которой размещён главный или корневой класс.

Различают восходящую и нисходящую разработку программ.

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

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

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

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

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

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

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

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

После отладки класса надо ещё раз проанализировать его содержимое, инкапсулировав всё, что не относится к интерфейсу.

Реализуем InfC++/CLI-приложение, разрабатывая его поэтапно снизу-вверх.

Этап 1

Отладим класс CComputer. На этом этапе, располагая только описанием класса CComputer, создадим в главной функции main() объект pComp класса CComputer и вызовем интерфейсные функции Enter() и Show(), как в примере 7.5.1.