Самоучитель UML | Страница 1 | Онлайн-библиотека


Выбрать главу

Александр Леоненков

Самоучитель UML

ГЛАВА 1 Введение

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

1.1. Методология процедурно-ориентированного программирования

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

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

С этой точки зрения вся история математики тесно связана с разработкой тех или иных алгоритмов решения актуальных для своей эпохи задач. Более того, само понятие алгоритма стало предметом соответствующей теории – теории алгоритмов, которая занимается изучением общих свойств алгоритмов. Со временем содержание этой теории стало настолько абстрактным, что соответствующие результаты понимали только специалисты. Как дань этой традиции какой-то период времени языки программирования назывались алгоритмическими, а первое графическое средство документирования программ получило название блок-схемы алгоритма. Соответствующая система графических обозначений была зафиксирована в ГОСТ 19.701-90, который регламентировал использование условных обозначений в схемах алгоритмов, программ, данных и систем.

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

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

Важным свойством таких программ является необходимость завершения всех действий предшествующей процедуры для начала действий последующей процедуры. Изменение порядка выполнения этих действий даже в пределах одной процедуры потребовало включения в языки программирования специальных условных операторов типа if-then-eise и Goto для реализации ветвления вычислительного процесса в зависимости от промежуточных результатов решения задачи.

Рис. 1.1. Графическое представление программы в виде последовательности процедур

Рассмотренные идеи способствовали становлению некоторой системы взглядов на процесс разработки программ и написания программных кодов, которая Получила название методологии структурного программирования. Основой данной методологии является процедурная декомпозиция программной системы и организация отдельных модулей в виде совокупности выполняемых процедур. В рамках данной методологии получило развитие нисходящее проектирование программ или программирование «сверху-вниз». Период наибольшей популярности идей структурного программирования приходится на конец 70-х-начало 80-х годов.

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

Листинг 1.1. Пример фрагмента программы на Pascal, разработанной с использованием правил структурного программирования

Procedure FirstOpt; BeginFuncRaz(Free, Rn); for i:=l to N doRvarRec[i]:= Rn[i]; FvarRec:= Freс; Numlt:=0; RepeatNumIt:=NumIt+l; V:= Freс; for j:=1 to К do for 1:=1 to M do beginS:=0.0; T:=0.0;for i:=l to N do beginT:=T+sqr(Wl[i,j])*Xpr[i,l];S:=S+sqr(Wl[i,j])end;Zentr[j,l]:=T/S end;for j:=1 to К do for i:=l to N do beginS:=0.0; P:=0.0; Q:=0.0; for l:=1 to M doS:=S+sqr(Xpr[i,l]-Zentr[j,l]); P:=1.0/S; end; Q:=0.0; D:=0;for i:=1 to N do for j:=1 to К doif Abs(Wl[i,j]-W2[i,j]) >= Eps then D:=l; for i:=l to N dofor j:=1 to К doW1[i,j]:=W2[i,j] Until (D=0)or(NumIt=NumMax) End;

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

1.2. Методология объектно-ориентированного программирования

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

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

1
Александр Леоненков: Самоучитель UML 1
ГЛАВА 1 Введение 1
1.1. Методология процедурно-ориентированного программирования 1
1.2. Методология объектно-ориентированного программирования 1
1.3. Методология объектно-ориентированного анализа и проектирования 3
1.4. Методология системного анализа и системного моделирования 4
ГЛАВА 2 Исторический обзор развития методологии объектно-ориентированного анализа и проектирования сложных систем 5
2.1. Предыстория. Математические основы 5
Теория множеств 5
Теория графов 7
Семантические сети 8
2.2. Диаграммы структурного системного анализа 8
Диаграммы «сущность-связь» 8
Диаграммы функционального моделирования 9
Диаграммы потоков данных 10
2.3. Основные этапы развития UML 11
ГЛАВА 3 Основные компоненты языка UML 12
3.1. Назначение языка UML 13
3.2. Общая структура языка UML 14
3.3. Пакеты в языке UML 14
3.4. Основные пакеты метамодели языка UML 15
Пакет Основные элементы 15
Пакет Элементы ядра 15
Пакет Вспомогательные элементы 15
Пакет Механизмы расширения 16
Пакет Типы данных 16
Пакет Элементы поведения 16
Пакет Общее поведение 16
Пакет Кооперации 16
Пакет Варианты использования 17
Пакет Автоматы 17
Пакет Общие механизмы 17
Пакет Управление моделями 17
3.5. Специфика описания метамодели языка UML 17
3.6. Особенности изображения диаграмм языка UML 19
ГЛАВА 4 Диаграмма вариантов использования (use case diagram) 20
4.1. Вариант использования 20
4.2. Актеры 21
4.3. Интерфейсы 21
4.4. Примечания 21
4.5. Отношения на диаграмме вариантов использования 22
Отношение ассоциации 22
Отношение расширения 23
Отношение обобщения 23
Отношение включения 23
4.6. Пример построения диаграммы вариантов использования 24
4.7. Рекомендации по разработке диаграмм вариантов использования 25
ГЛАВА 5 Диаграмма классов (class diagram) 26
5.1. Класс 26
Имя класса 26
Атрибуты класса 26
Операция 28
5.2. Отношения между классами 29
Отношение зависимости 29
Отношение ассоциации 29
Отношение агрегации 30
Отношение композиции 30
Отношение обобщения 31
5.3. Интерфейсы . 31
5.4. Объекты 32
5.5. Шаблоны или параметризованные классы 32
5.6. Рекомендации по построению диаграмм классов 32
ГЛАВА 6 Диаграмма состояний (statechart diagram) 32
6.1. Автоматы 33
6.2. Состояние 34
Имя состояния 34
Список внутренних действий 34
Начальное состояние 34
Конечное состояние 35
6.3. Переход 35
Событие 35
Сторожевое условие 35
Выражение действия 36
6.4. Составное состояние и подсостояние 36
Последовательные подсостояния 36
Параллельные подсостояния 36
6.5. Историческое состояние 37
6.6. Сложные переходы 37
Переходы между параллельными состояниями 37
Переходы между составными состояниями 38
Синхронизирующие состояния 38
6.7. Заключительные рекомендации по построению диаграмм состояний 38
ГЛАВА 7 Диаграмма деятельности (activity diagram) 39
7.1. Состояние действия 39
7.2. Переходы 40
7.3. Дорожки 40
7.4. Объекты 41
7.5. Рекомендации по построению диаграмм деятельности 41
ГЛАВА 8 Диаграмма последовательности (sequence diagram) 42
8.1. Объекты 42
Линия жизни объекта 42
Фокус управления 42
8.2. Сообщения 43
Ветвление потока управления 43
Стереотипы сообщений 43
Временные ограничения на диаграммах последовательности 44
Комментарии или примечания 44
8.3. Пример построения диаграммы последовательности 44
8.4. Заключительные рекомендации по построению диаграмм последовательности 44
ГЛАВА 9 Диаграмма кооперации (collaboration diagram) 45
9.1. Кооперация 45
Диаграмма кооперации уровня спецификации 45
9.2. Объекты 46
Мультиобъект 46
Активный объект 46
Составной объект 46
9.3. Связи 46
Стереотипы связей 47
9.4. Сообщения 47
Формат записи сообщений 47
9.5. Пример построения диаграммы кооперации 48
9.6. Заключительные рекомендации по построению диаграмм кооперации 48
ГЛАВА 10 Диаграмма компонентов (component diagram) 48
10.1. Компоненты 49
Имя компонента 49
Виды компонентов 49
10.2. Интерфейсы 49
10.3. Зависимости 50
10.4. Рекомендации по построению диаграммы компонентов 50
ГЛАВА 11 Диаграмма развертывания (deployment diagram) 51
11.1. Узел 51
11.2. Соединения 52
11.3. Рекомендации по построению диаграммы развертывания 52
ГЛАВА 12 Особенности реализации языка UML в CASE-инструментарии Rational Rose 98/2000 53
12.1. Общая характеристика CASE-средства Rational Rose 98/2000 53
12.2. Особенности рабочего интерфейса Rational Rose 53
Главное меню программы 53
Стандартная панель инструментов 53
Окно браузера 54
Специальная панель инструментов 54
Окно диаграммы 54
Окно документации 54
Окно журнала 54
12.3. Начало работы над проектом в среде Rational Rose 54
12.4. Разработка диаграммы вариантов использования в среде Rational Rose 55
12.5. Разработка диаграммы классов в среде Rational Rose 55
12.6. Разработка диаграммы состояний в среде Rational Rose 55
12.7. Разработка диаграммы последовательности в среде Rational Rose 56
12.8. Разработка диаграммы кооперации в среде Rational Rose 56
12.9. Разработка диаграммы компонентов в среде Rational Rose 56
12.10. Разработка диаграммы развертывания в среде Rational Rose 56
Заключение 57