UML2 и унифицированный процесс. Джим арлоуайла нейштадтпрактический объектно ориентированныйанализ и проектированиеu
Скачать 6.08 Mb.
|
Рис. 12.19. Применение цикла для реализации операции поиска FindCourse() 290 Глава 12. Реализация прецедентов с кратностью больше 1 можно использовать как коллекцию объектов. В данном случае для представления коллекции объектов Course ис пользуется имя courses (курсы). 12.11. Коммуникационные диаграммы Коммуникационные диаграммы акцентируют внимание на структур ных аспектах взаимодействия, на том, как соединяются линии жизни. В UML 2 их семантика довольно слаба по сравнению с диаграммами последовательностей. Коммуникационные диаграммы акцентируют внимание на структурных аспектах взаимодействия. Мы уже приводили некоторые коммуникационные диаграммы. Со гласно спецификации UML 2.0 [UML2S] диаграммы объектов, кото рые были представлены в главе 7, могут считаться особыми случаями диаграмм классов или особыми случаями коммуникационных диа грамм формы экземпляров, где каждая линия жизни представляет эк земпляр класса (объект). Синтаксис коммуникационных диаграмм подобен синтаксису диа грамм последовательностей, за исключением того, что здесь у линий жизни нет «хвостов». Вместо этого они соединены связями, образую щими коммуникационные каналы для передачи сообщений. Порядок сообщений определяется путем иерархической нумерации. На рис. 12.21 показана простая коммуникационная диаграмма для прецедента AddCourses, в котором :Registrar добавляет два новых объекта :RegistrationManager sd FindCourse( name : String ) : Course courses loop [for each course in courses] course:Course course null break [name = courseName] courseName = getName() Рис. 12.20. Применение цикла для перебора коллекции объектов 12.11. Коммуникационные диаграммы 291 Course. Следует обратить внимание на нумерацию сообщений, обознача ющую их последовательность и вложенность в другие сообщения. Ниже пошаговая интерпретация рис. 12.21. 1. addCourse( "UML" ) – сообщение addCourse(...) отправляется линии жиз ни объекта :RegistrationManager с параметром "UML". Экземпляр :Regis trationManager инициирует операцию addCourse( … ) и передает в нее параметр "UML", фокус управления переходит в эту операцию. 1.1. «create» – порядковый номер 1.1 говорит о том, что фокус управ ления по прежнему находится в операции addCourse(...). :Registra tionManager посылает анонимное сообщение, помеченное стерео типом «create». Такие сообщения «create» создают новые объек ты, и это конкретное сообщение создает новый объект uml:Course. Позже при анализе или проектировании этому анонимному со общению будет дано имя и, возможно, параметры, но пока до статочно показать, что создается новый объект uml:Course. По сле создания объекта из операции addCourse( … ) больше не по сылается никаких сообщений, и этот поток возвращается. 2. addCourse( "MDA" ) – в :RegistrationManager посылается сообщение add Course(…) с параметром "MDA". Фокус управления переходит к опера ции addCourse( … ). 2.1. «create» – порядковый номер 2.1 говорит о том, что фокус управ ления по прежнему находится в операции addCourse(…). :Regis trationManager посылает анонимное сообщение, помеченное сте реотипом «create»; это создает новый объект, mda:Course. После создания объекта фокус управления addCourse(…) возвращается и итерация завершается. Поначалу могут возникнуть некоторые сложности с прочтением ком муникационных диаграмм, потому что в них заключено довольно мно 2: addCourse( "MDA" ) :Registrar :RegistrationManager mda:Course uml:Course 1: addCourse( "UML" ) 1.1: «create» 2.1: «create» sd AddCourses связь cообщение порядковый номер линия жизни сообщение создания объекта Рис. 12.21. Коммуникационная диаграмма прецедента AddCourses 292 Глава 12. Реализация прецедентов го информации. Главное необходимо понимать, что в результате от правления сообщения вызывается некоторая операция экземпляра и что сложная нумерация сообщений указывает на вложенность вызо вов операций (т. е. вложенный фокус управления). 12.11.1. Итерация Показать итерацию на коммуникационных диаграммах можно с по мощью выражения, описывающего итерацию. Оно включает специфи катор итерации ( *) и (необязательный) блок итерации, как показано на рис. 12.22. Выражение, описывающее итерацию, определяет, сколько раз должно быть отправлено сообщение. UML 2 не определяет никакого конкретного синтаксиса для блоков итераций, поэтому может использоваться все, что имеет смысл. Обыч но хорошим вариантом являются код или псевдокод. Вероятно, вы ду маете, что коммуникационные диаграммы могли бы по умолчанию ис пользовать синтаксис итерации диаграммы последовательностей, опи санный в разделе 12.10.2. Однако в спецификации UML об этом ниче го не сказано! Если действительно применить аналогичный синтаксис итерации, описывающее итерацию сообщение могло бы выглядеть следующим образом: * [ loop min, max [ условие ] ] В такой записи есть преимущество единообразия, но и некоторая син таксическая избыточность, поскольку и loop, и символ * являются спе цификаторами итерации. Тем не менее мы считаем, что это очень хо роший подход. В примере на рис. 12.22 для обозначения повторения блока итерации при увеличении i от 1 до n применяется псевдокод. Затем i использует блок итерации 1: printCourses( ) :Registrar :RegistrationManager [i]:Course 1.1.1: print() 1.1 * [for i = 1 to n] : printCourse( i ) sd PrintCourses спецификатор итерации Рис. 12.22. Синтаксис итерации на коммуникационных диаграммах 12.11. Коммуникационные диаграммы 293 ся как селектор для выбора определенного экземпляра Course, которо му отправляется сообщение print(). В результате этого происходит рас печатка всех экземпляров Course. Однако такой подход предполагает, что экземпляры Course хранятся в индексированной коллекции. Если вы не хотите делать такое предположение, можно воспользоваться альтернативным подходом, показанным на рис. 12.23. Рисунок 12.23 иллюстрирует два аспекта: 1. На связи между :RegistrationManager и :Course указано имя роли во мно жественном числе ( courses) и кратность. Все это свидетельствует о том, что :RegistrationManager соединен с коллекцией объектов :Course (см. диаграмму классов на рис. 12.7). 2. К сообщению print() добавлен спецификатор итерации. Это указыва ет на то, что сообщение print() посылается каждому объекту кол лекции. Стандартный спецификатор итерации ( *) означает, что сообщения бу дут выполняться последовательно. Если необходимо показать, что все сообщения выполняются параллельно, используется спецификатор параллельной итерации *//. 12.11.2. Ветвление Ветвление можно смоделировать, добавив в сообщения сторожевые ус ловия. Такие сообщения посылаются только тогда, когда сторожевое условие становится истинным. Ветвление – сообщение посылается, только если условие истинно. На рис. 12.24 показан пример ветвления в нашей системе регистрации курсов. Эта коммуникационная диаграмма реализует прецедент Regis terStudentForCourse (зарегистрировать студента на курс). В этой системе регистрация является трехэтапным процессом: 1: printCourses( ) :Registrar :RegistrationManager :Course 1.1: * print() sd PrintCourses courses * Рис. 12.23. Альтернативный синтаксис итерации 294 Глава 12. Реализация прецедентов • найти запись студента – нельзя зарегистрировать студента на курс, если его нет в системе; • найти необходимый курс; • зарегистрировать студента на курс. На рис. 12.24 широко представлены условия, чтобы продемонстриро вать варианты их применения в коммуникационных диаграммах. Ус ловия не имеют формального синтаксиса, но обычно являются выра жениями, в которых используются временные переменные области действия текущего фокуса управления или атрибуты классов, участ вующих во взаимодействии. На рис. 12.24 результаты операций find Student(…) и findCourse(…) записываются в две временные переменные: student (студент) и course (курс). Затем значения этих переменных ис пользуются для вычисления значения временной булевой переменной found (найден). found применяется для образования ветви в шаге 1.3. Кроме того, found используется для принятия решения о формирова нии ошибки для :Registrar на шаге 1.4. Рассмотрим пошаговую интерпретацию рис. 12.24. 1. registerStudent( "Jim", "UML" ) – актер :Registrar посылает сообщение reg isterStudent( "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. Иначе :RegistrationManager 1: register ( "Jim", "UML" ) :Registrar course:Course 1.3 [found] : register( student ) 1.1: student = findStudent( "Jim" ) 1.4 [!found] : error() 1.2: course = findCourse( "UML" ) sd RegisterStudentForCourse сторожевое условие found = (student != null) & (course != null) Рис. 12.24. Коммуникационная диаграмма с ветвлением 12.12. Что мы узнали 295 говоря, попытка зарегистрировать student на course делается только в случае успешного обнаружения обоих объектов, stu dent и 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) и предварив со общение спецификатором итерации ( *). Сообщение посылается всем объектам по очереди. • Спецификатор параллельной итерации *// применяется для обо значения параллельного выполнения сообщений. • Ветвление – сообщение предваряется сторожевыми условиями. Со общение исполняется, если сторожевое условие истинно. • Могут возникнуть сложности с четким представлением ветвле ния на коммуникационных диаграммах – для сложного ветвле ния используются диаграммы последовательностей. |