Создание диаграммы сотрудничества

Рекомендуемое содержание пункта «Создание диаграммы сотрудничества». В этом пункте пояснительной записки приводится и описывается последовательность действий по созданию диаграммы сотрудничества для выбранного прецедента информационной подсистемы (см. лабораторное занятие «Создание диаграммы сотрудничества (Collaborationdiagram)»).

Кооперативные диаграммы являются вторым видом диаграмм взаимодействия.

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

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

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

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

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.6 – Кооперативная диаграмма, описывающая, как клиент снимает деньги со счета

Создание диаграммы классов

Рекомендуемое содержание пятого раздела пояснительной записки «Создание диаграммы классов». В этом пункте пояснительной записки приводится и описывается диаграмма классов для выбранного прецедента информационной подсистемы (см. лабораторное занятие «Создание диаграммы классов»).

Диаграмма классов определяет типы классов системы и раз­личного рода статические связи, которые существуют между ними. На диаграммах классов изображаются также атрибуты классов, операции классов и ограничения, которые накладыва­ются на связи между классами. Диаграмма классов для варианта использования «Снять деньги со счета» представлена на рисунке 2.7.

На этой диаграмме классов показаны связи между классами, реализующими вариант использования «Снять деньги со счета». В этом процессе задействованы четыре класса: CardReader (уст­ройство для чтения карточек), Account (счет), ATMScreen (экран ATM) и CashDispenser (кассовый аппарат). Каждый класс на диаграмме выглядит в виде прямоугольника, разделенного на три части. В первой содержится имя класса, во второй - его атрибу­ты. В последней части содержатся операции класса, отражающие его поведение (действия, выполняемые классом).

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.7 –Диаграмма классов для варианта использования

«Снять деньги со счета»

Связывающие классы линии отражают взаимодействие между классами. Так, класс Account связан с классом ATMScreen, пото­му что они непосредственно сообщаются и взаимодействуют друг с другом. Класс CardReader не связан с классом CashDispenser, поскольку они не сообщаются друг с другом непосредственно.

Стереотипы классов. Стереотипы – это механизм, позволяющий разделять классы на категории. В языке UML основными стереотипами являются: Boundary (граница), Entity (сущность) и Control (управление).

Граничные классы(boundaryclasses) – это классы, которые расположены на границе системы и окружающей среды. Они включают все формы, отчеты, интерфейсы с аппаратурой (такой, как принтеры или сканеры) и интерфейсы с другими системами.

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

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

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

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

Помимо упомянутых выше стереотипов можно создавать и свои собственные.

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

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

Механизм пакетов применим к любым элементам модели, а не только к классам. Если для группировки классов не приме­нять некоторые эвристики, то она становится весьма произволь­ной. Одна из них, которая в основном используется в UML, – это зависимость. Зависимость между двумя пакетами существует в том случае, если между любыми двумя классами в пакетах суще­ствует любая зависимость. Таким образом, диаграмма пакетов(рисунок 2.8) представляет собой диаграмму, содержащую пакеты классов и зависимости между ними. Строго говоря, пакеты и за­висимости являются элементами диаграммы классов, т. е. диаг­рамма пакетов – это форма диаграммы классов.

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.8 – Диаграмма пакетов

Зависимость между двумя элементами имеет место в том слу­чае, если изменения в определении одного элемента могут повлечь за собой изменения в другом. Что касается классов, то причины для зависимостей могут быть самыми разными: один класс посы­лает сообщение другому; один класс включает часть данных дру­гого класса; один класс использует другой в качестве параметра операции.

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

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

Атрибуты. Атрибут – это элемент информации, связанный с классом. Например, у класса Company (Компания) могут быть атрибуты Name (Название), Address (Адрес) и NumberOfEmployees (Число служащих).

Атрибуты содержатся внутри класса, поэтому они скрыты от других классов. В связи с этим иногда требуется указать, какие классы имеют право читать и изменять атрибуты. Это свойство называется видимостью атрибута (attributevisibility).

У атрибута можно определить четыре возможных значения этого параметра. Рассмотрим каждый из них в контексте приме­ра (рисунок 1.9). Пусть у нас имеется класс Employee с атрибутом Address и класс Company. Возможны следующие спецификаторы доступа к атрибутам и операциям класса:

- public (общий, открытый).Это значение видимости пред­полагает, что атрибут будет виден всеми остальными классами. Любой класс может просмотреть или изменить значение атрибу­та. В таком случае класс Company может изменить значение ат­рибута Address класса Employee. В соответствии с нотацией UML общему атрибуту предшествует знак « Создание диаграммы сотрудничества - student2.ru ».

- private (закрытый, секретный).Соответствующий атрибут не виден никаким другим классам. Класс Employee будет знать значение атрибута Address и сможет изменять его, но класс Company не сможет его ни увидеть, ни редактировать. Если это понадобится, он должен попросить класс Employee просмотреть или изменить значение этого атрибута, что обычно делается с помощью общих операций. Закрытый атрибут обозначается зна­ком « Создание диаграммы сотрудничества - student2.ru » в соответствии с нотацией UML.

- protected (защищенный).Такой атрибут доступен только самому классу и его потомкам. Допустим, что у нас имеются два типа сотрудников - с почасовой оплатой и на окладе. Таким образом, мы получаем два других класса HourlyEmp и SalariedEmp, являющихся потомками класса Employee. Защищенный атрибут Address можно просмотреть или изменить из классов Employee, HourlyEmp и SalariedEmp, но не из класса Company. Нотация UML для защищенного атрибута - это знак « Создание диаграммы сотрудничества - student2.ru ».

- packageorImplementation (пакетный).Предполагает, что данный атрибут является общим, но только в пределах его паке­та. Допустим, что атрибут Address имеет пакетную видимость. В таком случае он может быть изменен из класса Company, только если этот класс находится в том же пакете. Этот тип видимости не обозначается никаким специальным значком.

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

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.9 – Спецификаторы доступа к атрибутам и операциям класса

Операции. Операции реализуют связанное с классом поведение. Опера­ция включает три части – имя, параметры и тип возвращаемого значения. Параметры – это аргументы, получаемые операцией «на входе». Тип возвращаемого значения относится к результату дей­ствия операции.

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

В языке UML операции имеют следующую нотацию:

Имя Операции (аргумент1 : тип данных аргумента1, аргумент2: тип данных аргумента2,...) : тип возвращаемого значения;

Существует четыре различных типа операций:

- операции реализации(implementeroperations) реализуют не­которые бизнес-функции. Такие операции можно найти, иссле­дуя диаграммы взаимодействия. Диаграммы этого типа фокусируются на бизнес-функциях, и каждое сообщение диаграммы, ско­рее всего, можно соотнести соперацией реализации. Каждая операция реализации должна быть легко прослежи­ваема до соответствующего требования. Это достигается на раз­личных этапах моделирования. Операция выводится из сообще­ния на диаграмме взаимодействия, сообщения исходят из под­робного описания потока событий, который создается на основе варианта использования, а последний - на основе требований. Возможность проследить всю эту цепочку позволяет гарантиро­вать, что каждое требование будет реализовано в коде, а каждый фрагмент кода реализует какое-то требование;

- операции управления(manageroperations) управляют созданием и уничтожением объектов. В эту категорию попадают конст­рукторы и деструкторы классов;

- операции доступа(accessoperations) существуют для того, чтобы просматривать или изменять значения атрибутов других классов. Пусть, например, у нас имеется атрибут Salary класса Employee. Мы не хотим, чтобы все остальные классы могли изменять этот ат­рибут. Вместо этого к классу Employee мы добавляем две операции доступа – GetSalary и SetSalary. К первой из них, являющейся об­щей, могут обращаться и другие классы. Она просто получает зна­чение атрибута Salary и возвращает его вызвавшему ее классу. Опе­рация SetSalary также является общей, она помогает вызвавшему ее классу установить новое значение атрибута Salary. Эта операция может содержать любые правила и условия проверки, которые не­обходимо выполнить, чтобы зарплата могла быть изменена. Такой подход дает возможность безопасно инкапсулировать атрибуты внутри класса, защитив их от других классов, но все же позволяет осуществить к ним контролируемый доступ. Создание операций Get и Set (получения и изменения значения) для каждо­го атрибута класса является стандартом;

- вспомогательные операции(helperoperations) – это такие опе­рации класса, которые необходимы ему для выполнения его от­ветственностей, но о которых другие классы не должны ничего знать. Это закрытые и защищенные операции класса.

Чтобы идентифицировать операции, выполните следующие действия:

- изучите диаграммы последовательности и кооперативные диаграммы. Большая часть сообщений на этих диаграммах является операциями реализации. Рефлексивные сообщения будут вспомогательными операциями.

- рассмотрите управляющие операции. Может потребовать­ся добавить конструкторы и деструкторы.

- рассмотрите операции доступа. Для каждого атрибута клас­са, с которым должны будут работать другие классы, надо со­здать операции Get и Set.

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

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

Ассоциации(association) – это семантическая связь между клас­сами. Ее рисуют на диаграмме классов в виде обыкновенной ли­нии (рисунке 2.10).

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.10 –Ассоциация

Ассоциации могут быть двунаправленными, как в примере, или однонаправленными. На языке UML двунаправленные ассо­циации рисуют в виде простой линии без стрелок (или со стрелка­ми с обеих ее сторон). На однонаправленной ассоциации изобра­жают только одну стрелку, показывающую ее направление.

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

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

Зависимости(dependency) также отражают связь между клас­сами, но они всегда однонаправлены и показывают, что один класс зависит от определений, сделанных в другом. Зависимости изображают в виде стрелки, проведенной пунктирной линией (рисунке 2.11).

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.11 –Зависимость

При генерации кода для этих классов к ним не будут добав­ляться новые атрибуты. Однако будут созданы специфические для языка операторы, необходимые для поддержки связи. Например, на языке C++ в код войдут необходимые операторы #include.

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

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.12 –Агрегация

В дополнение к простой агрегации UML вводит более силь­ную разновидность агрегации, называемую композицией. Соглас­но композиции объект-часть может принадлежать только един­ственному целому, и, кроме того, зачастую жизненный цикл час­тей совпадает с циклом целого: они живут и умирают вместе с ним. Любое удаление целого распространяется на его части.

Такое каскадное удаление нередко рассматривается как часть определения агрегации, однако оно всегда подразумевается в том случае, когда множественность роли составляет 1.. 1; например, если необходимо удалить Клиента, то это удаление должно распрост­раниться и на Заказы (и, в свою очередь, на Строки_заказа).

Обобщения(generalization) показывают связи наследования между двумя классами. Большинство объектно-ориентированных языков непосредственно поддерживают концепцию наследова­ния. Она позволяет одному классу наследовать все атрибуты, операции и связи другого. На языке UML связи наследования называют обобщениями и изображают в виде стрелок от класса-потомка к классу-предку (рисунок 2.13).

Помимо наследуемых атрибутов, операций и связей каждый подкласс, как правило, имеет свои собствен­ные уникальные атрибуты, операции и связи.

Множественность(multiplicity) показывает, сколько экземп­ляров одного класса взаимодействуют с помощью этой связи с одним экземпляром другого класса в данный момент времени.

Например, при разработке системы регистрации курсов в уни­верситете можно определить классы Course (Курс) и Student (Сту­дент). Между ними установлена связь: у курсов могут быть сту­денты, а у студентов – курсы. Вопрос, на который должен отве­тить параметр множественности: «Сколько курсов студент может посещать в данный момент?» и «Сколько студентов может за раз посещать один курс?».

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.13 – Обобщение

Так как множественность дает ответ на оба эти вопроса, ее индикаторы устанавливаются на обоих концах линии связи. Если в примере регистрации курсов один студент мо­жет посещать от 0 до 4 курсов, а один курс могут слушать от 10 до 20 студентов, то на диаграмме классов это можно изобразить следующим образом (рисунок 2.14).

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.14 –Множественность

Для обозначения множественности приняты следующие нотации (таблица 2.4).

Таблица 2.4 – Значения множественности

Множественность Значение
* Много
Нуль
Один
0..* Нуль или больше
1..* Один или больше
0..1 Нуль или один
1..1 Ровно один

Связи можно уточнить с помощью имен связей или ролевых имен. Имя связи – это обычно глагол или глагольная фраза, описывающая, зачем она нужна. Например, между классом Person (человек) и классом Company (компания) может существо­вать ассоциация. В связи с этим возникает вопрос, является ли объект класса Person клиентом компании, ее сотрудником или вла­дельцем? Для того чтобы определить это, ассоциацию можно на­звать «employs» (нанимает). На рисунке 2.15 приведено имя связи.

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.15 –Имя связи

Имена у связей определять необязательно. Обычно это дела­ют, если причина создания связи не очевидна. Имя показывают около линии соответствующей связи.

Ролевые имена применяют в связях ассоциации или агре­гации вместо имен для описания того, зачем эти связи нужны. Воз­вращаясь к примеру с классами Person и Company, можно сказать, что класс Person играет роль сотрудника класса Company. Роле­вые имена - это обычно имена существительные или включающие их фразы, их показывают на диаграмме рядом с классом, играю­щим соответствующую роль. Как правило, пользуются или роле­вым именем, или именем связи, но не обоими сразу. Как и имена связей, ролевые имена не обязательны, их дают, только если цель связи не очевидна. Пример ролевых имен приводится на рисунке 2.16.

Создание диаграммы сотрудничества - student2.ru

Рисунок 2.16 – Ролевые имена

Наши рекомендации