В библиотеку

Объектно-ориентированный анализ и проектирование с примерами приложений на С++

5.2. Диаграммы классов. Существенное: классы и отношения между ними


Г. Буч
Источник: Объектно-ориентированный анализ и проектирование с примерами приложений на С++, 2-е изд./ Пер. с англ. - М.:"Издательство Бином", СПб.: "Невский диалект", 2000 - с.176-179.





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

Классы. На рис. 1 показано обозначение для представления класса на диаграмме. Класс обычно представляют аморфным объектом, вроде облака.

Каждый класс должен иметь имя; если имя слишком длинно, его можно сократить или увеличить сам значок на диаграмме. Имя каждого класса должно быть уникально в содержащей его категории. Для некоторых языков, в особенности для C++ и Smalltalk, мы должны требовать, чтобы каждый класс имел имя, уникальное в системе. На некоторых значках классов полезно перечислять несколько атрибутов и операций класса. «На некоторых», потому что для большинства тривиальных классов это хлопотно и не нужно. Атрибуты и операции на диаграмме представляют прообраз полной спецификации класса, в которой объявляются все его элементы. Если мы хотим увидеть на диаграмме больше атрибутов класса, мы можем увеличить значок; если мы совсем не хотим их видеть — мы удаляем разделяющую черту и пишем только имя класса.

Рисунок 1 - Значок класса

Атрибут обозначает часть составного объекта, или агрегата. Атрибуты используются в анализе и проектировании для выражения отдельных свойств класса. Мы используем следующий не зависящий от языка синтаксис, в котором атрибут может обозначаться именем или классом, или и тем и другим, и, возможно, иметь значение по умолчанию:

• А только имя атрибута;

• : с только класс;

• А:с имя и класс;

• А: с=Е имя, класс и значение по умолчанию.

Имя атрибута должно быть недвусмысленно в контексте класса.

Операция — это услуга, предоставляемая классом. Операции обычно изображаются внутри значка класса только своим именем. Чтобы отличать их от атрибутов, к их именам добавляются скобки. Иногда полезно указать полную сигнатуру операции:

• N() только имя операции;

• RN(Аргументы) класс возвращаемого значения (R), имя и формальные параметры (если есть).

Имена операций должны пониматься в контексте класса однозначно в соответствии с правилами перегрузки операций выбранного языка реализации.

Общий принцип системы обозначений: синтаксис элементов, таких, как атрибуты и операции, может быть приспособлен к синтаксису выбранного языка программирования. Например, на C++ мы можем объявить некоторые атрибуты как статические, или некоторые операции как виртуальные или чисто виртуальные; в CLOS мы можем пометить операцию как метод: around. В любом случае мы пользуемся спецификой синтаксиса данного языка, чтобы обозначить детали. Абстрактный класс — это класс, который не может иметь экземпляров. Так как абстрактные классы очень важны для проектирования хорошей структуры классов, мы вводим для них специальный значок треугольной формы с буквой А в середине, помещаемый внутрь значка класса (рис. 2). Общий принцип: украшения представляют вторичную информацию о некой сущности в системе. Все подобные типы украшений имеют такой же вид вложенного треугольника.

Отношения между классами. Классы редко бывают изолированы; напротив они вступают в отношения друг с другом. Виды отношений показаны на рис. 3: ассоциация, наследование, агрегация (has) и использование; При изображении конкретной связи ей можно сопоставить текстовую пометку, документирующую имя этой связи или подсказывающую ее роль. Имя связи не обязано быть глобальным, но должно быть уникально в своем контексте.

Значок ассоциации соединяет два класса и означает наличие семантической связи между ними. Ассоциации часто отмечаются существительными, например Employment (место работы), описывающими природу связи. Класс может иметь ассоциацию с самим собой (так называемая рефлексивная ассоциация). Одна пара классов может иметь более одной ассоциативной связи. Возле значка ассоциации вы можете указать ее мощность, используя синтаксис следующих примеров:

• 1 В точности одна связь

• N Неограниченное число (0 или больше)

• 0..N Ноль или больше

• 1.. N Одна или больше

• 0.. 1 Ноль или одна

• 3.. 7 Указанный интервал

• 1.. 3, 7 Указанный интервал или точное число

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

Рисунок 2 - Значок абстрактного класса

Рисунок 3 - Значки отношений между классами

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

Значок наследования, представляющего отношение «общее/частное», выглядит как значок ассоциации со стрелкой, которая указывает от подкласса к суперклассу. В соответствии с правилами выбранного языка реализации, подкласс наследует структуру и поведение своего суперкласса. Класс может иметь один (одиночное наследование), или несколько (множественное наследование) суперклассов. Конфликты имен между суперклассами разрешаются в соответствии с правилами выбранного языка. Как правило, циклы в наследовании запрещаются. К наследованию значок мощности не приписывается.

Значок агрегации обозначает отношение «целое/часть» (связь «has») и получается из значка ассоциации добавлением закрашенного кружка на конце, обозначающем агрегат. Экземпляры класса на другом конце стрелки будут в каком-то смысле частями экземпляров класса-агрегата. Разрешается рефлексивная и циклическая агрегация. Агрегация не требует обязательного физического включения части в целое.

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