7.4.1. Классы и объекты
Отношения объединяют сущности.
Между классом и объектами этого класса устанавливается отношение
«instantiate» (создать экземпляр). Это первый встречающийся нам при мер отношения. Книга «UML Reference Manual» [Rumbaugh 1] опреде ляет отношение как «связь между элементами модели». В UML суще ствует множество типов отношений, и со временем все они будут нами рассмотрены.
Отношение зависимости означает, что изменение сущности поставщика оказывает влияние на сущность клиент.
Отношение
«instantiate» между объектами и классами показано на рис. 7.6. Пунктирная линия со стрелкой обозначает отношение зависи мости, которому стереотип
«instantiate» придает особое значение. Как было показано в главе 1, все, что находится во французских кавычках
(«
…»), называется стереотипом. Стереотипы – один из трех механиз withdraw()
deposit()
Account number : String owner : String balance : double класс
«instantiate»
«instantiate»
«instantiate»
объекты ilasAccount:BankAccount number : "803"
owner : "Ila"
balance : 310.00
fabsAccount:BankAccount number : "802"
owner : "Fab"
balance : 1000.00
jimsAccount:BankAccount number : "801"
owner : "Jim"
balance : 300.00
Рис. 7.6. Отношение
«instantiate»
158Глава 7. Объекты и классы мов расширения в UML. Стереотип – это способ настройки элементов модели, способ создания вариантов с новой семантикой. В данном слу чае стереотип
«instantiate» превращает обычную зависимость в отноше ние конкретизации между классом и объектами этого класса.
«UML Reference Manual» [Rumbaugh 1] определяет зависимость как
«отношение между двумя элементами, при котором изменение одного элемента (поставщика) может влиять или поставлять информацию, не обходимую другому элементу (клиенту)». Из рис. 7.6 очевидно, что класс
Account должен быть поставщиком, потому что он определяет структуру всех объектов этого класса, а объекты – это клиенты.
7.4.2. Создание экземпляров классаСоздание экземпляров (instantiation) – это создание новых экземпля ров элементов модели. В данном случае создаются объекты классов.
Создаются
новые экземпляры классов.
При создании экземпляра класса создается новый объект. Класс ис пользуется как шаблон.
UML старается быть универсальным, поэтому создание экземпляров
применяется не только к классам и объектам, но и к другим элементам модели. Понятие создания экземпляров, по сути, представляет общий процесс создания конкретного экземпляра чего либо по шаблону.
В большинстве ОО языков есть специальные операции, называемые конструкторами, которые на самом деле принадлежат классу, а не объ ектам этого класса. Говорят, что область действия этих специальных операций – класс. Более подробно на области действия мы остановимся в разделе 7.6. Назначение операции конструктор – создание новых эк земпляров класса. Конструктор выделяет память для нового объекта,
присваивает ему уникальный идентификатор и задает исходные значе ния атрибутов. Он также настраивает все связи с другими объектами.
7.5. Нотация классов в UMLВизуальный синтаксис UML для класса очень богат. Чтобы синтаксис был управляемым, в UML существует понятие необязательных допол нений. Обязательной частью в визуальном синтаксисе является толь ко ячейка с именем класса. Все остальные ячейки и дополнения необя зательны. Однако для справки на рис. 7.7 показано все.
Показывайте только важные ячейки и дополнения.
Какие ячейки и дополнения будут включены в класс на диаграмме классов, зависит только от назначения диаграммы. Если интерес пред ставляют лишь отношения между различными классами, тогда может
7.5. Нотация классов в UML
159быть достаточно ячейки с именем. Если диаграмма призвана проиллю стрировать поведение классов, тогда, вероятно, в каждый класс будет добавлена ячейка с ключевыми операциями. С другой стороны, диа грамма может быть более «ориентированной на данные», например представлять проецирование классов в реляционные таблицы. В этом случае должны быть показаны ячейки имени и атрибутов, возможно,
и типы атрибутов. Необходимо стремиться использовать эту гибкость
UML и размещать на диаграмме классов именно такой объем информа ции, который необходим для четкого и лаконичного представления идеи.
В аналитических моделях обычно необходимо показывать только:
•имя класса;
•ключевые атрибуты;
•ключевые операции;
•стереотипы (если они приносят пользу делу).
Обычно
не показывают следующее:
•помеченные значения;
•параметры операций;
•видимость;
•исходные значения (если только они не значимы для дела).
В нескольких следующих подразделах будут более подробно рассмот рены ячейки имени, атрибутов и операций.
7.5.1. Ячейка имениХотя UML не определяет для классов никаких обязательных соглаше ний о присваивании имен, существует общепринятое соглашение.
number : String owner : String balance : double = 0.0
+create( theNumber : String, theOwner : String )
+deposit( amount : double )
+withdraw( amount : double )
+ getNumber() : String
+ getOwner() : String
+ getBalance() : double ячейка имени ячейка атрибутов ячейка операций дополнение видимости операция с областью действия – класс (подчеркнута)
исходное значение имя
класса стереотип помеченное значение«entity»
BankAccount
{ author = Jim,
status = tested }
Рис. 7.7. Нотация классов в UML 160Глава 7. Объекты и классы
•Имя класса записывается в стиле UpperCamelCase: имя и все слова,
его образующие, пишутся с заглавной буквы. Специальные симво лы, такие как знаки препинания, тире, подчеркивание, «&», «#»
и слэш,
никогда не используются. Для этого есть достаточное основа ние: эти символы применяются в таких языках, как HTML и XML,
и в операционных системах. Поэтому их применение в именах классов или именах любых других элементов модели может при вести к неожиданным последствиям при генерации из модели кода или документации HTML/XML.
Никогда не используйте аббревиатуры в именах классов, атрибутов или операций.
•Во что бы то ни стало необходимо избегать сокращений. Имена классов всегда должны отражать имена реальных сущностей
без со кращений. Например, имя
FlightSegment всегда более предпочти тельно, чем
FltSgmnt, DepositAccount предпочтительнее, чем DpstAccnt.
Опять же причина этому очень простая – аббревиатуры затрудняют чтение модели (и результирующего кода). Время, сэкономленное при наборе, не сравнимо со временем, необходимым для обслужи вания моделей или кода с сокращенными именами.
•Если есть специальные акронимы данной предметной области (на пример, CRM (Customer Relationship Management – управление взаи моотношениями с клиентами)), широко используемые и понятные
всем пользователям модели, они могут применяться. Однако необ ходимо помнить, что полное имя, если оно делает модель более по нятной, все равно предпочтительнее.
Классы представляют «сущности», поэтому их имена должны быть су ществительными или именной группой, например
Person (человек),
Money (деньги), BankAccount (банковский счет).
7.5.2. Ячейка атрибутовЕдинственной обязательной частью UML синтаксиса для атрибутов
(рис. 7.8) является имя атрибута. Имена атрибутов записываются в сти ле lowerCamelCase, т. е. начинаются со строчной буквы, а далее большие и малые буквы пишутся вперемежку. Обычно в качестве имен атрибу тов используются
имена существительные или именные группы, пото му что атрибуты указывают на некоторую «сущность», например ба ланс счета. Необходимо избегать специальных символов и сокращений.
видимость имя : тип [множественность] = начальноеЗначение обязателен
Рис. 7.8. UML синтаксис для атрибутов 7.5. Нотация классов в UML
161Необязательные части синтаксиса атрибутов рассматриваются в сле дующих нескольких разделах.
7.5.2.1. ВидимостьВидимость контролирует доступ к свойствам класса.
Дополнение видимости (visibility) (табл. 7.3) применяется к атрибу там и операциям класса. Оно также может применяться к именам ро лей в отношениях (глава 9). При анализе диаграммы обычно не загро мождают видимостями, поскольку, по сути, это дополнение дает опи сание того «как», а не «что».
Таблица 7.3Языки реализации могут по разному интерпретировать все типы ви димости UML, кроме public (открытый). Это важно. Фактически язы ки программирования могут определять дополнительные типы види мости, которые UML не поддерживает по умолчанию. Обычно это не проблема. Самые распространенные ОО языки программирования, та кие как С++ и Java, и даже популярные полуОО языки, например Vi sual Basic, замечательно справляются с видимостями public, private
(закрытый), protected (защищенный) и package (пакетный), по край ней мере, в первом приближении.
Давайте более подробно рассмотрим два ОО языка. В табл. 7.4 прово дится сравнение семантики видимости UML и языков программирова ния Java и C#.
Видимость зависит от языка реализации и может стать очень слож ной. Какой именно тип видимости используется, является конкрет
Дополнение ВидимостьСемантика+
Public (Открытый)
Любой элемент, который имеет дос туп к классу,
имеет доступ к любой из его возможностей, видимость ко торой public.
–
Private (Закрытый)
Только операции класса имеют дос туп к возможностям, имеющим ви димость private.
#
Protected (Защищенный)
Только операции класса или потомка класса имеют доступ к возможност ям, имеющим видимость protected.
Package (Пакетный)
Любой элемент, находящийся в од ном пакете с классом или во вложен ном подпакете, имеет доступ ко всем его возможностям, видимость кото рых package.
162
Глава 7. Объекты и классы ным решением реализации, которое обычно принимается программи стом, а не аналитиком/проектировщиком. Для общего моделирования стандартных UML определений public, private, protected и package вполне достаточно. Рекомендуем ограничиться ими.
Таблица 7.4
Видимость
Семантика UML
Семантика Java
Семантика C#
public
Любой элемент,
который имеет дос туп к классу, имеет доступ к любой из его возможностей,
видимость кото рой public.
Аналогично UML.
Аналогично
UML.
private
Только операции класса имеют дос туп к возможнос тям, имеющим ви димость private.
Аналогично UML.
Аналогично
UML.
protected
Только операции класса или потомка класса имеют дос туп к возможнос тям, имеющим ви димость protected.
Аналогично UML, но доступ также имеют все классы, находя щиеся в том же паке те Java, что и опреде ляющий класс.
Аналогично
UML.
package
Любой элемент,
находящийся в од ном пакете с клас сом или во вложен ном подпакете,
имеет доступ ко всем его возможно стям, видимость которых package.
Применяемая по умолчанию види мость в Java: вложен ным классам вложен ных подпакетов дос туп к элементам ро дительского пакета автоматически не предоставляется.
–
private protected
(закрытый защи щенный)
–
Аналогично protect ed в UML.
–
internal
(внутренний)
–
–
Доступны любо му элементу той же программы.
protected internal
(защищенный внутренний)
–
–
Сочетает семан тику protected и internal, при менимо только к атрибутам.
7.5. Нотация классов в UML
1637.5.2.2. ТипТипом атрибута может быть другой класс или примитивный тип.
Типом атрибута может быть другой класс или примитивный тип.
Спецификация UML определяет четыре примитивных типа, использу емых в самой спецификации UML. Их можно применять в аналитиче ских моделях, если необходимо сохранить платформонезависимость.
Эти типы приведены в табл. 7.5.
Таблица 7.5Объектный язык ограничений (Object Constraint Language, OCL) –
формальный язык для выражения ограничений в UML моделях. Под робно OCL обсуждается в главе 25. OCL определяет стандартные опера ции для простых типов UML (кроме
UnlimitedNatural) и вводит новый тип
Real.
Если модель ориентирована на определенный язык программирова ния, например Java или C#, можно использовать простые типы этого языка. Однако тогда модель будет привязана к этому конкретному языку программирования.
Иногда необходимо ввести в UML модель ряд примитивных типов, ис пользуемых в остальных классах в качестве атрибутов и типов парамет ров операций. Добавить простой тип можно, создав класс с таким же именем и стереотипом «
primitive». У такого класса обычно нет атрибутов или операций, поскольку он просто выступает в роли структурного ну ля для простого типа, добавляя его имя в пространство имен модели.
7.5.2.3. КратностьКратность широко используется при проектировании. Она также мо жет быть полезной в аналитических моделях, поскольку с ее помощью можно лаконично
обозначить определенные бизнес ограничения, ка сающиеся «количества сущностей», участвующих в отношении.
Простой типСемантикаUMLInteger
Целое число.
UnlimitedNatural
Целое число >= 0.
Бесконечность обозначается как
*.
Boolean
Может принимать значения true или false.
String
Последовательность символов.
Строковые литералы заключаются в кавычки,
например "Джим".
OCLReal
Число с плавающей точкой.
164
Глава 7. Объекты и классы
Кратность позволяет моделировать коллекции сущностей или неопре деленные значения.
Применяя выражение кратности к атрибуту, можно моделировать две совершенно разные сущности (рис. 7.9).
•
Коллекции – если выражение кратности определяет целое число больше нуля, значит, задается коллекция типа. Например, выра жение colors : Color[7] моделирует атрибут, являющийся коллекцией из семи объектов
Color (цвет), которые можно использовать для мо делирования цветов радуги.
•
Неопределенные значения – большинство языков различают атри бут, содержащий пустой, или неинициализированный, объект (на пример, пустая строка,
""), и атрибут, указывающий в «никуда»,
т. е. ссылку на неопределенный (
null) объект. Когда атрибут ссыла ется на null, это означает, что объект, на который он указывает, еще не был создан или уже прекратил существование. При детальном проектировании иногда важно указать, что null является возмож ным значением атрибута. Смоделировать это можно с помощью специального выражения кратности
[0..1]. Рассмотрим пример ат рибута emailAddress (электронныйАдрес) (рис. 7.9): если значение ат рибута –
"" (пустая строка), то это можно понять так, что адрес электронной почты был запрошен, но не был предоставлен. С дру гой стороны, если атрибут emailAddress указывает на null, можно ска зать, что адрес электронной почты еще не был запрошен и, следова тельно, его значение неизвестно. Если проводятся такие разграни чения, исключительно важно указывать в документации emailAdd ress точную семантику "" и null. Как видите, это довольно тонкие проектные рассуждения, но они могут быть важны и полезны.
На рис. 7.9 приведено несколько примеров синтаксиса кратности.
7.5.2.4. Начальное значение
Начальное значение позволяет задавать значение атрибута в момент создания объекта.
выражение кратности имя состоит из двух или более строк адрес состоит из трех строк emailAddress состоит из одной строки или имеет значение null
PersonDetails
–name : String [2..*]
–address : String [3]
–emailAddress : String [0..1]
Рис. 7.9. Примеры синтаксиса кратности
7.5. Нотация классов в UML
165Начальное значение (
initialValue) позволяет задавать значение, прини маемое атрибутом при создании экземпляра класса (т. е. объекта). Это
значение называют начальным, потому что оно присваивается атрибу ту в момент создания объекта. Использование начальных значений везде, где есть возможность, является хорошим стилем программиро вания. Это гарантирует, что состояние создаваемых объектов класса всегда действительное (valid) и они пригодны к использованию.
В анализе начальные значения используются только тогда, когда они могут выразить или обозначить важное бизнес ограничение. Подобная ситуация встречается довольно редко.
7.5.2.5. Расширенный синтаксис атрибутаПодобно любому другому элементу моделирования UML, семантику атрибутов можно расширять, указывая перед ними стереотипы или задавая после них помеченные значения, например
«стереотип» атрибут { метка1 = значение1, метка2 = значение2, … }
В помеченных значениях можно хранить любую информацию. Напри мер, иногда они используются для хранения информации о версии,
как показано здесь:
address { addedBy="Jim Arlow", dateAdded="20MAR2004" }
В этом примере записано, что Джим Арлоу (Jim Arlow) добавил атри бут address (адрес) в некоторый класс 20 марта 2004 года.
7.5.3. Ячейка операцийОперации – это функции, закрепленные за определенным классом.
По сути, они обладают всеми характеристиками функций:
•имя
•список параметров
•возвращаемый тип
Сигнатура операции включает имя, тип всех ее параметров и возвращае мый тип.
Сочетание имени операции, типов всех ее параметров и возвращаемого типа образует сигнатуру операции (рис. 7.10). Сигнатура каждой опе видимость имя( направление имяПараметра : типПараметра = значениеПоУмолчанию, ... ) : возвращаемыйТип сигнатура операции список параметров
Рис. 7.10. Сигнатура операции 166Глава 7. Объекты и классы рации класса должна быть уникальной, поскольку именно сигнатура идентифицирует операцию. Когда объект получает сообщение, его сиг натура сравнивается с сигнатурами операций, определенных в классе объекта. Если обнаруживается соответствие, инициируется запраши ваемая операция объекта.
Разные языки
программирования немного по разному определяют,
что должно составлять сигнатуру операции. Например, в С++ и Java возвращаемый тип игнорируется. Это означает, что две операции клас са, отличающиеся только возвращаемыми типами, будут рассматри ваться как одна и та же операция и генерировать ошибку компилято ра/интерпретатора. В Smalltalk, языке со слабым контролем типов,
все параметры и возвращаемый тип имеют тип
Object, и поэтому сигна туру составляет только имя операции.
Имена операций записываются в стиле lowerCamelCase. В качестве имен используются глаголы или глагольные группы. Необходимо из бегать применения в именах специальных символом и сокращений.
Каждый параметр операции имеет форму, показанную на рис. 7.11.
В операции может быть от нуля до нескольких параметров.
Имена параметров записываются в стиле lowerCamelCase и обычно яв ляются именем существительным или именной группой, поскольку обозначают что то, что передается в операцию. Каждый параметр име ет определенный тип, который является классом или примитивным типом.
Направление и применяемое по умолчанию значение параметра рас сматриваются в следующих двух разделах.