Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Uml Book (Rus).doc
Скачиваний:
15
Добавлен:
11.08.2019
Размер:
58.74 Mб
Скачать

Ассоциации

Ассоциацией (Association) называется структурное отношение, показывающее, что объекты одной сущности связаны с объектами другой (см. главу 5). Так, класс Библиотека может быть связан ассоциацией «один ко многим» с классом Книга, показывая, что все экземпляры второго принадлежат одному экземпляру первого. Если имеется объект класса Книга, можно всегда найти содержащую его Биб­лиотеку, а зная Библиотеку, в ней можно осуществить навигацию ко всем Кни­гам. Графически ассоциация изображается в виде линии, связывающей класс сам с собой или с другими классами. Используйте ассоциации, если хотите показать структурные отношения.

К ассоциациям применимы четыре базовых дополнения: имя, роль и кратность на каждом конце и агрегирование. В распоряжении опытных пользователей име­ется ряд других свойств для моделирования тонких деталей, например навигация, квалификация и различные виды агрегирования.

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

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

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

определены в главе 9). Например, как показано на рис. 10.4, между объектами UserGroup (группа пользователей) и User существует одна ассоциация, а дру­гая - между объектами User и Password. Зная пользователя, можно найти его пароль, но эта информация принадлежит пользователю и не должна быть доступна извне (если, конечно, объект User явно не даст доступ к объекту Password, возможно посредством открытой операции). Поэтому, как явствует из рисунка, можно осуществлять навигацию от объекта UserGroup к входящим в нее объек­там User и обратно, но из объекта UserGroup нельзя видеть объекты Password, принадлежащие отдельным объектам User.

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

Квалификаторы. Одной из наиболее распространенных идиом в контексте ас­социаций является задача поиска. Как, зная объект на одном конце ассоциации, можно определить объект или группу объектов на другом ее конце? Рассмотрим j для примера моделирование рабочего стола в мастерской, на котором сортируют­ся возвращенные изделия, подлежащие ремонту. Как видно из рис. 10.5, для этого нужно смоделировать ассоциацию между классами РабочийСтол и ВозвращенноеИзделие. Применительно к РабочемуСтолу определен jobID - идентифи­катор задания, связанный с каждым конкретным ВозвращеннымИзделием. В этом

смысле jobID - атрибут ассоциации (см. главы 4 и 9). Он не является свойством объекта ВозвращенноеИзделие, поскольку изделия ничего не знают ни о ремон­те ни о заданиях. Если известен объект РабочийСтол и значение jobID, то мож­но осуществить навигацию к нулю или одному объекту ВозвращенноеИзделие. В языке UML эта идиома моделируется с помощью квалификатора, являющегося атрибутом ассоциации, значения которого разбивают множество объектов на подмножества, связанные с объектом на другом конце ассоциации. Квалификатор изображается в виде маленького прямоугольника, присоединенного к одной из концевых точек ассоциации, внутри которого располагаются атрибуты квалифика­тора (см. рис. 10.5). Объект-источник вместе со значениями атрибутов квалифика­тора порождает один целевой объект (если кратность цели не больше единицы) или множество таких объектов (если кратность больше единицы).

Примечание Семантика квалификаторов нетривиальна, и существует ряд сложных примеров их использования. Однако чаще всего ситуации, в которых нужны Квалификаторы, довольно просты. Если на одном конце ассоциации вы можете поместить поисковую структуру данных (например, хэш-таблицу или В-дерево), то объявите индекс, по которому производится поиск, как квалификатор. Обычно кратность на исходном конце будет «много», а на целевом - 0.. 1.

Спецификатор интерфейса. Интерфейсом называется набор операций, кото­рые используются для спецификации услуг, предоставляемых классом или ком­понентом, причем один класс может реализовывать несколько интерфейсов (см. главу 11). Перечень всех реализуемых классом интерфейсов образует полную спе­цификацию поведения класса. Однако в контексте ассоциации с другим целевым классом исходный класс может не раскрывать все свои возможности. Так, в сло­варе системы управления человеческими ресурсами класс Person (Сотрудник) способен реализовывать несколько интерфейсов: IManager (Управляющий), lEmployee (Работник), lOfficer (Служащий) и т.д. Как видно из рис. 10.6, от­ношения между начальником и подчиненными можно моделировать с помощью ассоциации типа «один ко многим», явно пометив роли в ней (см. главу 4) как super visor (контролер) и worker (рабочий), В контексте этой ассоциации объект класса Person в роли supervisor предоставляет объектам worker только интерфейс Imanager; он же в роли worker предоставляет объекту supervisor лишь интерфейс lEmployee. На рисунке показано, что можно явно

описать тип роли с помощью синтаксиса rolename : iname, где iname - некото­рый интерфейс другого классификатора (см. главу 9).

Композиция. Агрегирование является простой концепцией с достаточно глубо­кой семантикой. Простое агрегирование - чисто концептуальное отношение, оно лишь позволяет отличить «целое» от «части» (см. главу 5), но не изменяет смысла навигации по ассоциации между целым и его частями и не накладывает никаких ограничений на соотношение времен жизни целого и частей.

Однако существует вариация простого агрегирования - композиция, которая добавляет к семантике агрегирования новые важные особенности (для моделиро­вания композиции используются атрибуты, см. главы 4 и 9). Композицией назы­вается форма агрегирования с четко выраженным отношением владения, причем время жизни частей и целого совпадают. Части с нефиксированной кратностью могут быть созданы уже после самого композита, но, будучи созданы, живут и умирают вместе с ним. Впрочем, части могут быть удалены явным образом еще до уничтожения композита.

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

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

Как показано на рис. 10.7, композиция яв­ляется просто частным случаем ассоциации и обозначается путем дополнения ассоциа­ции закрашенным ромбом на конце со сторо­ны «целого».

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

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

На языке UML такая ситуация моделируется с помощью класса-ассоциации (Association class) - элемента, сочетающего в себе свойства как ассоциации, так и класса. Это означает, что класс-ассоциацию можно считать или ассоциацией, имеющей свойства класса, или классом со свойствами ассоциации. Изображают его в виде класса, соединенного пунктирной линией с ассоциацией, как показано на рис. 10.8.

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

Ограничения. Рассмотренных выше простых и более развитых свойств отноше­ний ассоциации, как правило, бывает вполне достаточно. Однако на тот случай если вы хотите специфицировать смысловые нюансы, в языке UML предусмотре­но пять ограничений, применимых к отношениям ассоциации (механизмы расши­рения UML обсуждаются в главе 6, а определенные в UML стереотипы и ограни­чения - в «Приложении В»).

Прежде всего, можно указать, является ассоциация реальной или концептуальной:

  • implicit (неявный) - говорит о том, что данное отношение не показано явно (сделать вывод о его наличии можно только логическим путем), то есть является исключительно концептуальным. Например, если имеется ассоци­ация между двумя базовыми классами, то вы можете определить ту же са­мую ассоциацию и между их потомками (так как они наследуют отношения родительских классов). При этом данное отношение будет помечено словом implicit, поскольку оно не задано отдельно, а неявно вытекает из отноше­ния, которое существует между родительскими классами.

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

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

Наконец, три последних ограничения связаны с изменяемостью экземпляров ассоциации (перечисленные ниже характеристики изменяемости применимы также к атрибутам, см. главу 9):

  • changeable (изменяемый) - показывает, что можно добавлять, удалять и из­менять связи между объектами;

  • addOnly (только добавляемый) - говорит, что от объекта на противополож­ном конце ассоциации можно добавлять новые связи (см. главу 15);

  • frozen (замороженный) - означает, что связь, добавленная от объекта на противоположном конце ассоциации, не может быть впоследствии изменена или удалена.

Примечание Строго говоря, ordered, changeable, frozen и addOnly - это свойства концевой точки ассоциации. Однако изображаются они с помощью нотации ограничений.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]