
Задания, лекции / Червенчук
.pdfНо иногда приходится визуализировать или специфицировать и другие специфические свойства, такие как видимость отдельных атрибутов и операций, специфические для конкретного языка программирования типы данных или даже исключительные ситуации, которые объекты класса могут возбуждать или обрабатывать. Эти и многие другие особенности тоже можно выразить в UML, но в таком случае требуется обращение к более развитым возможностям языка.
Большинство создаваемых при моделировании абстракций являются разновидностью классов. Часто бывает необходимо отделить реализацию класса от его спецификации, что может быть выражено с помощью интерфейсов.
Переходя к разработке более сложных моделей, часто приходится сталкиваться с теми же классами (которые представляют, например, параллельные процессы и потоки или физические элементы модели, в частности апплеты, компоненты JavaBeans и СОМ+, файлы, Web-страницы, базы данных). Поскольку подобные классы очень распространены и представляют важные архитектурные абстракции, в UML имеются такие элементы, как активные классы, компоненты и узлы.
При всем этом, классы редко существуют сами по себе. При построении моделей следует обращать внимание на группы взаимодействующих между собой классов. В языке UML такие сообщества принято называть кооперациями и изображать на диаграммах классов.
2.6.ТИПИЧНЫЕ ПРИЕМЫ МОДЕЛИРОВАНИЯ
Спомощью классов обычно моделируют абстракции, извлеченные из решаемой задачи или технологии, применяемой для ее решения. Такие абстракции являются составной частью словаря вашей системы, то есть представляют сущности, важные для пользователей и разработчиков.
Для пользователей не составляет труда идентифицировать большую часть абстракций, поскольку они созданы на основе тех сущностей, которые уже использовались для описания системы. Чтобы помочь пользователям выявить эти абстракции, лучше всего прибегнуть к таким методам, как использование CRC-карточек и анализ прецедентов. Для разработчиков же абстракции являются обычно просто элементами технологии, которая была задействована при решении задачи.
41

Моделирование словаря системы включает следующие этапы:
1.Определение элементов, которые пользователи и разработчики применяют для описания задачи или ее решения. Для отыскания правильных абстракций используются CRC-карточки и анализ прецедентов.
2.Выявление для каждой абстракции соответствующего ей множества обязанностей. Необходимо проследить, чтобы каждый класс был четко определен, а распределение обязанностей между ними хорошо сбалансировано.
3.Разработка атрибутов и операций, необходимых для выполнения классами своих обязанностей.
На рис. 2.9 показан набор классов для системы розничной торговли: Customer (Клиент), Order (Заказ) и Product (Товар). Представлено несколько соотнесенных с ними абстракций, взятых из словаря проблемной об-
ласти: Shipment (Отгрузка), Invoice (Накладная) и Warehouse (Склад). Од-
на абстракция, а именно Transaction (Транзакция), применяемая к заказам
иотгрузкам, связана с технологией решения задачи.
Warehouse
customer |
|
|
имя |
|
|
адрес |
|
Order |
телефон |
|
|
|
товар |
|
датаРождения |
|
|
|
количество |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Transaction |
|
Invoice |
|||
|
action |
||
|
|
||
|
|
|
|
|
|
Commit() |
|
|
|
RollBack() |
|
|
|
wasSuccessful() |
|
|
|
|
Product
идентификатор
название
цена
местонахождение
Shipment
Обязанности
–сохранять информацию о товарах, поставленных по закзам
–отслеживать состояние и местонахождение товаров
Рис. 2.9. Моделирование словаря системы
42
По мере того, как будет развиваться модель, обнаружится, что многие классы естественным образом объединяются в концептуально и семантически родственные группы. В языке UML для моделирования таких групп классов используются пакеты.
Как правило, модели не бывают статичными. Напротив, большинство абстракций из словаря системы динамически взаимодействует друг с другом. В UML существует несколько способов моделирования такого динамического поведения.
2.7. РАСПРЕДЕЛЕНИЕ ОБЯЗАННОСТЕЙ В СИСТЕМЕ
Если в разрабатываемый проект входит нечто большее, нежели пара несложных классов, предстоит позаботиться о сбалансированном распределении обязанностей. Это значит, что надо избегать слишком больших или, наоборот, чересчур маленьких классов. Каждый класс должен быть автономен, хорошо делать что-то одно. Если выделенные абстрактные классы слишком велики, то модель будет трудно модифицировать и повторно использовать. Если же они слишком малы, то придется иметь дело с таким большим количеством абстракций, что ни понять, ни управлять ими будет невозможно. Язык UML способен помочь в визуализации и специфицировании баланса обязанностей.
Моделирование распределения обязанностей в системе включает следующие этапы:
1. Идентификация совокупности классов, совместно отвечающих за некоторое поведение.
2.Определение обязанностей каждого класса.
3.Оценка классов на предмет сбалансированного распределения обязанностей. Необходимо взглянуть на полученные классы как на единое целое и разбить те из них, у которых слишком много обязанностей, на меньшие – и наоборот, крошечные классы с элементарными обязанностями объединить в более крупные.
4.Перераспределение обязанностей таким образом, чтобы каждая абстракция стала в разумной степени автономной.
5.Кооперация классов. Следует рассмотреть, как классы кооперируются друг с другом, и перераспределить обязанности с таким расчетом, чтобы ни один класс в рамках кооперации не делал слишком много или слишком мало.
43

В качестве примера на рис. 2.10 показано распределение обязанностей между классами Model (Модель), View (Вид) и Controller (Контроллер) из совокупности классов языка Smalltalk.
Sourсe
Обязанности
–предоставлять информацию
модели
Controller
Обязанности
–синхронизировать изменение источника и монитора
Monitor
Обязанности
–изображать данные на экране
–управлять перемещением и изменением размера поля зрения
–перехватывать события пользователя
Рис. 2.10. Моделирование распределения обязанностей в системе
Как видим, их совместная работа организована так, что ни одному из классов не приходится делать слишком мало или слишком много.
2.8. ВНЕПРОГРАММНЫЕ СУЩНОСТИ
Не все моделируемые сущности обязательно будут присутствовать в конечном программном продукте. Например, частью рабочего процесса в модели предприятия может быть взаимодействие с различными службами (инспектор пожарной охраны, налоговый инспектор), роботы – упаковщики, перевозчики. В конечном приложении совсем не обязательно будут присутствовать компоненты для представления данных сущностей (в отличие от сущности «клиент», для хранения информации о которой, собственно, и создается система).
Моделирование внепрограммных сущностей производится в несколько этапов:
1.Моделирование сущностей, абстрагируемых в виде классов.
2.Расширение словаря сущностей (при необходимости) с помощью стереотипов. Если необходимо отличить эти сущности от предопределенных строительных блоков UML, следует создать с помощью стереотипов новый строительный блок, описать его семантику и сопоставить с ним ясный визуальный образ.
44

3. Моделирование аппаратного средства. Если моделируемый элемент является аппаратным средством с собственным программным обеспечением, следует рассмотреть возможность смоделировать его в виде узла, что позволило бы в дальнейшем расширить его структуру.
Язык UML предназначен в первую очередь для моделирования программных систем, однако в сочетании с языком описания аппаратных средств его вполне допустимо использовать и для моделирования аппаратных систем.
Рис. 2.11. Моделирование внепрограммных сущностей
Как видно из рис. 2.11, абстрагирование представителей служб (Tax Officer – Налоговый инспектор) и аппаратуры (Robot) в виде классов вполне естественно, поскольку они представляют собой множества объектов с общей структурой и поведением. Внешние по отношению к системе сущности часто моделируются как актеры.
2.9.ПРИМИТИВНЫЕ ТИПЫ
Вразличных языках программирования применяются различные предопределенные типы данных. Так, например, в языке Си используется четыре целых типа: Int (стандартное целое), Long (длинное целое), Short (короткое целое), Unsigned (беззнаковое целое стандартной длины). Данные абстракции называются примитивными типами и моделируются с помощью стереотипа «Type». К таким абстракциям относят целые типы, символы, строки и перечисления.
Моделированиепримитивных типовпроизводитсяследующимобразом:
1.Моделируются сущность, абстрагируемая в виде типа (стереотип «Type») или перечисления (стереотип «Еnumeration»).
2.Если требуется задать связанный с типом диапазон значений, пользуются ограничениями.
45

Рис. 2.12 показывает, что такие сущности можно моделировать в UML как типы или перечисления, которые изображаются точно так же, как классы, но с явно указанным стереотипом. Сущности, подобные целым числам (представленные типом Unsigned), моделируются как типы, а с помощью ограничений можно явно указать диапазон принимаемых значений (range of….). Перечислимые типы (скажем, Boolean и Должность) разрешено моделировать как перечисления, допустимые значениия указываются как атрибуты.
Рис. 2.12. Моделирование примитивныхтипов
Такие языки, как Си C++, позволяют определить эквивалентные целые значения для перечислений. Подобное моделирование возможно и в UML, если указать для атрибута, обозначающего перечисление, константное начальное значение по умолчанию.
2.10. КЛАССИФИКАТОРЫ И ИХ СВОЙСТВА
Описание структурных свойств классов производится посредством атрибутов, поведенческих – посредством операций. Но атрибуты и операции могут иметь не только классы. Множество таких структурных сущностей обобщенно называется классификатором.
Классификатор (Classifier) – это механизм, описывающий структурные и поведенческие свойства. К числу классификаторов относятся классы, интерфейсы, типы данных, сигналы, компоненты, узлы, прецеденты и подсистемы.
46

Большинство перечисленных сущностей уже рассматривалось, остановимся на тех, определение которых не вводилось:
а) сигнал – спецификация асинхронного стимула, используемого для связи между экземплярами (стереотип класса);
б)подсистема – совокупность элементов, из которых отдельные составляют спецификацию поведения других элементов (стереотип пакета).
2.10.1. Видимость
Доступ к атрибутам и операциям регулируется через свойства видимости.
Вязыке UML используются стандартные для объектно ориентированных систем три уровня видимости:
1) public (открытый) – любой внешний классификатор, который «видит» данный, может пользоваться его открытыми свойствами. Обозначается знаком «+» (плюс) перед именем атрибута или операции;
2) protected (защищенный) – любой потомок данного классификатора может пользоваться его защищенными свойствами. Обозначается знаком
«#» (диез);
3) private (закрытый) – только данный классификатор может пользоваться закрытыми свойствами. Обозначается символом «–» (минус).
Вразвитых системах моделирования могут использоваться графические значки для определения видимости, например: закрытый – закрытый замок, открытый – открытый замок и т. д.
На рис. 2.13 показаны открытые, защищенные и закрытые атрибуты
иметоды для класса SortArray.
Рис. 2.13. Видимость атрибутов и операций
47

Отношения дружественности (Friendship) позволяют классификатору показывать другим свои закрытые детали (моделируется посредством стереотипной зависимости).
2.10.2. Область действия
Не менее важным свойством атрибутов и операций классификатора является область действия (Scope). Задавая область действия некоторого свойства, определяют, как оно будет проявлять себя в каждом экземпляре классификатора. ВUML определены два видаобластей действия:
1)instance (экземпляр) – у каждого экземпляра классификатора есть собственное значение данного свойства;
2)classifier (классификатор) – все экземпляры классификатора совместно используют общее значение данного свойства (статическая переменная).
На рис. 2.14 показано, что имя свойства, которое имеет область действия classifier, подчеркивается. Если подчеркивание отсутствует, предполагается область действия instance. На рис. 2.14 атрибут ID имеет область видимости – классификатор.
Рис. 2.14. Видимость
Обычно свойства классов имеют область действия экземпляра. Свойства с областью действия классификатора чаще всего применяются для описания служебных идентификаторов классов.
2.10.3. Абстрактные, корневые, листовые и полиморфные элементы
Отношения обобщения применяются для моделирования наследования свойств и операций классов. При разработке статического скелета системы желательно как можно шире использовать возможности наследования, позволяющего избежать многократного повторения описания одного и того
48
же. При этом, чтобы построить максимально связные иерархии, часто необходимо вводить дополнительные классы – носители общих свойств, которым возможно и не будут соответствовать реальные объекты. Например, на рис. 1.17 с целью выделения общих свойств, относящихся к описанию человека, использовался класс Персона, данные свойства наследовались классами Студент и Преподаватель. Непосредственно Класс Персона не имеет экземпляров, хотя их, естественноЮ могут иметь его потомки. Такие классы, не имеющие непосредственных экземпляров, называют абстрактными. Имя их пишется курсивом (наклонным шрифтом). Классы, которые могут иметь экземпляры, называют конкретными.
Изображая иерархию наследования классов в UML, предполагают, что диаграмма является неполной, то есть на ней могут быть не указаны некоторые родительские и дочерние классы, а показана только часть иерархии. Чтобы явно отметить вершину иерархии – базовый класс, можно воспользоваться ограничением {root} – корень, чтобы отметить конечную вершину иерархии, используется ограничение {leaf} – лист. Естественно, у корневого класса не может быть предков, у листового – потомков.
Аналогичные свойства могут иметь атрибуты и операции. Так, абстрактная операция декларируется в некотором не листовом классе иерархии, а ее конкретное воплощение определяется в потомках данного класса. Их удобно использовать, чтобы обозначить некоторое действие, которое у различных потомков данного класса будет реализовано поразному. Абстрактные операции и атрибуты записываются наклонным шрифтом. Абстрактные операции соответствуют виртуальным операциям в Си.
Как правило, операции являются полиморфными. Это значит, что в различных местах иерархии классов можно определять операции с одинаковыми сигнатурами и операции могут переопределяться в потомках.
Используя ограничение {leaf}, можно определить листовые атрибуты и операции, которые не могут переопределяться в потомках.
На рис. 2.15 представлена иерархия специфических типов данных, позволяющих хранить массивы и строки.
49

Рис. 2.15. Иерархия классов
Корневой класс BaseStruct является абстрактным, имеет атрибутклассификатор, не переопределяемый в потомках, и две абстрактные операции, которые, наоборот, получат конкретное воплощение только в потомках fArray и cString. Класс fSortArray указан как листовой и не может иметь потомков. Корневой класс BaseStruct не может иметь предков.
2.10.4. Кратность
Разумно предположить, что у конкретного класса может существовать любое количество его экземпляров. Однако в некоторых случаях число экземпляров класса необходимо ограничить. В UML используются различные разновидности кратности:
‒ нет ни одного экземпляра – такой класс является служебным (Utility), содержащим только атрибуты и операции с областью действия класса;
50