Лабораторная работа №1. UML. Практикум по промышленному
Скачать 1.02 Mb.
|
Диаграмма последовательности (Sequence diagram)Диаграммы взаимодействия (interaction diagrams) описывают взаимодействие групп объектов в различных условиях их поведения. UML определяет диаграммы взаимодействия нескольких типов, из которых наиболее употребительными являются диаграммы последовательности. Обычно диаграмма последовательности описывает один сценарий. На диаграмме показаны экземпляры объектов и сообщения, которыми обмениваются объекты в рамках одного прецедента (use case). Прецедент (use case) — множество сценариев, объединенных по некоторому критерию и описывающих последовательности производимых системой действий, доставляющих значимый для некоторого действующего лица результат. Фактически, диаграмма последовательности — это запись протокола конкретного сеанса работы системы (или фрагмента такого протокола). В объектноориентированном программировании самым существенным во время выполнения является пересылка сообщений между взаимодействующими объектами. Именно последовательность посылок сообщений отображается на данной диаграмме, отсюда и название. Рассмотрим простой сценарий. Предположим, что у нас есть заказ, и мы собираемся вызвать команду для определения его стоимости. При этом объекту заказа (Order) необходимо просмотреть все позиции заказа (Line Items) и определить их цены, основанные на правилах построения цены продукции в строке заказа (Order Line). Проделав это для всех позиций заказа, объект заказа должен вычислить общую скидку, которая определяется индивидуально для каждого клиента. На рис. 13 приведена диаграмма, представляющая реализацию данного сценария. Диаграммы последовательности показывают взаимодействие, представляя каждого участника вместе с его линией жизни (lifeline), которая идет вертикально вниз и упорядочивает сообщения (или обращения к каждому участнику); сообщения также следует читать сверху вниз. Можно видеть, что экземпляр заказа посылает строке заказа сообщения getQuantity и getProduct. Можно также видеть, как заказ применяет метод к самому себе и как этот метод посылает сообщение getDiscountInfo экземпляру клиента. Рис.13.Примердиаграммыпоследовательности(централизованноеуправление) Однако диаграмма не все показывает так хорошо. Последовательность сообщений getQuantity, getProduct, getPricingDetails и calculateBasePrice должна быть реализована для каждойстроки заказа, тогда как метод calculateDiscounts вызывается лишь однажды. Такое заключение нельзя сделать на основе этой диаграммы, но позднее будет введено дополнительное обозначение, которое поможет в этом. В большинстве случаев можно считать участников диаграммы взаимодействия объектами. На приведенной диаграмме участники поименованы с использованием стиля anOrder. В большинстве случаев это вполне приемлемо. Вот более полный синтаксис: имя : Класс, где и имя, и класс не обязательны, но если класс используется, то двоеточие должно присутствовать. Такой синтаксис используется на рис. 16. Каждая линия жизни имеет полосу активности, которая показывает интервал активности участника при взаимодействии. Она соответствует времени нахождения в стеке одного из методов участника. Именование бывает часто полезным для установления связей между участниками на диаграмме. Как видно на диаграмме, вызов метода getProduct возвращает aProduct, имеющего то же самое имя и, следовательно, означающего того же самого участника, aProduct, которому посылается вызов getPricingDetails. Обратите внимание, что обратной стрелкой обозначен только этот вызов с целью показать соответствие. Многие разработчики используют возвраты для всех вызовов, но можно применять их, только когда это дает дополнительную информацию; в противном случае они просто вносят неразбериху. Не исключено, что даже в данном случае можно было опустить возврат. У первого сообщения нет участника, пославшего его, поскольку оно приходит из неизвестного источника. Оно называется найденным сообщением (found message). Другой подход можно увидеть на рис. 14. Основная задача остается той же самой, но способ взаимодействия участников для ее решения совершенно другой. Заказ спрашивает каждую строку заказа о его собственной цене (Price). Сама строка заказа передает вычисление дальше – объекту продукта (Product); обратите внимание, как показана передача параметра. Подобным же образом для вычисления скидки объект заказа вызывает метод для клиента (Customer). Поскольку для выполнения этой задачи клиенту требуется информация от объекта заказа, то он делает повторный вызов в отношении заказа для получения этих данных. Рис.14.Примердиаграммыпоследовательности(распределенноеуправление) Вопервых, на этих двух диаграммах надо обратить внимание на то, насколько ясно диаграмма последовательности показывает различия во взаимодействии участников. В этом проявляется мощь диаграмм взаимодействий. Они не очень хорошо представляют детали алгоритмов, такие как циклы или условное поведение, но делают абсолютно прозрачными вызовы между участниками и дают действительно ясную картину того, какую обработку выполняют конкретные участники. Вовторых, посмотрите, как четко видна разница в стиле между двумя взаимодействиями. На рис. 13 представлено централизованное управление (centralized control), когда один из участников в значительной степени выполняет всю обработку, а другие предоставляют данные. На рис. 14 изображено распределенное управление (distributed control), при котором обработка распределяется между многими участниками, каждый их которых выполняет небольшую часть алгоритма. Оба стиля обладают преимуществами и недостатками. Большинство разработчиков, особенно новички в объектноориентированном программировании, чаще всего применяют централизованное управление. Во многих случаях это проще, так как вся обработка сосредоточена в одном месте. Одна из главных задач хорошего проектирования заключается в локализации изменений. Данные и программный код, получающий доступ к этим данным, часто изменяются вместе. Поэтому размещение данных и обращающейся к ним программы в одном месте – первое правило объектноориентированного проектирования. Кроме того, распределенное управление позволяет создать больше возможностей для применения полиморфизма, чем в случае применения условной логики. Если алгоритмы определения цены отличаются для различных типов продуктов, то механизм распределенного управления позволяет нам использовать подклассы класса продукта (Product) для обработки этих вариантов. Создание и удаление участниковВ диаграммах последовательности для создания и удаления участников применяются некоторые дополнительные обозначения (рис. 15). В случае создания участника надо нарисовать стрелку сообщения, направленную к прямоугольнику участника. Если применяется конструктор, то имя сообщения не обязательно, но лучше маркировать его словом «new» в любом случае. Если участник выполняет чтонибудь непосредственно после создания, например, команду запроса, то надо начать активацию сразу после прямоугольника участника. Рис.15.Созданиеиудалениеучастников Удаление участника обозначается большим крестом (X). Стрелка сообщения, идущая в X, означает, что один участник явным образом удаляет другого; X в конце линии жизни показывает, что участник удаляет сам себя. Если в системе работает сборщик мусора (например, JVM), то объекты не удаляются вручную, тем не менее следует при помощи X показать, что объект больше не нужен и готов к удалению. Так следует поступать и в случае операций закрытия, показывая, что объект больше не используется. Циклы, условияОбщая проблема диаграмм последовательности заключается в том, как отображать циклы и условные конструкции. Прежде всего надо усвоить, что диаграммы последовательности для этого не предназначены. Подобные управляющие структуры лучше показывать с помощью диаграммы деятельности или собственно кода. Диаграммы последовательности применяются для визуализации процесса взаимодействия объектов, а не как средство моделирования алгоритма управления. Рис.16.Фреймывзаимодействиявдиаграммепоследовательности Для этого существуют дополнительные обозначения. И для циклов, и для условий используются фреймы взаимодействий (interaction frames), представляющие собой средство разметки диаграммы взаимодействия. На рис. 16 показан простой алгоритм, основанный на следующем псевдокоде. foreach (lineitem)if (product.value > $10K) careful.dispatch elseend if end for regular.dispatchif (needsConfirmation) messenger.confirm В основном фреймы состоят из некоторой области диаграммы последовательности, разделенной на несколько фрагментов. Каждый фрейм имеет оператор, а каждый фрагмент может иметь защиту. (В табл. 2 перечислены общепринятые операторы для фреймов взаимодействия.) Для отображения цикла применяется оператор loop с единственным фрагментом, а тело итерации помещается в защиту. Для условной логики можно использовать оператор alt и помещать условие в каждый фрагмент. Будет выполнен только тот фрагмент, защита которого имеет истинное значение. Для единственной области существует оператор opt. Таблица2.Общепринятыеоператорыдляфреймоввзаимодействия
Синхронные и асинхронные вызовыЕсли вы были внимательны, то заметили, что стрелки в последней диаграмме отличаются от предыдущих. Это небольшое отличие достаточно важно в UML версии 2. Здесь закрашенныестрелкипоказываютсинхронноесообщение,апростыестрелкиобозначаютасинхронноесообщение. Если вызывающий объект посылает синхронное сообщение (synchronous message), то он должен ждать, пока обработка сообщения не будет закончена, например при вызове подпрограммы. Если вызывающий объект посылает асинхронное сообщение (asynchronous message), то он может продолжать работу и не должен ждать ответа. Асинхронные вызовы можно встретить в многопоточных приложениях и в промежуточном программном обеспечении, ориентированном на сообщения. Асинхронность улучшает способность к реагированию и уменьшает количество временных соединений, но сложнее в отладке. Читая диаграмму последовательности, не спешите делать предположения о синхронности по виду стрелок до тех пор, пока не убедитесь, что автор умышленно нарисовал их разными. |