Шаг 96.
Унифицированный язык моделирования UML.
Базовые дополнения к ассоциациям в UML

    На этом шаге рассмотрим базовые дополнения к ассоциациям в UML.

    Ассоциация – это структурная связь, показывающая, что объекты одной сущности соединены с объектами другой. Например, класс Library (Библиотека) может иметь ассоциацию "один-ко-многим" с классом Book (Книга), сообщая таким образом, что каждый экземпляр Book принадлежит одному экземпляру Library. Более того, вы можете найти библиотеку, где содержится конкретная книга, а в рамках одной библиотеки можете осуществить навигацию по всем ее книгам. Ассоциация изображается сплошной линией, соединяющей разные классы или же один – сам с собой. Используется, когда необходимо показать структурные связи.

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

    Навигация (navigation). Имея простую, без дополнений, ассоциацию между двумя классами (наподобие Book и Library в вышерассмотренном примере), вы можете осуществлять навигацию от объектов одного вида к объектам другого. Если только не указано иное, навигация по ассоциации двунаправлена. Иногда требуется ограничить ее лишь одним направлением. Например, при моделировании служб операционной системы (см. рис. 1) вы столкнетесь с ассоциацией между объектами User (Пользователь) и Password (Пароль).


Рис.1. Навигация

    Для данного объекта User понадобится искать соответствующий ему объект Password, но по объекту Password нет смысла находить соответствующий объект User. Вы можете явно задать направление навигации, снабдив ассоциацию дополнением в виде стрелки, указывающей в нужную сторону.

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

    Видимость (visibility). При наличии ассоциации между двумя классами объекты одного класса могут "видеть" объекты другого и допускать навигацию к ним, если только она не ограничена явным образом. Однако иногда необходимо ограничить видимость одних объектов по отношению к другим в пределах ассоциации. В примере на рис. 2 ассоциации установлены между UserGroup (ГруппаПользователей) и User (Пользователь), а также между User и Password (Пароль).


Рис.2. Видимость

    Имея объект User, можно идентифицировать соответствующие ему объекты Password. Однако Password является закрытым по отношению к User и не может быть доступен извне (конечно, если только пользователь не открывает доступ к паролю, – возможно, посредством какой-то открытой операции). Таким образом, по рисунку видно, что, имея объект UserGroup, вы можете перейти к его объектам User и наоборот, но не можете увидеть объекты Password, принадлежащие User, потому что они закрыты по отношению к User.

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

    Квалификация (qualification). Применительно к ассоциациям одна из наиболее часто используемых идиом моделирования – проблема поиска (lookup). Как, имея объект на одном конце ассоциации, идентифицировать один или множество объектов на другом ее конце? Рассмотрим в качестве примера моделирование рабочего стола в мастерской, на котором сортируются бракованные изделия. Как показано на рис. 3, вы должны смоделировать ассоциацию между двумя классами: WorkDesk (РабочийСтол) и ReturnedItem (ВозвращенноеИзделие).


Рис.3. Квалификация

    Для WorkDesk вам понадобится jobId – идентификатор определенного ReturnedItem. В этом смысле jobId – атрибут ассоциации. Он не является свойством ReturnedItem, поскольку сами изделия не несут в себе представления о ремонте. Поэтому, имея в наличии объект WorkDesk и определенное значение jobId, вы можете осуществить навигацию к нулю или одному объекту ReturnedItem. В UML данную идиому следует моделировать с помощью квалификаторов (qualifiers), которые являются атрибутами ассоциаций, значение которых идентифицирует подмножество объектов (чаще – один объект), связанных с другим объектом по ассоциации. Квалификатор изображается в виде маленького прямоугольника, присоединенного к концу ассоциации; в этот прямоугольник помещены атрибуты, как показано на рис. 3. Исходный объект вместе со значениями атрибутов квалификатора порождает целевой объект, если множественность целевого объекта равна единице, или же набор целевых объектов, если множественность более единицы.

    Композиция (composition). Агрегация представляет собой простую концепцию с довольно глубокой семантикой. Простая агрегация исключительно концептуальна и не заявляет ничего помимо отличия целого от части. Она не изменяет смысла навигации по ассоциации между целым и его частями и ничего не говорит о жизненном цикле связи целого с его частями.

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

    Это означает, что в композитной агрегации объект может быть одновременно частью только одного композита. Например, при моделировании оконной системы объект Frame (Рамка) принадлежит только одному объекту – Window (Окно). Этот вариант отличается от простой агрегации, допускающей принадлежность части нескольким целым. Так, в модели дома Wall (Стена) может быть частью одного или нескольких объектов Room (Комната).

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

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


Рис.4. Композиция

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

    Ассоциации-классы (association class). Ассоциация, связывающая два класса, сама по себе может обладать некоторыми свойствами. Например, на рис. 5 в связи "работодатель/работник" между классами Company (Компания) и Person (Человек) присутствует элемент Job (Должность) – свойство ассоциации, описывающее должность работника в компании и соединяющее каждую пару объектов Company и Person.


Рис.5. Ассоциации-классы

    Было бы неверно моделировать эту ситуацию ассоциациями Company с Job и Job с Person, поскольку при этом не определяется конкретный экземпляр Job, связывающий друг с другом классы Company и Person.

    В UML такой случай описывается ассоциацией-классом – элементом, который одновременно имеет свойства класса и ассоциации. Его можно рассматривать двояко: как ассоциацию, которая несет в себе свойства класса, или же как класс, наделенный свойствами ассоциации. Изображается он символом класса, соединенным пунктирной линией с линией ассоциации (см. рис. 5).

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

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

    Во-первых, вы можете показать, что объекты на одном конце ассоциации (с множественностью больше единицы) упорядочены или не упорядочены:

  1. ordered – сообщает, что набор объектов на конце ассоциации должен быть явно упорядочен.

    Например, в ассоциации User/Password объекты Password, ассоциированные с User, могут сохраняться в обратном порядке (то есть первым идет последний использованный пароль), и, соответственно, ассоциация может быть помечена как ordered. Если это ключевое слово отсутствует, то объекты не упорядочены.

    Во-вторых, вы можете подчеркнуть, что объекты на одном конце ассоциации должны быть уникальными (то есть формировать набор) или же не должны быть таковыми (то есть формировать множество с повторяющимися элементами – bag):

  1. set – объекты уникальны, без дубликатов;
  2. bag – объекты не уникальны, допускаются дубликаты;
  3. ordered set – объекты уникальны и упорядочены;
  4. list или sequence – объекты упорядочены, могут быть дубликаты.

    И наконец, есть ограничение изменяемости экземпляров ассоциации:

  1. readonly – ссылка, однажды установленная от объекта на противоположном конце ассоциации, не может быть модифицирована или удалена. По умолчанию при отсутствии этого ограничения допускается изменяемость ассоциации.

    По сути, ordered и readonly – это свойства конца ассоциации. Однако они изображаются в нотации ограничений.

    На следующем шаге рассмотрим понятие реализации в UML.




Предыдущий шаг Содержание Следующий шаг