Джим Арлоу, Айла Нейштадт - UML 2 и Унифицированный процесс. Практический объектно-ориентированный анализ и проектирование (1037782), страница 55
Текст из файла (страница 55)
Реализация прецедентовго информации. Главное необходимо понимать, что в результате отправления сообщения вызывается некоторая операция экземпляраи что сложная нумерация сообщений указывает на вложенность вызовов операций (т. е. вложенный фокус управления).12.11.1. ИтерацияПоказать итерацию на коммуникационных диаграммах можно с помощью выражения, описывающего итерацию. Оно включает спецификатор итерации (*) и (необязательный) блок итерации, как показанона рис. 12.22.Выражение, описывающее итерацию, определяет, сколько раз должнобыть отправлено сообщение.UML 2 не определяет никакого конкретного синтаксиса для блоковитераций, поэтому может использоваться все, что имеет смысл. Обычно хорошим вариантом являются код или псевдокод.
Вероятно, вы думаете, что коммуникационные диаграммы могли бы по умолчанию использовать синтаксис итерации диаграммы последовательностей, описанный в разделе 12.10.2. Однако в спецификации UML об этом ничего не сказано! Если действительно применить аналогичный синтаксиситерации, описывающее итерацию сообщение могло бы выглядетьследующим образом:* [ loop min, max [ условие ] ]В такой записи есть преимущество единообразия, но и некоторая синтаксическая избыточность, поскольку и loop, и символ * являются спецификаторами итерации. Тем не менее мы считаем, что это очень хороший подход.В примере на рис.
12.22 для обозначения повторения блока итерациипри увеличении i от 1 до n применяется псевдокод. Затем i используетспецификатор итерацииsd PrintCoursesблок итерации1.1 * [for i = 1 to n] : printCourse( i )1: printCourses( ):Registrar:RegistrationManager1.1.1: print()[i]:CourseРис. 12.22. Синтаксис итерации на коммуникационных диаграммах29312.11. Коммуникационные диаграммыsd PrintCourses1: printCourses( ):RegistrationManager1.1: * print():Registrarcourses *:CourseРис. 12.23. Альтернативный синтаксис итерациися как селектор для выбора определенного экземпляра Course, которому отправляется сообщение print(). В результате этого происходит распечатка всех экземпляров Course. Однако такой подход предполагает,что экземпляры Course хранятся в индексированной коллекции. Есливы не хотите делать такое предположение, можно воспользоватьсяальтернативным подходом, показанным на рис.
12.23.Рисунок 12.23 иллюстрирует два аспекта:1. На связи между :RegistrationManager и :Course указано имя роли во множественном числе (courses) и кратность. Все это свидетельствуето том, что :RegistrationManager соединен с коллекцией объектов :Course(см.
диаграмму классов на рис. 12.7).2. К сообщению print() добавлен спецификатор итерации. Это указывает на то, что сообщение print() посылается каждому объекту коллекции.Стандартный спецификатор итерации (*) означает, что сообщения будут выполняться последовательно. Если необходимо показать, что всесообщения выполняются параллельно, используется спецификаторпараллельной итерации *//.12.11.2. ВетвлениеВетвление можно смоделировать, добавив в сообщения сторожевые условия.
Такие сообщения посылаются только тогда, когда сторожевоеусловие становится истинным.Ветвление – сообщение посылается, только если условие истинно.На рис. 12.24 показан пример ветвления в нашей системе регистрациикурсов. Эта коммуникационная диаграмма реализует прецедент RegisterStudentForCourse (зарегистрировать студента на курс). В этой системерегистрация является трехэтапным процессом:294Глава 12. Реализация прецедентовsd RegisterStudentForCourse1: register ( "Jim", "UML" )1.1: student = findStudent( "Jim" )1.2: course = findCourse( "UML" ):RegistrationManager1.4 [!found] : error():Registrar1.3 [found] : register( student )сторожевое условиеfound = (student != null) & (course != null)course:CourseРис.
12.24. Коммуникационная диаграмма с ветвлением•••найти запись студента – нельзя зарегистрировать студента на курс,если его нет в системе;найти необходимый курс;зарегистрировать студента на курс.На рис. 12.24 широко представлены условия, чтобы продемонстрировать варианты их применения в коммуникационных диаграммах. Условия не имеют формального синтаксиса, но обычно являются выражениями, в которых используются временные переменные областидействия текущего фокуса управления или атрибуты классов, участвующих во взаимодействии.
На рис. 12.24 результаты операций findStudent(…) и findCourse(…) записываются в две временные переменные:student (студент) и course (курс). Затем значения этих переменных используются для вычисления значения временной булевой переменнойfound (найден). found применяется для образования ветви в шаге 1.3.Кроме того, found используется для принятия решения о формировании ошибки для :Registrar на шаге 1.4.Рассмотрим пошаговую интерпретацию рис. 12.24.1.
registerStudent( "Jim", "UML" ) – актер :Registrar посылает сообщение registerStudent( "Jim", "UML" ) объекту :RegistrationManager.1.1. findStudent( "Jim" ) – :RegistrationManager сам себе посылает сообщение findStudent( “Jim” ). Возвращаемое в результате этой операции значение сохраняется в переменной student. В случае неудачного поиска значение равно null.1.2. findCourse( "UML" ) – :RegistrationManager сам себе посылает сообщение findCourse( "UML" ).
Возвращаемое в результате этой операции значение сохраняется в переменной course. В случае неудачного поиска значение равно null.1.3. [found] register( student ) – :RegistrationManager посылает сообщение register( student ) объекту course. Это сообщение защищеноусловием и будет послано, если и student, и course неnull. Иначе12.12. Что мы узнали295говоря, попытка зарегистрировать student на course делаетсятолько в случае успешного обнаружения обоих объектов, student и course.1.4. [!found] : error() – если found имеет значение false, вызываетсяоперация error() объекта :Registrar.На коммуникационных диаграммах довольно сложно отчетливо показать ветвления – создается впечатление, что условия разбросаны повсей диаграмме; диаграмма очень быстро становится достаточно сложной.
Основная рекомендация: показывайте на этих диаграммах только очень простое ветвление. Для представления сложных ветвленийбольше подходят диаграммы последовательностей.12.12. Что мы узналиРеализация прецедентов – важнейшая часть процесса анализа. Онапозволяет сравнить теорию с практикой, явно демонстрируя, как могут взаимодействовать объекты классов для обеспечения заданного поведения системы.
Диаграммы взаимодействий показывают, как классы и объекты реализуют требования, определенные в прецеденте.Мы изучили следующее:•Реализации прецедентов создаются в деятельности UP Анализ прецедента; эта деятельность формирует часть динамического представления системы.•Реализации прецедентов показывают, как взаимодействуют экземпляры классов анализа для реализации функциональных требований, определенных прецедентом.••Каждая реализация прецедента реализует только один прецедент.•Реализации прецедентов состоят из:•диаграмм классов анализа – они должны «рассказывать историю» об одном (или более) прецеденте;•диаграммы взаимодействий – должны демонстрировать, каквзаимодействуют объекты для реализации поведения прецедента;•особых требований – во время реализации прецедента всегдавыясняются новые требования и их необходимо фиксировать;•уточнений прецедента – вероятно, понадобится изменять прецедент во время его реализации.Взаимодействия – это единицы поведения контекстного классификатора.•Взаимодействия могут использовать любые возможности контекстного классификатора.296Глава 12.
Реализация прецедентов•••••В реализации прецедента контекстный классификатор – это прецедент.• Общая форма диаграммы взаимодействий показывает взаимодействия между ролями, которые могут исполнять в этом взаимодействии экземпляры классификатора.• Форма экземпляров диаграммы взаимодействий показываетвзаимодействия между конкретными экземплярами классификатора:• для линий жизни используется обычная нотация экземпляра.Линия жизни представляет участника взаимодействия – то, как экземпляр классификатора участвует во взаимодействии.• Каждая линия жизни имеет необязательное имя, тип и необязательный селектор.• Все линии жизни обозначаются той же пиктограммой, что и ихтип.• Экземпляры обозначаются путем подчеркивания имени, типаи селектора.Сообщение представляет конкретный тип соединения между двумявзаимодействующими линиями жизни.• Синхронное сообщение (сплошная стрелка).• Асинхронное сообщение (открытая стрелка).• Возврат (открытая стрелка, пунктирная линия).• Сообщение создания (открытая стрелка, сплошная линия, стереотип «create»).• Сообщение уничтожения (открытая стрелка, сплошная линия,стереотип «destroy»).• Найденное сообщение (открытая стрелка, исходящая из заштрихованного кружка).• Потерянное сообщение (открытая стрелка, заканчивающаясяв заштрихованном кружке).Диаграммы взаимодействий.• Диаграммы последовательностей – акцентируют внимание на временной упорядоченности сообщений.• Коммуникационные диаграммы – акцентируют внимание наструктурных отношениях между объектами.• Диаграммы обзора взаимодействий – акцентируют вниманиена отношениях между взаимодействиями.• Временные диаграммы – акцентируют внимание на реальномвремени взаимодействий.Диаграммы последовательностей.• Ход времени происходит сверху вниз.12.12.
Что мы узнали•••297Линии жизни выполняются слева направо:• у линий жизни есть вертикальные пунктирные «хвосты», отражающие продолжительность существования линии жизни;• линии жизни могут иметь активации для обозначения того,что фокус управления находится на этой линии жизни;• линии жизни должны быть хорошо организованы, чтобы свести к минимуму количество пересекающихся линий.• Поясняющие сценарии необходимо размещать на диаграмме последовательностей внизу слева.• Инварианты состояний – символы состояний размещаются в соответствующих точках линии жизни.• Ограничения заключаются в {} и размещаются на или рядомс линиями жизни.Комбинированные фрагменты – области разного поведения на диаграммах последовательностей.• Оператор определяет, как исполняются его операнды.• Сторожевое условие определяет, будут ли исполняться операнды.• Операнд заключает в себе поведение.Операторы.• opt – существует единственный операнд, который исполняетсяв случае истинности условия (как if … then).• alt – выполняется тот операнд, условие которого истинно.• loop – loop min, max [условие]:• loop или loop * – повторяется бесконечно;• loop n, m – повторяется (m n) раз;• loop [ booleanExpression ] – повторяется, пока booleanExpression истинно;• loop 1, * [ booleanExpression ] – выполняется один раз, затем повторяется, пока booleanExpression истинно;• loop [ for each object in collectionOfObjects ] – тело цикла выполняется один раз для каждого объекта коллекции;• loop [ for each object in className ] – тело цикла выполняетсяодин раз для каждого объекта класса.• break – если сторожевое условие истинно, выполняется операнд,а не остальная часть взаимодействия, в которую включен оператор.• ref – комбинированный фрагмент ссылается на другое взаимодействие.• par – все операнды исполняются параллельно.• critical – операнд исполняется атомарно без прерывания.298Глава 12.
Реализация прецедентов••••seq – операнды исполняются параллельно при условии выполнения следующего ограничения: последовательность поступлениясобытий на одну линию жизни от разных операндов совпадаетс последовательностью операндов.• strict – операнды исполняются в строгой последовательности.• neg – операнд показывает неверные взаимодействия.• ignore – перечисляет сообщения, намеренно исключенные из взаимодействия.• consider – перечисляет сообщения, намеренно включенные во взаимодействие.• assert – данный операнд является единственным действительнымповедением в данный момент взаимодействия.Коммуникационные диаграммы – акцентируют внимание на структурных аспектах взаимодействия:• линии жизни соединены связями;• сообщения имеют порядковый номер – иерархическая нумерация соответствует вложенности фокуса управления.Итерация – в сообщении используются спецификатор итерации (*)и необязательный блок итерации.• Блок итерации определяет число повторений.• В блоке итерации может использоваться естественный язык,псевдокод, исходный код или нотация цикла (оператора loop)диаграммы последовательностей.• Итерацию по коллекции объектов можно обозначить, указав нацелевом конце связи имя роли и кратность (>1) и предварив сообщение спецификатором итерации (*).