ВВедение в ИМЛ. Для чего был написан этот курс
Скачать 3.44 Mb.
|
Рис. 5.19. Как видите, все объекты, отображенные на диаграмме, являются активными. Таких объекта три - это робот, печь и менеджер цеха, который изображен как композитный активный объект. Вообще же, если говорить о композитных объектах, то следует отметить, что в UML 2 появился новый тип диаграмм - композитная структурная диаграмма. Она показывает внутреннюю структуру элемента, включая точки взаимодействия с другими частями системы. Таким образом, отображается состав и отношения между частями, которые совместными усилиями реализуют поведение элемента. Вот отличный пример композитной диаграммы из Zicom Mentor (). Рис. 5.20. Прекрасная модель велосипеда! Узнаете старых знакомых - композитные объекты? К сожалению, композитные структурные диаграммы находятся за пределами тематики экзамена UM0-100, поэтому больше о них мы здесь говорить не будем. Однако напоследок скажем, что, кроме внутренних частей, на таких диаграммах можно увидеть еще одно новшество UML 2 - порты. Порт - это типизированный элемент, который представляет "видимую снаружи" часть содержащего его элемента. Порт, как это и следует из названия, определяет взаимодействие элемента модели с окружающей его средой. Порт может размещаться на границе части, класса или композитной структуры. Порт может описывать сервисы, предоставляемые элементом модели (и требуемые окружающей его средой). Изображается порт как именованный (недаром же мы ранее сказали "типизированный") прямоугольник на границе содержащего его элемента модели (впрочем, иногда можно увидеть символ порта и внутри символа класса - тогда говорят, что класс имеет скрытый порт ). Чтобы покончить с этими отступлениями от темы, покажем, как все это выглядит на диаграмме, и вернемся к диаграммам взаимодействия (). Рис. 5.21. Вспомнили, что изображают "леденцы на палочке"? Правильно, интерфейсы - предоставляемый классом и требуемый им, молодцы. А теперь вернемся к основной нити нашего повествования. Рекомендации по построению диаграмм взаимодействия Каким же образом и в какой последовательности следует действовать, чтобы построить качественную диаграмму взаимодействия? Начинать нужно с выделения тех и только тех классов, объекты которых участвуют в моделируемом вами взаимодействии. Затем все объекты наносим на диаграмму. Следует также определить те объекты, которые будут существовать постоянно, и те, которые будут существовать только во время выполнения ими действий в рамках моделируемого взаимодействия. Так, объекты нарисованы, можно переходить к сообщениям. Возможно, чтобы лучше передать роли, играемые объектами во взаимодействии, понадобится использовать различные разновидности сообщений и стереотипы. Для уничтожения объектов, которые существуют только во время выполнения неких действий, тоже нужно предусмотреть специальные сообщения. А если есть ветвления? Самые простые случаи ветвлений процесса взаимодействия можно показать и на одной диаграмме - помните пример с разными способами платежа в зависимости от стоимости приглянувшейся вещи? Но при изображении ветвлений диаграмма становится более сложной для понимания "с лету". Нужно соблюдать баланс между детализацией и сложностью: лучше каждый альтернативный поток управления показывать на отдельной диаграмме. В таком случае следует рассматривать такие "частные" диаграммы в комплексе, как одну модель взаимодействия. Если же хочется еще больше детализировать диаграмму, можно ввести временные ограничения на выполнение отдельных действий. Впрочем, для простых асинхронных сообщений временные ограничения, скорее всего, не нужны. А вот необходимость синхронизации сложных потоков управления часто требует использования таких ограничений. Запись их должна следовать правилам языка объектных ограничений (OCL, Object Constraint Language). Рассмотрение OCL выходит за рамки нашего курса и экзамена UM0-100, для подготовки к которому он написан. Хотя, сами того не зная, мы уже использовали OCL - вспомните условия в квадратных скобках под сообщениями на диаграмме последовательностей с ветвлением! Выводы • Диаграмма последовательностей - диаграмма взаимодействия, в которой основной акцент сделан на упорядочении сообщений во времени. • Диаграмма кооперации - альтернативная форма представления информации, содержащейся в диаграмме последовательностей. • Диаграмма кооперации - диаграмма взаимодействий, в которой основной акцент сделан на структурной организации объектов, посылающих и получающих сообщения. • Существуют различные типы сообщений: синхронные, асинхронные и ответные, потерянные и найденные. • Диаграммы кооперации бывают двух "уровней" - уровня экземпляров и уровня спецификации. • Кооперация - это статическая конструкция для моделирования набора сущностей, взаимодействующих друг с другом. • С диаграммами кооперации связаны такие понятия, как мультиобъекты, композитные объекты и активные объекты. Контрольные вопросы • Может ли диаграмма последовательностей содержать объект с линией жизни, но без фокуса управления? • Чем отличаются представления кооперации на уровне спецификации и на уровне примеров? • В чем разница между активными и пассивными объектами? • Чем асинхронное сообщение отличается от синхронного? • Что такое мультиобъект? • Что такое композитный объект и как он связан с понятием кооперации? • Как можно избежать усложнения диаграммы взаимодействия с разветвленным потоком управления? Лекция 7: Диаграммы прецедентов: крупным планом Аннотация: Мы уже познакомились с диаграммами UML нескольких видов. Все они описывают, как устроена и как работает система. Но иногда важно показать, как ведет себя система с точки зрения внешнего наблюдателя, показать, что именно делает система, а не то, как она это делает. Для этого в UML имеется диаграмма прецедентов. О ней-то мы наконец и поговорим. В этой лекции мы рассмотрим такие вопросы: несколько слов о требованиях; диаграммы прецедентов и их нотация; моделирование при помощи диаграмм прецедентов Несколько слов о требованиях Итак, поговорим о требованиях. Что это такое, мы, в общем, понимаем - когда заказчик описывает нам, чего же именно он хочет, мы всегда слышим фразы типа "хотелось бы, чтобы проверка обновлений проводилась автоматически, как в антивирусах", "хочу большую зеленую кнопку в центре окна, которая начинает процесс", "программа должна позволять просматривать и печатать отчеты", "и чтоб красивенько все было, с полупрозрачностями, как в Висте", "при выходе должно выводиться подтверждение" и т. д. и т. п. Конечно, как настоящие разработчики, мы понимаем и то, что заказчик никогда не знает, что именно ему нужно, а если понимает, то объяснить не может. Но ведь фразы-то всегда, по сути, одинаковы! Они описывают, как заказчик представляет себе систему, чего заказчик хочет от системы, функциональность, которой он от нее ожидает, требования, которые к ней предъявляет. Если обратиться к классикам, например, к той же "банде трех" (Якобсон, Буч, Рамбо), мы узнаем, что требование - это желаемая функциональность, свойство или поведение системы. Именно со сбора требований начинается процесс разработки ПО. Если изобразить процесс разработки ПО в виде " черного ящика " (уверены, читатель знает, что это такое, если нет - "Википедия" к вашим услугам), на выходе которого мы получаем программный продукт, то на вход этого "черного ящика" будет подаваться именно набор требований к программному продукту ( рис. 6.1 )! Рис. 6.1. Кстати, какую диаграмму напоминает этот рисунок? Правильно, диаграмму активностей. И выбор именно этой диаграммы тут абсолютно оправдан - помните, мы говорили, что диаграммы активностей часто используют для описания бизнес-процессов? Единственный нюанс: обычно процесс разработки не заканчивается с выпуском программного продукта - грядет новая итерация, новые, уточненные требования, новая версия и т. д. Кстати, вернемся к требованиям. Да, мы сказали, что на вход нашего "черного ящика" подается набор требований. Но в какой форме? Как их документируют, эти требования? Думаю, большинство читателей помнит, что такое техническое задание - основной документ, без составления которого не начинался в советские времена ни один проект. Документ это был большой, многостраничный, с четкой структурой, определяемой ГОСТами (государственными отраслевыми стандартами). И описывал он, по сути, не что иное, как требования к создаваемой системе! Техническое задание - вещь по-своему хорошая. Но время шло, менялись стандарты, нотации, способы описания требований. И вот постепенно техническое задание уступило место набору артефактов, состоящему из документов двух видов: • диаграммы прецедентов; • нефункциональные требования. Диаграммы прецедентов составляют модель прецедентов (вариантов использования, use- cases). Прецедент - это функциональность системы, позволяющая пользователю получить некий значимый для него, ощутимый и измеримый результат. Каждый прецедент соответствует отдельному сервису, предоставляемому моделируемой системой в ответ на запрос пользователя, т. е. определяет способ использования этой системы. Именно по этой причине use cases, или прецеденты, часто в русской терминологии фигурируют как варианты использования. Варианты использования чаще всего применяются для спецификации внешних требований к проектируемой системе или для спецификации функционального поведения уже существующей системы. Кроме этого, варианты использования неявно описывают типичные способы взаимодействия пользователя с системой, позволяющие корректно работать с предоставляемыми системой сервисами. Нефункциональные требования - это описание таких свойств системы, как особенности среды и реализации, производительность, расширяемость, надежность и т. д. Часто нефункциональные требования не привязаны к конкретному варианту использования и потому выносятся в отдельный список дополнительных требований к системе ( рис. 6.2 ). Рис. 6.2. Но вернемся же к прецедентам (вариантам использования). Идентифицировать прецеденты и действующие лица - обязанность системного аналитика. И делает он это для того, чтобы: • четко разграничить систему и ее окружение; • определить, какие действующие лица и как именно взаимодействуют с системой, какой функционал (варианты использования) ожидается от системы; • определить и описать в словаре предметной области (глоссарии) общие понятия, которые необходимы для детального описания функционала системы (прецедентов). Подобный вид деятельности обычно выполняется в такой последовательности: 1. Определение действующих лиц. 2. Определение прецедентов. 3. Составление описания каждого прецедента. 4. Описание модели прецедентов в целом (этот этап включает в себя создание словаря предметной области). Вначале требования оформляются в виде обычного текстового документа, который создается или самим пользователем, или пользователем и разработчиком вместе. Далее требования оформляют в виде таблицы. В левую колонку помещают прецеденты, а в правую - действующих лиц, участвующих в прецеденте. Рассмотрим пример. Секретарь размещает на сервере меню обеденных блюд на неделю. Сотрудники должны иметь возможность ознакомиться с меню и сделать заказ, выбрав блюда на каждый день следующей недели. Офис-менеджер должен иметь возможность сформировать счет и оплатить его. Система должна быть написана на ASP.NET. Такое вот нехитрое интернет- приложение для автоматизации заказов обедов в офис. Думаем, здесь все понятно. Таблица с описанием требований может быть, например, такой: Прецедент Действующее лицо разместить меню секретарь ознакомиться с меню сотрудник, секретарь, офис-менеджер сделать заказ сотрудник, секретарь, офис-менеджер сформировать счет офис-менеджер оплатить счет офис-менеджер Здесь нигде не сказано о том, что система должна быть написана на ASP.NET. Почему - понятно: это ведь нефункциональное требование! И еще, очевидно, что секретарь и офис-менеджер тоже являются сотрудниками. Читатель, внимательно прочитавший предыдущие лекции, заподозрит, что в данном случае, создавая модель прецедентов, говоря о действующих лицах, можно бы применить генерализацию. Действительно, диаграмма прецедентов, построенная на основе этой таблицы, может быть, например, такой ( рис. 6.3 ): Рис. 6.3. Диаграммы прецедентов и их нотация Что ж, у нас есть пример диаграммы. Итак, какие же элементы мы на ней видим? Первое, что бросается в глаза, - большой прямоугольник, внутри которого размещаются эллипсы, обозначающие, как мы уже поняли, прецеденты. В верхней части прямоугольника указано название моделируемой системы, а называют его рамками системы (system boundary, subject boundary), контекстом или просто системой. Этот элемент диаграммы показывает границу между тем, что вы как аналитик показали в виде прецедентов (внутри этих рамок), и тем, что вы изобразили как действующие лица (вне их). Чаще всего таким прямоугольником показывают границы самой моделируемой системы. То есть внутри границы находятся прецеденты - тот функционал, который реализует система (и в этом смысле прецеденты могут рассматриваться как представления подсистем и классов модели), а снаружи - действующие лица: пользователи и другие внешние сущности, взаимодействующие с моделируемой системой. Следует сказать, что рамки системы на диаграммах прецедентов изображают довольно редко, т. к. они неявно подразумеваются самой диаграммой. По сути, этот элемент не привносит в диаграмму какой-либо дополнительной значимой информации, так что его использование - дело вкуса аналитика. Появление рамок системы на диаграмме прецедентов чаще всего диктуется особенностями персонального стиля проектирования. Кроме рамок системы или ее контекста на диаграмме мы видим еще два вида связанных с ней сущностей - это действующие лица (экторы, actors) и прецеденты. Начнем с экторов. Довольно часто в русскоязычной литературе по UML для обозначения действующих лиц можно встретить термин "актер". В принципе, смысл его более-менее понятен и оригинальному английскому термину он созвучен. Более того, есть еще одна причина такого перевода. Какое слово первым приходит к вам в голову, когда вы слышите слово "актер"? Да, конечно же - слово "роль"! Именно о ролях мы вскоре и поговорим, когда будем пытаться разобраться, что скрывается за понятием "действующее лицо". А пока, да простит нас читатель, далее мы все же будем пользоваться словом "эктор" - транскрипцией оригинального термина. Помнится, мы уже как-то писали о нашем отношении к буквальному переводу терминологии... Итак, какой же смысл вкладывают в понятие эктора? Эктор - это набор ролей, которые исполняет пользователь в ходе взаимодействия с некоторой сущностью (системой, подсистемой, классом). Эктор может быть человеком, другой системой, подсистемой или классом, которые представляют нечто за пределами рассматриваемой сущности. Экторы "общаются" с системой путем обмена сообщениями. Четко выделив экторов, вы тем самым ясно определяете границу между тем, что внутри системы, и тем, что снаружи, - рамки системы. Возможно, слова "роли, исполняемые пользователем" в определении эктора звучат не очень понятно. Очень забавно это понятие объясняется в Zicom Mentor: роль - это не конкретный пользователь, а подобие шляпы, которую человек надевает, когда взаимодействует с сущностью. Действительно, наденьте шляпу пирата - и вы капитан Джек Воробей, а наденьте цилиндр и вы - Джек-потрошитель! Шутка... "Физический" пользователь может играть роль одного или даже нескольких экторов, выполняя их функции в ходе взаимодействия с системой. И наоборот, роль одного и того же эктора может выполняться несколькими пользователями. На диаграммах UML экторы изображаются в виде стилизованных человечков, ведь, как вы, конечно, помните, идея была в создании нотации, любой символ которой легко может быть изображен от руки ( рис. 6.4 ): Рис. 6.4. Несмотря на "человеческий" вид этого обозначения, не следует забывать, что экторы - это не обязательно люди. Эктором, как мы уже говорили ранее, может быть внешняя система, подсистема, класс и т. д. Кстати, человечек ( "stick-person" ) - это не единственное обозначение эктора, используемое в UML. На диаграммах прецедентов обычно применяется именно "человекоподобная" форма эктора, но на других диаграммах, и особенно в случаях, когда эктор имеет атрибуты, которые важно показать, используется изображение эктора как класса со стереотипом < рис. 6.5 ): Рис. 6.5. С системой экторы, как мы уже сказали, общаются через сообщения, но если говорить на более высоком уровне абстракции, в терминах модели прецедентов, то взаимодействуют они с системой через прецеденты. Один и тот же эктор может быть связан с несколькими прецедентами, и наоборот, один прецедент может быть связан с несколькими разными экторами. Ассоциации между эктором и прецедентом всегда бинарные - т. е. представляют отношения типа "один к одному", использование кратности недопустимо. Это не противоречит сказанному выше: действительно, один эктор может быть связан с несколькими прецедентами, но только с помощью отдельных ассоциаций - по одной на каждый прецедент. Мы видели это в нашем примере. Кстати, там мы видели ассоциации, изображенные не просто в виде линий, а стрелками. Думаем, смысл этого обозначения вполне понятен: это направленная ассоциация и стрелка (как и на других диаграммах) всегда направлена в сторону той сущности, от которой что-то требуют, чьим сервисом пользуются и т. д. И еще - экторы не могут быть связаны друг с другом. Единственное допустимое отношение между экторами - генерализация ( наследование ). Опять-таки, в нашем примере с заказом обедов в офис, вы могли увидеть именно такой вид отношений между экторами. Это не значит, что в реальной жизни офис-менеджер и секретарь (да и вообще любые два сотрудника) не могут общаться: просто при создании модели прецедентов такое общение не попадает в область наших интересов, считается несущественным. Еще один тип элементов, встречающийся на диаграммах прецедентов, более того, давший им название, - это собственно прецеденты, или варианты использования. Прецедент - это описание набора последовательных событий (включая возможные варианты), выполняемых системой, которые приводят к наблюдаемому эктором результату. Прецеденты описывают сервисы, предоставляемые системой экторам, с которыми она взаимодействует. Причем прецедент никогда не объясняет, "как" работает сервис, а только описывает, "что" делается. Изображаются прецеденты в виде эллипса, внутрь контура которого помещается имя (описание) прецедента. Имя прецедента обычно намного длиннее имен других элементов модели. Почему это так, в принципе, понятно: имя прецедента описывает взаимодействие эктора с системой, говорит о том, какими сообщениями они обмениваются между собой. В нашем примере с заказом обедов мы видели несколько прецедентов и наверняка читатель заметил, что имя прецедента - это, скорее, название сценария, воспроизводящегося в ходе взаимодействия эктора с системой. Причем это всегда описание с точки зрения эктора, описание услуг, предоставляемых системой пользователю. Приведем пример простейшей диаграммы, иллюстрирующей сказанное нами об обозначениях прецедента ( рис. 6.6 ). |