Создание UML-модели в среде Visual Paradigm 16.2. Система обработки заказов |
Пособие составлено доц. кафедры СП, канд. физ.-мат. наук Малышко В. В. Размещение на других ресурсах, а также коммерческое использование материалов, опубликованных в данном разделе, возможно только с разрешения авторов. По всем вопросам пишите: |
1. Обзор возможностей о среды Visual Paradigm 16.2 |
Запустив среду, указываем путь к рабочей области (workspace), в которой будет находиться файл нашего проекта. Если автоматически не появилось окно Workspace Launcher, Вы можете самостоятельно настроить путь к рабочей области через меню File -> Switch Workspace (или возможный вариант: Help -> Switch Workspace). Настроим вид окна приложения. Вкладка меню Window -> Application options -> General -> вкладка Appearance (или возможный вариант: меню -> Tools -> Application options -> General -> вкладка Appearance). Устанавливаем User Interface: Classic; Look & Feel Theme: Gray. Чтобы настройки вступили в силу, перезапускаем среду. Если Вы оставите настройку User Interface: Sleek, то вид окон и меню будет значительно отличаться. Далее в пособии будут приводиться скриншоты и для режима Sleek, а также возможные варианты пунктов меню и проч. Необходимо начинать не с пустого проекта, а с шаблона, в котором уже создана основная структура модели, добавлены стереотипы и проектные механизмы RDBMS-JDBC и XMLRPCInterchange. Загружаем архив шаблона [zip] с веб-странички курса. Разворачиваем его в рабочую область. В рабочей области появился каталог с пиктограммами стереотипов, описание стереотипов stereotypes.xml и файл проекта -- myProject.vpp. Откроем проект (перед открытием Вы можете переименовать файл проекта так, чтобы в имени была Ваша фамилия, номер группы и номер варианта первого задания, например, Obraztsov341var1.vpp). Чтобы использовать набор стереотипов технологии Unified Process, осуществим настройку. Меню Modeling -> Manage Stereotypes -> Import (или возможный вариант: вкладка меню Window -> Configuration -> Manage Stereotypes -> Import). Файл с описаниями стереотипов находится в workspace. Он называется stereotypes.xml. При импорте выберите способ разрешения конфликтов Overwrite All. Переключаемся в левом верхнем углу с закладки Diagram Navigator на закладку Model Explorer (или возможный вариант: закрываем Project Browser / клик на светло-серый крестик на сером заголовке окна; открываем Model Explorer и закрепляем его / Toggle auto-hide). После этого окно среды примет вид, показанный на рисунке 1.1.a в интерфейсе Classic, или вид на рисунке 1.1.b в интерфейсе Sleek. Рис. 1.1.a. Окно среды после создания модели (Classic). Рис. 1.1.b. Окно среды после создания модели (Sleek). В левой верхней части находится навигатор или браузер, показывающий структуру проекта и модели. Для наших целей больше всего подходит вторая закладка -- Model Explorer (или возможный вариант: Model Structure). Преимущественно будем использовать его. В этот браузер мы будем добавлять UML-диаграммы, пакеты, и другие составляющие модели с помощью контекстного меню. Правая часть окна состоит из редактора диаграмм. Согласно технологии Unified Process на верхнем уровне модель должна состоять из четырёх пакетов, называемых архитектурными представлениями. Каждый из них показывает будущую систему с определённой точки зрения. Архитектурное представление вариантов использования (Use Case View) содержит модель требований к создаваемой системе. Архитектурное логическое представление (Logical View) содержит логическую структуру системы, её организацию как набора взаимосвязанных классов, типов, интерфейсов и пакетов. Архитектурное представление реализации (Component View) описывает организацию компонентов, из которых осуществляется сборка системы, и интерфейсов, которые реализуют или используют эти компоненты. Архитектурное представление размещения (Deployment View) содержит модель вычислительной среды, в которой будет функционировать система. Выделите в браузере элемент Use Case View. Вызвав контекстное меню элемента Use Case View в браузере правым кликом, выберите пункт Open Use Case View Specification. Откроется полная спецификация элемента в виде отдельного окна с вкладками. На вкладке General указано имя элемента и его основные свойства. На вкладке Stereotypes Вы увидите его стереотипы. Там указано, что к этому элементу применён стереотип «architectural view», указывающий, что пакет является архитектурным представлением. Краткий обзор основных возможностей среды дан. Переходим к упражнениям по составлению UML-модели.
|
В софтверную компанию обратился директор мебельного магазина с контрактом на создание программной системы учёта заказов. Из-за наплыва клиентов учёт заказов на бумаге и в электронных таблицах перестал быть возможен. Создаваемая программная система должна решить эту проблему. Система должна обеспечивать следующие возможности: добавление сведений о новых заказах, изменение сведений о ранее введённых заказах, учёт хода выполнения заказов, учёт сведений об текущих остатках на складе. При получении сведений о новом заказе система должна также послать сообщение внешней программе -- бухгалтерской системе, которая выписывает счёт заказчику. Любой заказ может содержать одну или более, чем одну товарную позицию. Для каждой позиции заказа указывается наименование товара, цена, его количество, стоимость позиции заказа (равная произведению цены на количество). Сумма стоимостей позиций заказа даёт общую стоимость заказа. Заполненный заказ получает кладовщик, который начинает сборку заказа. Если для каждой позиции товара на складе находится товар в достаточном количестве, то товар резервируется, и заказ помечается собранным, готовым к отправке заказчику. Если требуемого товара нет на складе, то заказ может быть отменён, либо выполнение заказа задерживается до поступления товара на склад. Текущие цены товаров -- предметов мебели -- меняются с ходом времени. Система должна позволять изменить цену товару. Изменение цены товара не влияет на цены и стоимости в ранее введенных заказах, в позициях которых есть этот товар. Ассортимент товаров также подвержен изменениям. Система должна позволять добавлять сведения о новых товарах, делать пометки о том, что товар больше не продаётся. |
Выполняя упражнения, мы сразу переходим к созданию модели требований к системе, минуя моделирование бизнес-процессов. Позволительно так поступать в случаях, когда предметная область, для которой разрабатывается система, сравнительно проста или хорошо знакома разработчикам. Определение требований к системе -- один из процессов жизненного цикла. В ходе этого процесса определяются задачи, поставленные перед разработчиками, и создаются модели, на основе которых планируется разработка системы. Требование к системе -- это условие, которому должно удовлетворять создаваемое программное обеспечение, или свойство, которым оно должно обладать, чтобы удовлетворить потребность пользователя в решении некоторой задачи, или чтобы соответствовать условиям контракта, спецификации или стандарта. Все требования к системе делятся на функциональные и нефункциональные. Функциональные требования к системе определяют действия, которые должна выполнять система, без учёта ограничений, связанных с её реализацией. Нефункциональные требования к системе не определяют поведение системы, но описывают её свойства или атрибуты системного окружения. Например, нефункциональными являются требования к производительности системы и требования к аппаратуре, на которую может быть установлена система. Требования к системе оформляются в виде ряда документов и моделей. К основным документам, согласно технологии Unified Process, относятся: концепция, глоссарий предметной области, дополнительная спецификация. Концепция определяет глобальные цели проекта и основные особенности разрабатываемой системы. Существенной частью концепции является постановка задачи разработки, определяющая функциональные требования к системе. Словарь предметной области (глоссарий) определяет общую терминологию для всех моделей системы и описаний требований к системе. Дополнительная спецификация (технические требования к системе) содержит описание нефункциональных требований к системе, таких, как надёжность, удобство использования, производительность, сопровождаемость и других. Постановка задачи разработки системы обработки заказов: Пользователями новой системы будут продавцы и работники склада (заведующий и кладовщики). База данных системы будет поддерживаться реляционной СУБД. Система должна обеспечивать возможность продавцам вводить сведения о новых заказах и изменять сведения о заказах, хранящиеся в системе. Сведения о заказе могут быть изменены до тех пор пока ведётся работа на складе по его сборке. Собранные заказы поставляются заказчикам, внесение изменений в сведения о них запрещено. Дата окончания сборки заказа хранится в системе. По её наступлении заказ считается собранным. Не собранные заказ может быть отменен. Сведения об отменённых заказах изменению не подлежат. При вводе сведений о заказе важно сохранить дату, когда был принят заказ, и дату, до которой нужно осуществить сборку и доставку заказа. Каждый заказ содержит одну или несколько позиций. В любой позиции указывается наименование предмета мебели, количество штук, цена предмета мебели и стоимость позиции, вычисляемая как произведение количества на цену. Общая стоимость заказа вычисляется как сумма стоимостей всех его позиций. После ввода заказа данные передаются в бухгалтерскую систему для составления счёта на оплату. Работают несколько продавцов, поэтому необходимо обеспечить защиту данных, чтобы продавец мог работать только с собственными заказами, и не имел доступа к данным чужих заказов. Продавец может удалить данные о любом из своих заказов (но не о чужом). Заведующий складом использует систему, чтобы работать с данными об остатках -- описями, в которых указываются текущие (на момент составления описей) количества предметов мебели на складе. Остатки определяются системой по данным последней инвентаризации и данным о выполнении заказов. Например, если по данным инвентаризации было 10 стульев и 8 стульев отмечены как собранные позиции заказов введённых после инвентаризации, (т. е. стулья переданы заказчикам или отложены в собираемые заказы), то текущий остаток -- 2 стула. При проведении инвентаризации для каждого предмета мебели со склада текущее его количество заносится в опись. Данные из описи вводятся в систему. Относительно этих данных будут рассчитываться остатки до ввода следующей описи. Также заведующий складом работает со сведениями о предметах мебели: добавляет их, обновляет цены, удаляет. Кладовщики отмечают в системе ход сборки заказов. Любой кладовщик может работать с любым заказом. Кладовщик может пометить какую-либо позицию заказа как собранную. При этом соответствующее количество предметов мебели вычитается при расчёте текущих остатков. Если собраны все позиции заказа, он также считается собранным. Кладовщик может пометить не собранный заказ как отменённый, если нужного для полной сборки заказа предмета мебели на складе нет (или если он есть, но в недостаточном количестве). При отмене заказа снимается резерв с собранных позиций отменённого заказа и, соответственно, увеличиваются остатки. Глоссарий предметной области создаётся на основе концепции, описания системы обработки заказов и на основе постановки задачи, а также на основе глоссария деловой деятельности предприятия (бизнес-глоссария), созданного в ходе бизнес-моделирования. Глоссарий предназначен для фиксации общей терминологии области, в которой будет работать ПО. Выделяются термины, им даётся описание, рассчитанное на широкий круг читателей (пользоваться этим описанием будут все лица, заинтересованные в разработке системы). Глоссарий составляется на русском языке. Термины сопровождаются переводом на английский на тот случай, если термин будет использован в модели системы как название класса, типа, интерфейса, пакета и т. п.. Глоссарий: |
Бухгалтерская система | Внешняя система, в которую передаются данные обо всех введённых заказах. |
Заведующий складом | Пользователь системы. Имеет возможность работать с данными об остатках (вносить данные новой описи, просматривать и распечатывать данные описей, введённых ранее, удалять неактуальные данные описей, узнать остатки, рассчитанные по данным описей и принятых заказов). |
Заказ | Непустой перечень требуемых заказчиком позиций. Дата заказа указывает момент его создания. Дата поставки заказа отмечает день, к которому должны быть завершены работы по сборке и поставке заказа. Дата сборки заказа указывает день, когда была помечена выполненной последняя из не собранных позиций заказа. Общая стоимость заказа вычисляется как сумма стоимостей его позиций. |
Заказчик | Покупатель мебельного магазина. Данные о покупателе включают в себя ф., и., о., список его телефонов, адрес для доставки мебели. |
Инвентаризационная опись | Перечень, в котором для каждого предмета мебели, хранящегося на складе, указано его количество, имеющееся в наличии на дату, когда была составлена опись. |
Кладовщик | Пользователь системы. Работник склада, отвечающий за сборку заказов. Может помечать позиции заказов как собранные, а заказы, сборка которых не успешна -- как отменённые. |
Остатки | Данные о количестве предметов мебели на складе, рассчитываемые по сведениям из последней описи и данным о собранных позициях заказов. |
Позиция заказа | Один или более одинаковых предметов мебели, указанных в заказе. Позиция характеризуется наименованием, количеством, стоимостью, порядковым номером в заказе и статусом (собрана или нет). Стоимость позиции вычисляется как произведение количества на цену предмета мебели (ту, какой она была при внесении позиции в заказ). |
Предмет мебели | Предмет обстановки, хранящийся на складе. Может быть указан в позиции заказа. Характеризуется наименованием и текущей ценой. Количество предметов мебели, имеющихся на складе, указывается в инвентаризационных описях. |
Продавец | Пользователь системы. Автор произвольного количества заказов. Может вводить заказы и изменять введённые им ранее заказы. |
Дополнительная спецификация определяет нефункциональные требования к системе, такие, как надёжность, удобство использования, производительность, сопровождаемость, а также ряд функциональных требований, являющихся общими для нескольких вариантов использования. Назначение дополнительных спецификаций -- определить требования к системе обработки заказов, которые не отражены в других документах и моделях. Вместе они образуют полный набор требований к системе. Рассмотрим дополнительную спецификацию:
Функциональные требования к системе моделируются и документируются с помощью вариантов использования (use case). Вариант использования (use case) -- связный элемент функциональности, предоставляемый системой при взаимодействии с действующими лицами. Действующее лицо (actor) -- роль, обобщение элементов внешнего окружения системы, ведущих себя по отношению к системе одинаковым образом. Такие роли исполняют либо пользователи системы, либо внешние программы, взаимодействующие с системой. Изредка роль действующего лица исполняет некий невычислительный процесс, протекающий во внешней среде: ход времени, изменение температуры воздуха и т. п.. В контексте процесса определения требований к системе варианты использования трактуются следующим образом:
Модель вариантов использования состоит из диаграмм вариантов использования, текстовых описаний вариантов использования и диаграмм деятельности, моделирующих сценарии вариантов использования. Сценарии также принято называть потоками событий. UML-диаграмма вариантов использования составляется системным аналитиком, который сначала выявляет элементы модели, а затем устанавливает связи между ними, а также структурирует модель. Элементами диаграмм вариантов использования являются варианты использования и действующие лица, соединённые разного рода связями. Из постановки задачи разработки и глоссария системный аналитик может выделить для системы обработки заказов список действующих лиц и их интересов:
|
Упражнение 3.1. Построение начальной версии UML-диаграммы вариантов использования |
1. В Model Explorer найдите пакет Use Case View, а внутри него модель Use Case Model. В модели находится UML-диаграмма вариантов использования Main. Откройте её двойным кликом. UML-диаграмма пуста. Если Вы работаете на FullHD-дисплее или с ещё большим разрешением, то желательно установить увеличение 130% или выше (Ctrl+), чтобы Ваши UML-диаграммы были обозримы на обычном дисплее. С таким увеличением все элементы UML-диаграммы и все связи между ними должны помещаться на экране. В палитре найдите элемент System. Нажмите на него. Затем поместите курсор на диаграмму и кликните. Система появится на диаграмме. Назовите добавленный элемент Система обработки заказов. Этим элементом в модели представляется рамка моделируемой программной системы. С помощью контекстного меню добавьте системе стереотип «subject». В палитре редактора выберите элемент Actor и добавьте действующее лицо на диаграмму. Введите имя актора: Продавец. Повторите те же действия и добавьте оставшихся действующих лиц: заведующего складом, кладовщика, бухгалтерскую систему. Увеличьте размеры элемента System, чтобы он вместил варианты использования системы. Получившаяся UML-диаграмма примет вид, показанный на рисунке 3.1.1. Рис. 3.1.1. UML-диаграмма вариантов использования после добавления действующих лиц (для всех вариантов) Исходя из потребностей действующих лиц, системный аналитик может предложить следующие варианты использования: CRUD данных о заказах, CRUD данных об остатках, CRUD данных о предметах мебели, Собрать заказ, Отменить заказ. Все эти варианты использования относятся к «уровню моря», т. е. соответствуют цели одного из пользователей системы. Такую цель пользователь может достичь в течение одного сеанса работы с системой. CRUD рашифровывается как Create, Read, Update, Delete (или как Create, Retrieve, Update, Destroy). Предполагается, что вариант использования CRUD данных о заказах описывает все функции системы, предоставляемые продавцу для управления сведениями о заказах. CRUD данных об остатках описывает все функции системы, предоставляемые заведующему складом для управления сведениями об остатках. CRUD данных о предметах мебели описывает все функции системы, предоставляемые заведующему складом для управления сведениями о предметах мебели. Варианты использования Войти в систему и Выйти из системы не соответствуют какой-либо явной цели какого-нибудь действующего лица. Они описывают функциональные требования к системе по обеспечению защиты данных. Про каждого своего пользователя система должна знать, какую роль по отношению к ней он выполняет: продавца, заведующего складом, кладовщика, к каким функциям и данным ему можно предоставлять доступ. Эти варианты использования не относятся к «уровню моря». Такого рода служебные варианты использования относят к «уровню рыбы», т. е. считают соответствующими подфункциям. 1. В палитре редактора выберите элемент Use Case и добавьте вариант использования на диаграмму (внутрь System). Введите название: CRUD данных о заказах. Повторите те же действия для добавления оставшихся вариантов использования: CRUD данных об остатках, CRUD данных о предметах мебели, Собрать заказ, Отменить заказ, Войти в систему, Выйти из системы. Каждый вариант использования пометьте стереотипом, указывающим его уровень. Для этого вызовите контекстное меню правым кликом, выберите пункт Stereotypes и укажите нужный стереотип в списке. Разместите варианты использования примерно так, как показано на рисунке 3.1.2. 2. В палитре редактора выберите ассоциацию Association и проведите её от действующего лица Продавец к варианту использования CRUD данных о заказах. Чтобы было видно направление связи, вызовите контекстное меню у левого конца ассоциации и выберите пункт Navigable. Установите флажок на значении Unspecified. По умолчанию связь была двунаправленная, теперь же она явно указывает, направление от действующего лица к варианту использования. 3. Повторите те же действия для добавления остальных ассоциаций между действующими лицами и вариантами использования. Получившаяся UML-диаграмма вариантов использования изображена на рис. 3.1.2. Направления ассоциаций между действующими лицами и вариантами использования показывают, какое лицо является основным для некоторого варианта использование, а какое -- второстепенным. Для варианта использования CRUD данных о заказах действующее лицо Продавец -- основное (оно инициирует запуск варианта использования), а действующее лицо Бухгалтерская система -- второстепенное (сведения о заказах пересылаются в бухгалтерскую систему). 4. Добавьте связь расширения (Extend) от варианта использования Отменить заказ к варианту использования Собрать заказ. Связь расширения показывает, что в ходе выполнения варианта использования Собрать заказ могут возникнуть условия, при которых реализуется особый сценарий, описываемый вариантом использования Отменить заказ. Заметим, что переключение происходит не всегда. Обратите внимание, что рисовать связь следует, указав сначала расширяемый вариант использования (в который входит стрелка), а затем -- расширяющий (из которого исходит связь). Переименовать точку расширения можно, открыв спецификацию расширяемого варианта использования через контекстное меню (контекстное меню -> Open specification), и перейдя на вкладку Extension Points. Рис. 3.1.2. Начальная версия UML-диаграммы вариантов использования (для всех вариантов) (на диаграмме имеется дефект!) |
Упражнение 3.2. Построение уточнённой версии UML-диаграммы вариантов использования |
5. Созданная UML-диаграмма имеет недостаток в том, что у вариантов использования Войти в систему и Выйти из системы несколько основных действующих лиц. Стандартное её прочтение предполагает, что при входе в систему и при выходе из системы с ней взаимодействуют одновременно три экземпляра действующего лица -- один продавец, один кладовщик и один заведующий. Полагая поведение системы одинаковым при входе любого пользователя, полагая что вход в систему каждый пользователь производит сам по себе, введём абстрактное действующее лицо Пользователь, подвидами которого будут лица Продавец, Заведующий складом, Кладовщик. Указать, что действующее лицо является абстрактным, нужно в спецификации (контекстное меню -> Open specification) на вкладке General, поставив флаг в поле Abstract. Другой вариант: контекстное меню -> Model Element Properties -> Abstract. Для добавления связей обобщения используйте элемент палитры Generalization. Лишние ассоциации удалите из модели, выделяя их в Model Explorer и нажимая Del. Чтобы связи отображались в Model Explorer, осуществите его настройку: вызовите контекстное меню на белом поле Model Explorer и отметьте флажками Show Relationships. Обратите внимание, что лишний элемент (или связь) следует удалить из модели (выделяя их в Model Explorer и нажимая Del). Если необходимо сохранить элемент (или связь) в модели и всего лишь убрать с UML-диаграммы, на которую он случайно попал по какой-то причине, выделите элемент или связь на диаграмме и используйте пункт контекстного меню Delete -> Delete View Only. Следует чётко понимать, удаляете ли Вы текущий элемент из модели или всего лишь убираете с UML-диаграммы, оставляя в модели (маскируете). Удаление вместо маскирования (как и обратное) может быть нежелательным. Случайно удалённый элемент можно попытаться восстановить, нажав Ctrl+z. Маскированный по ошибке элемент можно снова поместить на диаграмму, перетаскивая его из Model Explorer. Маскированную по ошибке связь можно снова поместить на диаграмму с помощью контекстного меню одного из связываемых ей элементов (Related Elements -> Visualize Related Model Element, флаг Visualize, кнопка Visualize). Работать с моделью следует аккуратно, не оставляя в ней «мусора» -- случайно созданных элементов и/или связей, не видимых на UML-диаграммах. UML-диаграмма вариантов использования должна принять вид, изображённый на рисунке 3.2.1. Рис. 3.2.1. Уточнённая версия UML-диаграммы вариантов использования (для всех вариантов / дефект начальной версии исправлен!) Теперь на нашей диаграмме каждый вариант использования связан ровно с одним действующим лицом, которое для него является основным, и с произвольным количеством дополнительных действующих лиц. Каждое действующее лицо прямо или косвенно связано хотя бы с одним вариантом использования. Никакие два варианта использования между собой не связаны ассоциацией. Связи между вариантами использования допускаются, если они имеют тип, отличный от ассоциации. Это могут быть связи обобщения, включения и расширения. О них рассказывается на лекциях. Системный аналитик с их помощью производит структурирование модели вариантов использования. Модель с большим количеством вариантов использования может быть разбита им на части -- пакеты. Никакие действующие лица не связаны между собой ассоциацией. Между ними допускаются лишь связи обобщения. Самостоятельно создавая UML-диаграммы вариантов использования, старайтесь, чтобы их элементы и связи удовлетворяли таким же ограничениям. Также рекомендуется действующих лиц, являющихся ролями пользователей-людей, размещать в левой части UML-диаграммы, а остальных, являющихся ролями программных систем или невычислительных процессов -- на правой. Рекомендуется родительские элементы в иерархии наследования/обобщения размещать выше и/или левее их сыновних элементов (наследников). Получившаяся UML-диаграмма является примерным оглавлением проекта. Мы видим, какие функции и кому предоставляет система. По ней архитектор проекта может составить примерную оценку трудоёмкости всего проекта, основанную на прогнозируемой трудоёмкости реализации каждого из вариантов использования. Также архитектор может ранжировать варианты использования по приоритету. Отмеченные им более важные варианты использования будут проанализированы, спроектированы и реализованы в первую очередь. Для каждого варианта использования составляется описание. Выполняют эту работу use case писатели.
|
Упражнение 3.3. Составление описаний вариантов использования |
Функциональные требования к системе подробно фиксируются в описаниях вариантов использования. Описания составляются специальным образом, чтобы уменьшить вероятность неверного толкования и облегчить однозначное восприятие текста. Каждое описание включает в себя: Каждый поток событий задаётся перенумерованным набором шагов. Используются шаги трёх типов: действие системы (например, «Система запрашивает имя пользователя и пароль»); реакция действующего лица («Пользователь вводит имя и пароль»); управление потоком («Выполнение переходит на начало основного потока»). Структура предложений, описывающих шаги, одинакова: подлежащее, сказуемое и прочее. От неё отходят лишь при описании циклов и ветвлений. Цикл задаётся составным описанием, в начале которого указывается условие цикла («Для каждой позиции нового заказа выполняется:») или количество повторений. Далее следует тело цикла -- последовательность вложенных шагов (см. подчинённый поток «4А. Ввести заказ» варианта использования «CRUD данных о заказах»). Чаще ветвление описывают с помощью альтернативных потоков. В основном потоке варианта использования «Войти в систему» 4-й шаг -- шаг подтверждения -- указывает основное продолжение потока, а альтернативный поток «4А. Неправильное имя/пароль» содержит второй вариант развития событий и начинается с шага обнаружения. Почти всегда действия по проверке условия ветвления не описывают. Вместо этого указывается шаг на котором система (или действующее лицо) подтверждает, что условие выполнено, в основном потоке, и другой шаг, где система обнаруживает, что условие нарушено, в альтернативном потоке. Соберите в единый текстовый файл описания, приведённые ниже. Для этого скопируйте тексты описаний в окно текстового редактора (Word, Writer и т. п.) и сохраните в формате pdf. Обратите внимание, что в описании любого варианта использования должен присутствовать хотя бы один шаг для каждого действующего лица, связанного с ним ассоциацией. Постусловие в описании не может отсутствовать, так как по нему тестировщики составляют тестовые сценарии. Постусловие состоит из двух частей: гарантии успеха и минимальных гарантий. Первая часть описывает, что должно быть истинно при успешном завершении варианта использования. Вторая часть -- это гарантии системы во всех случаях, в том числе в случаях неуспеха. Например, при успешном входе в систему гарантируется доступ пользователя к главному меню, но в любом случае (даже при неуспехе) -- гарантируется, что доступ не будет предоставлен тем, кто не может указать верную комбинацию пароля и логина. Пустое постусловие допускало бы произвольное поведение системы и было бы не пригодно для тестирования. Неполное постусловие без минимальных гарантий (описывающих, что система не должна предоставлять доступ при неудачном входе) также непригодно. Обратите внимание, что следует явно указывать шаг неуспешного завершения варианта использования. Шаг успешного завершения обычно явно не указывают, если он находится в конце основного потока событий. В реальном рабочем процессе описания составляются для всех вариантов использования. Выполняя упражнения, мы создадим лишь два полных описания, а остальные опишем кратко. Вариант использования «Войти в систему»: Краткое описание: Описывается вход пользователя в систему. Область действия: система как «чёрный ящик». Уровень: подфункция («уровень рыбы»). Основной поток событий: Обратите внимание на номер альтернативного потока. Цифра указывает номер шага основного потока, на котором может произойти переключение на альтернативный поток, буква позволяет различить несколько альтернативных потоков, на которые можно переключиться на одном и том же шаге. Если переход на альтернативный поток может происходить в течение нескольких подряд идущих шагов, указывают их номера через дефис (например, 1-3Б). Если поток вызывается из разных шагов, он может иметь несколько номеров, перечисленных через запятую. Вариант использования «CRUD данных о заказах»: Краткое описание Область действия: система как «чёрный ящик». Уровень: цель пользователя («уровень моря»). Основной поток событий: Для остальных вариантов использования мы составим только краткие описания. В рамках работ по определению требований в ходе одной итерации допускается составлять полные описания лишь для нескольких приоритетных вариантов использования. Менее приоритетные варианты использования описываются кратко. Их полные описания могут быть составлены на последующих итерациях. Вариант использования «Собрать заказ»: Точки расширения Краткое описание Область действия: система как «чёрный ящик». Уровень: цель пользователя («уровень моря»). Вариант использования «Отменить заказ»: Краткое описание Область действия: система как «чёрный ящик». Уровень: цель пользователя («уровень моря»). Вариант использования «CRUD данных об остатках»: Краткое описание Область действия: система как «чёрный ящик». Уровень: цель пользователя («уровень моря»). Вариант использования «CRUD данных о предметах мебели»: Краткое описание Область действия: система как «чёрный ящик». Уровень: цель пользователя («уровень моря»). Вариант использования «Выйти из системы»: Краткое описание Область действия: система как «чёрный ящик». Уровень: подфункция («уровень рыбы»). |
Упражнение 3.4. Построение UML-диаграмм деятельности для сценариев вариантов использования |
Все потоки событий одного варианта использования, взаимосвязанные сценарии двух и более вариантов использования или отдельный поток событий могут быть смоделированы на UML-диаграммах деятельности. Постройте диаграмму деятельности для варианта использования Войти в систему. 1. В браузере вызовите контекстное меню варианта использования Войти в систему и выберите Subdiagrams -> New diagram. В открывшемся окне укажите тип создаваемой UML-диаграммы: Activity diagram. 2. На появившейся в редакторе диаграмме создайте два раздела (Vertical Swimlane) -- Пользователь, Система обработки заказов -- каждый из которых обозначает область ответственности. Свяжите каждый раздел с элементом модели, который он представляет, в окне спецификации на вкладке General в поле Represents (первый -- с актором Пользователь, второй с системой). Узлы действия, которые будут расположены в области ответственности пользователя, описывают действия пользователем, остальные -- действия системы. Входной узел (Initial Node) поместите в раздел Пользователь. Заметьте, что если бы с вариантом использования были бы связаны два действующих лица, на диаграмме следовало бы создать три раздела (два для действующих лиц и один для системы). 3. Согласно описаниям потоков событий варианта использования создайте узлы действий (Action): запустить приложение, запросить имя и пароль; ввести имя и пароль; проверить имя и пароль; сообщить об ошибке; определить тип пользователя и вывести главное меню. Узлы действий разместите по разделам в соответствии с тем, кто выполняет действия. 4. Добавьте узел логического ветвления (Decision Node). Соедините узлы рёбрами потоков управления (Control Flow). Задать сторожевые условия можно, открыв спецификацию потока, на вкладке General в поле Guard (или выбрав пункт Guard в контекстном меню при потоке). Не следует указывать сторожевые условия в названиях потоков управления. 5. Добавьте два узла завершения деятельности (Activity Final Node) с именами, указывающими на успешное и безуспешное завершение варианта использования. Вид получившейся UML-диаграммы представлен на рис. 3.4.1.
Рис. 3.4.1. UML-диаграмма деятельности для варианта использования «Войти в систему» (для всех вариантов) UML-диаграмма деятельности описывает пути передачи управления между узлами. Изначально курсор управления порождается во входном узле. Оттуда он передаётся по ребру на вход узла действия (запустить приложение). Узел действия ждёт, когда курсоры управления придут на все входящие ребра, после чего запускается действие, а по окончании действия курсоры управления подаются на все исходящие из узла действия ребра. Когда курсор попадает в узел логического ветвления, проверяются сторожевые условия на всех исходящих рёбрах этого узла. Исходящих рёбер может быть два и более. По одному из рёбер, на котором сторожевое условие истинно, курсор управления передаётся дальше. Если таких рёбер (с истинными сторожевыми условиями) несколько, то случайным образом выбирается одно. Если все сторожевые условия ложны, то курсор не может быть передан дальше. Поток управления заблокирован, а UML-диаграмма нарушает правила стандарта языка. Во избежание ошибок следует внимательно формулировать сторожевые условия. Рекомендуется делать их взаимоисключающими и покрывающими все возможные случаи. Часто используется условие [else], способствующее выполнению этих требований. При попадании курсора управления в (любой) узел завершения деятельности вся деятельность прекращается. Уничтожаются все курсоры управления на всех рёбрах UML-диаграммы. В случаях, когда требуется остановить один поток, оставив другие активными, применяется узел завершения потока (Flow Final Node), изображаемый кружком с крестиком. Самостоятельно постройте диаграмму для варианта использования «CRUD данных о заказах». Обратите внимание на то, что подчинённый поток может быть представлен на диаграмме в виде одного узла (см. узлы «Ввести заказ», «Изменить заказ», «Удалить заказ»). Тип этих узлов -- Call Behavior Action Node (узел действия вызова деятельности). С каждым из них связана деятельность, которая может быть промоделирована отдельной диаграммой деятельности. При создании UML-диаграммы следует сначала создать в Model Explorer внутри варианта использования три деятельности (Activity): Ввести заказ, Изменить заказ, Удалить заказ. Затем разместите на диаграмме деятельности три узла действия (Action). В окне спецификации каждого созданного узла на вкладке General в поле Type укажите тип узла: Call Behaviour Action, после чего нажмите на кнопку с многоточием. В открывшемся окне выберите подходящую деятельность. Рис. 3.4.2. UML-диаграмма деятельности варианта использования «CRUD данных о заказах» (для всех вариантов) Обратите внимание на то, что если деятельности созданы в корне проекта, то следует перетащить их внутрь варианта использования «CRUD данных о заказах» в браузере модели. Может оказаться, что какая-то UML-диаграмма создана Вами в корне проекта, а не внутри элемента проекта. Перетащить диаграмму в нужное место Model Explorer не даёт. Тем не менее, переместить диаграмму из корня можно. Откройте спецификацию UML-диаграммы. На закладке General второе сверху поле Parent model: <No parent model>. Нажмите "..." и укажите нужный элемент проекта как родительскую модель для UML-диаграммы. В браузере модели поддерево проекта Use Case View (соответствующее архитектурному представлению вариантов использования из модели «4+1») должно иметь примерно такой вид, как указано на рисунке 3.4.3. Действующие лица должны находиться в корне Use Case Model; варианты использования -- внутри рамок системы; UML-диаграммы деятельности -- внутри соответствующих вариантов использования; деятельности, которые моделируют подчинённые потоки варианта использования CRUD данных о заказах -- внутри этого варианта использования.
Рис. 3.4.3. Структура архитектурного представления Use Case View в браузере модели (для всех вариантов) Моделирование требований к системе следовало бы продолжить дальше, описав все варианты использования и построив для них UML-диаграммы деятельности. Однако, не имеет смысла сразу описывать все требования к системе. Работа осуществляется последовательными итерациями, в ходе которых составляются описания отдельных вариантов использования в порядке их важности. Когда описания важных вариантов использования составлены, выполняются работы по эскизному и проектному моделированию частей системы, реализующих их. Use case писатели приступают к работе над менее приоритетными вариантами использования во время последующих итераций, или занимаются ими на той же итерации, если они мало загружены. Следует быть готовыми к изменчивости требований к системе в ходе проекта. Нестабильность требований обусловлена тем, что заказчики и будущие пользователи системы не могут сразу точно указать свои пожелания, и тем, что по ходу проекта разработчики лучше узнают предметную область и контекст системы. Из-за изменения требований к системе переделываются описания вариантов использования, исправляются UML-диаграммы деятельности. |
При эспизном моделировании системы производится трансформация требований в системный проект, создание эскизной архитектуры, соответствующей функциональным требованиям к системе. Эскизная архитектура включает в себя набор ключевых абстракций, набор классов анализа, перечень механизмов анализа, иерархию уровней системы, реализации вариантов использования. В ходе жизненного цикла эскизная архитектура подлежит уточнению, на её основе создаётся проектная архитектура, учитывающая нефункциональные требования и подлежащая реализации в коде. Эскизное моделирование нацелено на прояснение проблемы, решаемой в проекте, построение её решения, простого насколько это возможно, но удовлетворяющего функциональным требованиям к системе. Создание эскизной модели разбивается на несколько итераций, в ходе каждой из которых выполняется моделирование реализации части вариантов использования. Работа ведётся в соответствии с приоритетом вариантов использования. Самые важные варианты использования берутся в работу в первую очередь. Результаты каждой итерации интегрируются в общую модель. При эскизном моделировании последовательно выполняются два вида работ: архитектурный анализ и анализ вариантов использования. Исполнителями эскизного моделирования являются архитектор, разработчик. Обязанности архитектора состоят в координации и в руководстве выполнением технологических операций, в определении структуры каждого архитектурного представления, осуществлении архитектурного анализа. Обязанности разработчика включают: анализ вариантов использования; определение для анализируемых классов их обязанностей, поведения и свойств, а также связей между ними. Архитектурный анализ выполняется архитектором и включает в себя следующие технологические операции:
Соглашения моделирования фиксируются в документе «Руководящие указания по проектированию» (Design Guidelines). Они определяют: перечень используемых диаграмм и элементов модели; правила применения диаграмм; соглашения по именованию элементов модели; организацию модели (пакеты). Будем придерживаться следующих соглашений моделирования:
|
Упражнение 4.1. Построение структуры логического архитектурного представления в соответствии с соглашениями моделирования |
Рис. 4.1.1. Структура эскизной модели в браузере проекта (для всех вариантов) 1. В эскизную модель Analysis Model добавьте пакет Use Case Realizations. Для этого в браузере проекта вызовите контекстное меню меню пакета Analysis Model, Model Element -> Package (или Model Element -> New Model Element -> Model element type: Package). 2. В пакет Use Case Realizations добавьте две кооперации (Collaboration) Login и CRUDOrders (контекстное меню пакета -> Model Element -> New Model Element -> Model element type: Collaboration). Назначьте каждой созданной кооперации стереотип «usecase realization». Каждая кооперация описывает сценарии одного из вариантов использования: Login -- Войти в систему, CRUDOrders -- CRUD данных о заказах. В пакете Use Case Realizations создайте диаграмму вариантов использования (Use Case Diagram), на которой покажите связи между вариантами использования и их реализациями. Перетащите кооперации и варианты использования из браузера модели на созданную диаграмму. Проведите связи реализации (Realization, этот тип связи можно найти в палитре, если открыть выпадающий список у связи Generalization) между кооперациями и теми вариантами использования, которые они реализуют. Важно, чтобы стрелки у связей показывали в направлении от коопераций к реализуемым вариантам использования. Получившаяся UML-диаграмма примет вид, показанный на рис. 4.1.2. Рис. 4.1.2. UML-диаграмма Use Case Realizations (для всех вариантов) 3. Внутри каждой кооперации -- реализации варианта использования -- создайте диаграмму последовательности BasicFlow (LoginBasicFlow, CRUDOrdersBasicFlow) и диаграмму классов VOPC (LoginVOPC, CRUDOrdersVOPC). Воспользуйтесь контекстным меню кооперации -> Sub Diagrams -> New Diagram -> Sequence Diagram / Class Diagram. UML-диаграмма последовательности BasicFlow служит для моделирования реализации основного сценария варианта использования (возможно, вместе с его альтернативными сценариями). Назначение диаграмм классов VOPC (сокращение View Of Participating Classes) -- отображение классов, экземпляры которых участвуют в реализации варианта использования, и связей между этими классами. 4. Если в заготовке проекта нет UML-диаграммы классов Key Abstractions в корне пакета Analysis Model, то создайте её. Контекстное меню пакета Analysis Model-> Sub Diagrams -> New Diagram -> Class Diagram. Дополнительно в кооперацию CRUDOrders внутри взаимодействия CRUDOrdersBasicFlow (тип элемента модели -- Frame) добавьте три UML-диаграммы последовательности, моделирующие реализации подчинённых потоков: CreateOrderSubflow, UpdateOrderSubflow, DeleteOrderSubflow (контекстное меню взаимодействия -> Sub Diagrams -> New Diagram -> Sequence Diagram). Моделирование каких-то вспомогательных взаимодействий на отдельных UML-диаграммах последовательности оправдано, так как размер диаграмм остаётся приемлемым, чтобы использовать их как иллюстрации в отчётах, и чтобы видеть диаграмму целиком на экране. Структура эскизной модели в браузере должна соответствовать рис. 4.1.1. 5. В модели Analysis Model присутствует UML-диаграмма классов Key Abstractions. На ней будут представлены классы, представляющие собой основные абстракции предметной области. Каждый из них является абстрактным типом данных, имеющим отношение к предметной области -- к обработке заказов мебельного магазина. Откройте диаграмму ключевых абстракций двойным щелчком в Model Explorer. Ключевые абстракции -- основные понятия предметной области -- архитектор выделяет, анализируя требования и пользуясь, глоссарием и моделью бизнес-анализа, если таковая была создана. Каждый термин из глоссария является кандидатом для того, чтобы быть трансформированным в класс ключевой абстракции (или в несколько классов, если структура данных, связанная с ним, слишком сложна для представления одним классом). Некоторые термины могут быть источником для атрибутов классов. В системе обработки заказов можно выделить следующие ключевые абстракции: Order (данные о заказе), OrderItem (данные о позиции заказа), ArticleOfFurniture (данные о предмете мебели), Client (данные о заказчике), User (учётная запись пользователя системы), Inventory (инвентаризационная опись), InventoryItem (позиция описи с данными об остатке мебели на складе). Ассоциации между абстракциями показывают типы соединений между экземплярами ключевых абстракций. Мощности у полюсов указывают ограничения на количество соединений у одного экземпляра. Ассоциация может быть рефлексивной, т. е. соединяющей класс с ним самим. Такая связь описывает соединения между разными экземплярами одного класса. Чтобы различать роли объектов, участвующих в таких соединениях, полюсам рефлексивных ассоциаций обязательно дают имена. Также поступают при наличии двух ассоциаций между одной парой классов. Иногда имена полюсов указывают, чтобы пояснить назначение конкретной ассоциации. На диаграмме классов помимо ассоциаций могут присутствовать и другие связи. Так, связь между классом User и перечислимым типом UserType, указывает, что описание класса зависит от описания типа (так как атрибут User::type имеет тип UserType). Ещё одна зависимость указывает на то, что в описании атрибута Order::status используется перечислимый тип OrderStatus. Рис. 4.1.3. UML-диаграмма классов Key Abstractions (ключевых абстракций) (для всех вариантов) Предварительно настройте среду для более удобной работы. Меню Tools -> Project Options -> Diagramming (вариант: Window -> Project Options -> Diagramming). На вкладке Association отмените отображение уникальности (Show multiplicity constraints -- Unique). По умолчанию любая пара объектов, связывается не более чем одним соединением, являющимся экземпляром одной ассоциации. Если необходимо допустить повторные соединения, уникальность соединения следует отменить. Там же укажите необходимость явно выводить мощность полюса, равную 1 (снимите флажок Suppress implied "1" multiplicity). Перейдите к вкладке Class. Выберите вложенную вкладку Presentation. Снимите флажок отображения классов в виде пиктограмм стереотипов (Display as Robustness Analysis icon). Сохраните настройки, закройте окно настроек проекта. Снятие флажка Suppress implied "1" multiplicity может потребоваться дополнительно на каждой диаграмме классов. Вызовите контекстное меню на поле UML-диаграммы классов, нужный флажок спрятан в Presentation Options. Также в Presentation Options UML-диаграммы Key Abstractions найдите и установите флажок Attribute Display Options -> Show Property Modifiers. 1. Откройте диаграмму Key Abstractions. Выберите в палитре инструмент Class. Добавьте классы Order, OrderItem, ArticleOfFurniture, Client, User, Inventory, InventoryItem. 2. Добавьте перечислимые типы (Enumeration) UserType (Тип пользователя) и OrderStatus (Статус заказа). Внутри них расположите значения перечислимого типа (enumeration literal): SALESMAN, STOCKMAN, WAREHOUSEMAN; ARCHIVED, CANCELLED, DELIVERED, FILLED, INPROCESS. 3. Выберите в палитре инструмент Association. Проведите ассоциации между классами. Укажите мощности у полюсов -- концов ассоциаций (контекстное меню полюса Multiplicity). Укажите, что связь между заказом и позицией заказа -- композиция (контекстное меню полюса, Association Kind -> Composited). Укажите на полюсах ассоциаций их имена (контекстное меню полюса, Edit Role Name...). Чтобы имя полюса отобразилось на диаграмме вызовите контекстное меню UML-диаграммы, Presentation Options -> Association Display Options -> Show From Role Name и Show To Role Name. Также выводом имён ролей можно управлять через контекстное меню отдельной ассоциации. Свойство полюса ordered добавьте, открыв спецификацию ассоциации и нажав ... у соответствующей роли. В открывшейся спецификации полюса (Association End Specification) найдите и установите флаг Ordered. 4. Добавьте атрибуты (Attribute) классов: классу Order -- number:long, creation:Date, delivery:Date[0..1], filling:Date[0..1], status:OrderStatus, sumTotal:long; классу OrderItem -- quantity:byte, number:byte, filled:boolean, total:long, price:long; классу ArticleOfFurniture -- code:string, description:string, discontinued:boolean, price:long; классу Client -- name:string, address:string[3], phones:string[*]; классу User -- login:string, passwordHash:long[2]; type:UserType; классу Inventory -- number:long, date:Date, approved:boolean; классу InventoryItem -- quantity:int. Мощности атрибутов следует вводить при создании атрибута как часть его типа. Другим способом их ввода является указание мощности как модификатора типа в окне спецификации атрибута (открыть которое можно, выделив атрибут и вызвав его контекстное меню). Среда Visual Paradigm загромождает диаграмму лишними сведениями, если указывать мощность атрибута в предназначенном для этого поле и выводить её на диаграмме. Поэтому рекомендуется указывать мощности как модификаторы типов атрибутов. Значения атрибутов по умолчанию (Initial value) вводятся в окне спецификации атрибута. Признак того, что атрибут входит в состав идентификатора экземпляра класса, также указывается в окне спецификации атрибута. Признак того, что атрибут является выводимым (Derived), также указывается в этом окне. 5. Проведите зависимости (Dependency) от класса User к перечислимому типу UserType; от класса Order к перечислимому типу OrderStatus. 6. Добавьте всем классам -- ключевым абстракциям -- стереотип «entity». Эта пометка означает, что каждый экземпляр класса-сущности имеет явно выраженную индивидуальность, и что обязанностью класса будет хранение данных об объектах предметной области. Для добавления стереотипа выделите нужный класс в браузере, вызовите контекстное меню, Stereotypes -> Edit Stereotypes... -> entity. 7. Важно, что класс InventoryItem является классом ассоциации (используйте инструмент палитры Association Class). В итоге UML-диаграмма должна соответствовать рисунку 4.1.3. Мы не описали операции, не уточнили направления всех ассоциаций. Дело в том, что нет необходимости сразу указывать все детали ключевых абстракций. Можно даже не указывать типы некоторых атрибутов. Важно определить начальный набор классов, установить между ними связи, вытекающие из свойств предметной области, указать основные данные, хранимые в объектах. В ходе проекта возможности уточнить набор ключевых абстракций ещё представятся. Мы готовы перейти к выполнению анализа вариантов использования. В технологии Unified Process он выполняется разработчиками и включает в себя следующие технологические операции:
Классы анализа отражают функциональные требования к системе и моделируют типы объектов. Совокупность классов анализа по большей части определяет начальную эскизную модель системы. Эта модель проста и позволяет сосредоточиться на реализации функциональных требований к системе, не отвлекаясь на детали реализации, обеспечение эффективности и надёжности. Впоследствии для решения этих вопросов эскизная модель будет трансформирована в проектную модель. В ходе анализа вариантов использования в их потоках событий выявляются классы трёх типов:
Правило выделения граничных классов: для каждой связи между действующим лицом и вариантом использования создаётся или назначается граничный класс, отвечающий за данное взаимодействие. Правило выделения классов-сущностей: классы-сущности -- это, обычно, классы, представляющие ключевые абстракции системы. Правило выделения управляющих классов: для каждого варианта использования создаётся ответственный за управление его сценарием класс управления. Выполните анализ варианта использования CRUD данных о заказах.
|
Упражнение 4.2. Анализ варианта использования «CRUD данных о заказах» |
Анализ варианта использования начинается с идентификации классов анализа. Надо решить, какие классы будут задействованы в реализации варианта использования. Согласно диаграмме вариантов использования имеются два действующих лица (Продавец и Бухгалтерская система), связанных с нашим вариантом использования. Создайте в пакете Analysis Model граничные классы (контекстное меню пакета Analysis Model, Model Element -> Class): MainMenu -- форму главного меню, OrderForm -- форму заказа, ASAccess -- класс-посредник, реализующий протокол взаимодействия с Бухгалтерской системой. Первые два класса обеспечат взаимодействие системы с действующим лицом Продавец в рамках нашего варианта использования. Созданным трём классам назначьте стереотип «boundary» (контекстное меню, Stereotypes -> Edit Stereotypes... -> boundary). Создайте управляющие классы OrderController, отвечающий за реализацию бизнес-логики, и DataAccess, отвечающий за передачу запросов к базе данных (действия аналогичны). Созданным двум классам назначьте стереотип «control» (контекстное меню, Stereotypes -> Edit Stereotypes... -> control). Из описания варианта использования следует, что в потоках событий будут задействованы экземпляры классов User, Order, OrderItem, ArticleOfFurniture, Client. Без данных, которые хранятся в экземплярах этих классов, потоки событий не могут быть реализованы. Откройте диаграмму классов CRUDOrdersVOPC. Перетащите на неё вышеупомянутые классы из браузера. Вид UML-диаграммы, которая должна получиться, изображён на рис. 4.2.1. Скриншот UML-диаграммы сделан с отключённым выводом членов классов (атрибутов и операций). Выполняя моделирование Вы можете не отключать их вывод, так как при дальнейшей работе они на диаграмме понадобятся.
Рис. 4.2.1. Начальная версия UML-диаграммы классов CRUDOrdersVOPC (для всех вариантов). Работа над диаграммой не завершена! Распределение поведения, предусматриваемого вариантом использования, между классами анализа реализуется при построении диаграмм взаимодействия. На основе описания варианта использования для всех потоков событий (основного, альтернативных, подчинённых) строится UML-диаграмма взаимодействия -- UML-диаграмма последовательности, или UML-диаграмма коммуникации, или обе. Осуществите моделирование потоков событий с помощью диаграмм последовательности. |
Упражнение 4.2.A. Создание UML-диаграммы последовательности «CRUDOrdersBasicFlow» |
Откройте диаграмму последовательности CRUDOrdersBasicFlow. Добавьте на диаграмму 5 линий жизни (Lifeline). Ими будут являться взаимодействующие объекты: Продавец -- экземпляр действующего лица; m : MainMenu -- экземпляр граничного класса; oc : OrderController -- экземпляр управляющего класса; asa : ASAccess -- экземпляр граничного класса; Бухгалтерская система -- экземпляр действующего лица. Заметьте, что линии жизни объектов граничных классов следует располагать рядом линиями жизни, представляющими действующих лиц, за общение с которыми они отвечают. Линия жизни экземпляра класса-контроллера расположена в середине UML-диаграммы. Выберите на палитре синхронное сообщение вызова (Call Message) и проведите его от линии жизни Продавец к линии жизни m : MainMenu. Оставьте сообщение без имени. Вызовите контекстное меню сообщения и выберите в нём Select Operation -> Create Operation. Дайте имя операции crudOrders. Так же поступите, добавляя второе синхронное сообщение с тем же именем, которым форма извещает контроллер о выборе продавца (так же создайте одноимённую операцию). Каждое сообщение к экземпляру класса должно быть связано с операцией данного класса. Сообщения, получаемые экземплярами действующих лиц связывать с операциями не следует. На диаграмме классов CRUDOrdersVOPC можно видеть, что в классе MainMenu появилась операция crudOrders. Также можно видеть операцию crudOrders в классе-контроллере OrderController.
Рис. 4.2.2. Начальный вид UML-диаграммы последовательности CRUDOrdersBasicFlow (для всех вариантов). Работа над диаграммой не завершена! Далее есть три варианта развития событий, в зависимости от того, что хочет сделать с заказом Продавец: создать новый заказ, изменить ранее введённый заказ, удалить заказ. Добавиьте на диаграмму альтернативный комбинированный фрагмент взаимодействия (Alt. Combined Fragment). Добавьте третий операнд внутрь фрагмента (контекстное меню комбинированного фрагмента, Operand -> Add Operand). Добавьте сторожевые условия каждому операнду (контекстное меню комбинированного фрагмента, Operand -> Manage Operands). В открывшемся окне в поле Guard укажите сторожевые условия операндов: создаётся заказ -- верхнему операнду, изменяется заказ -- среднему, удаляется заказ -- нижнему (см. диаграмму 4.2.3). Внутри каждого их трёх операндов комбинированного фрагмента будет происходить одно из взаимодействий, соответствующих трём подчинённым потокам варианта использования. Чтобы не загромождать диаграмму основного потока для каждого подчинённого потока создаётся отдельная UML-диаграмма (ранее мы уже создали для этого пустые UML-диаграммы CreateOrderSubflow, UpdateOrderSubflow, DeleteOrderSubflow). На основной диаграмме будут размещены лишь ссылки на используемые взаимодействия. Вернитесь к диаграмме последовательности CRUDOrdersBasicFlow. В созданный последним комбинированный фрагмент взаимодействия с тремя операндами добавьте указанные на диаграмме сообщения, а также элементы Interaction Use. С помощью контекстного меню каждого Interaction Use укажите на какое взаимодействие он ссылается (Refers to). Ниже нарисуйте два вложенных комбинированных фрагмента. Создать их нужно, поместив на диаграмму два Loop Combined Fragment и изменив в них оператор с loop на alt (контекстное меню фрагмента, Operator type -> opt). Добавьте сообщения: синхронное сообщение вызова от объекта-контроллера к экземпляру граничного класса; аcинхронное сообщение к экземпляру действующего лица Бухгалтерская система (тип сообщения установите в контекстом меню сообщения, Model element properties -> Asynchronous); два сообщения-возврата (Reply); синхронное сообщение к форме главного меню. UML-диаграмма примет вид, схожий с рисунком 4.2.3. Не забудьте создать операции и связать их с сообщениями. Для сообщения к экземпляру действующего лица создавать операцию не следует, достаточно только указать имя сообщения. То же справедливо для сообщений-возвратов, у них лишь указывается имя. Рис. 4.2.3. Окончательный вид UML-диаграммы последовательности CRUDOrdersBasicFlow (для всех вариантов) Чтобы у взаимодействующих экземпляров классов была возможность обмениваться сообщениями, проведите на диаграмме классов CRUDOrdersVOPC две ассоциации: от MainMenu к OrderController и от OrderController к ASAccess. Так как сообщения-вызовы идут в одну сторону, то можно указать направление навигации. UML-диаграмма CRUDOrdersVOPC примет вид как на рис. 4.2.4. Скриншот UML-диаграммы сделан со включённым выводом операций классов, но с отключённым выводом атрибутов классов. Рис. 4.2.4. Промежуточный вид UML-диаграммы классов CRUDOrdersVOPC (для всех вариантов). Работа над диаграммой не завершена! Моделировать потоки событий в реализациях вариантов использования можно не только с помощью диаграмм последовательности. Также для этой цели применяют коммуникационные UML-диаграммы (communication diagram). Об этих UML-диаграммах рассказывается на лекции. При выполнении упражнений мы создавать такие UML-диаграммы не будем. |
Упражнение 4.2.B. Создание UML-диаграммы последовательности «CreateOrderSubflow» |
Если у Вас 1й вариант, то смоделируйте один из подчинённых потоков CreateOrderSubflow. Вид UML-диаграммы последовательности, которая должна получиться, показан на рисунке 4.2.5. Создание заказа моделируется на диаграмме последовательности созданной внутри взаимодействия CRUDOrdersBasicFlow. Продавец посылает дату поставки и сведения о заказчике в форму of : OrderForm. Форма, получив эти данные, передаёт запрос о создании заказа OrderController'у. Тот с помощью экземпляра класса для доступа к базе данных DataAccess либо получает из базы данных сведения о ранее созданном заказчике, либо добавляет в базу данных запись со сведениями о новом заказчике. Затем создаётся экземпляр класса Order и добавляется в список заказов, заведённых текущим пользователем. Далее в цикле для каждой позиции заказа Продавец вводит данные. Данные из формы попадают к контроллеру. Он проверяет, что предмет мебели из введённой позиции заказа есть в базе данных через менеджера транзакций. Если проверка успешна, контроллер запрашивает у Order добавление новой позиции. Логично возложить эту обязанность на сам заказ, чтобы оградить контроллер от лишних знаний о внутреннем устройстве заказа. Как заказ работает с собственными позициями -- это его личное дело. Если данные от Продавца ошибочны, данные о такой позиции заказа в системе не сохраняются. Далее продавец нажимает кнопку Сохранить заказ в форме. Форма передаёт сообщение об этом контроллеру. Контроллер передаёт доступа к базе данных запрос на сохранение заказа в базе данных. Форма закрывается (об этом говорит значок-крестик на её линии жизни, его следует добавить через контекстное меню линии жизни, Model Element Properties -> Stopped). Для передачи в бухгалтерскую систему контроллер преобразует данные о заказе в формат JSON. Это преобразование происходит в нескольких подчинённых потоках, поэтому оно моделируется на отдельной диаграмме, а здесь располагается только элемент Interaction Use. На диаграмме использованы комбинированные фрагменты с оператором opt (Optional), представляющие ветвления с единственной содержательной альтернативой, а также комбинированный фрагмент с оператором loop, описывающий цикл, и элемент Interaction Use. Создавая цикл, следует задать в сторожевых условиях ограничения на количество итераций. Линиям жизни ol[j] : OrderItem и a[j] : ArticleOfFurniture следует отметить флажок Multi-object в их спецификациях на вкладке General. Так будет показано, что работа ведётся с объектом из коллекции. Обратите внимание, что на рис. 4.2.5 есть сообщения new, которые имеют тип Creation Message. Не забудьте для всех сообщений-вызовов добавить соответствующие операции в классы и связать их вызовы с сообщениями. Действующему лицу создавать операции не следует. Операции-конструкторы вроде new в эскизной модели можно не заводить. Рис. 4.2.5. UML-диаграмма последовательности CreateOrderSubflow (моделируется только в варианте 1) Каждое сообщение на диаграмме последовательности назначает экземплярам классов обязанности по отправке или приёму и обработке сообщений. Для приёма сообщения в классе объекта-приёмника должна быть одноимённая операция. Для отправки сообщения между экземплярами классов должно быть соединение. Возможность соединения проще всего обеспечить, проведя ассоциацию между классами, экземпляры которых обмениваются сообщениями. На диаграмме 4.2.5 форма OrderForm отправляет сообщение newOrderData() контроллеру OrderController. Значит, в классе OrderController должна быть одноимённая операция, которая обрабатывает сообщение от формы OrderForm, а между классом-формой и классом-контроллером должна быть ассоциация. Нарисуем ассоциацию на диаграмме CRUDOrdersVOPC. Мощности полюсов этой ассоциации указывать не будем, уточним их позже при проектировании. По схожим причинам проведём ассоциации: от OrderController к DataAccess; от OrderController к User; от OrderController к Order. Вид обновлённой UML-диаграммы CRUDOrdersVOPC приведён на 4.2.6. Обратите внимание, что на диаграмме отражены новые операции, сообщениями-вызовами которых обмениваются экземпляры классов в ходе взаимодействия. Проверьте, что для каждого сообщения, принимаемого экземпляром любого класса (но не действующего лица), существует связанная операция. Не следует лишь давать имя сообщению-вызову, направленному экземпляру класса системы, необходимо создать вызываемую операцию и связать её с сообщением. Пропускать создание операций можно лишь у действующих лиц. Рис. 4.2.6. Вид обновлённой UML-диаграммы классов CRUDOrdersVOPC после моделирования подпотока CreateOrderSubflow (в варианте 1) |
Упражнение 4.2.C. Создание UML-диаграммы последовательности «DeleteOrderSubflow» |
Если у Вас 2й вариант, то составьте диаграмму последовательности DeleteOrderSubflow. Вид UML-диаграммы последовательности, которая должна получиться приведён на рис. 4.2.7, обновлённый вид UML-диаграммы классов CRUDOrdersVOPC -- на рис. 4.2.8. Линиям жизни or[i] : Order и ol[j] : OrderItem следует отметить флажок Multi-object в их спецификации на вкладке General. Остановленные линии жизни (с крестиками на концах) следует пометить как Stopped (контекстное меню -> Model Element Properties -> Stopped). Сообщение с вызовом деструктора (destroy) лучше создавать как Destroy Message и просто давать им имя, не заводя операцию-деструктор в классе явно. На CRUDOrdersVOPC следует поместить новый класс-участник SelectOrderForm и соединить его ассоциацией с контроллером. Следует расширить размеры классов, чтобы были видны новые добавленные операции, необходимые для моделируемого взаимодействия. Рис. 4.2.7. UML-диаграмма последовательности DeleteOrderSubflow (моделируется только в варианте 2) Рис. 4.2.8. Вид обновлённой UML-диаграммы классов CRUDOrdersVOPC после моделирования подпотока DeleteOrderSubflow (в варианте 2) |
Упражнение 4.2.D. Создание UML-диаграммы последовательности «Order2JSON» |
Если у Вас 3й вариант, то составьте диаграмму последовательности Order2JSON. Вид UML-диаграммы последовательности, которая должна получиться приведён на рис. 4.2.9, обновлённый вид UML-диаграммы классов CRUDOrdersVOPC -- на рис. 4.2.10. Первое сообщение является найденным (Found Message). Добавьте его на диаграмму, а затем откройте окно спецификации (контекстное меню, Open Specification...). Укажите тип сообщения Call в поле Action Type. Создайте операцию к классе Order и свяжите с сообщением. Линиям жизни ol[j] : OrderItem и a[j] : ArticleOfFurniture следует отметить флажок Multi-object в их спецификациях на вкладке General. Нижнее сообщение является потерянным (Lost Message). Добавьте его на диаграмму, а затем откройте окно спецификации (контекстное меню, Open Specification...). Укажите тип сообщения Reply в поле Action Type. На CRUDOrdersVOPC следует расширить размеры классов, чтобы были видны новые добавленные операции, необходимые для моделируемого взаимодействия. Заметим, что CRUDOrdersVOPC пока ещё не является связным графом. Это означает, что работа над ней не завершена. Это так, поскольку смоделирована не вся реализация варианта использования, а только вспомогательное взаимодействие Order2JSON. Рис. 4.2.9. UML-диаграмма последовательности Order2JSON (моделируется только в варианте 3) Рис. 4.2.10. Вид обновлённой UML-диаграммы классов CRUDOrdersVOPC после моделирования взаимодействия Order2JSON (в варианте 3) Работа над диаграммой не завершена! |
Упражнение 4.3. Анализ варианта использования «Войти в систему» (только для варианта 4) |
Если у Вас 4й вариант, то проведите анализ варианта использования Войти в систему. Откройте диаграмму LoginVOPC внутри кооперации Login из пакета Use Case Realizations. Поместите на неё классы User, LoginForm, MainMenu, LoginController, DataAccess. Классы, пока отсутствующие в модели, лучше не создавать на диаграмме, а создавать в браузере через контекстное меню пакета Analisys Model, так чтобы все классы анализа оказались в корне этого пакета. Если Вы создали классы на диаграмме, то найдите их в браузере (внутри кооперации) и переместите (перетащите) в корень пакета Analisys Model. Назначьте стереотипы: «boundary» -- LoginForm и MainMenu, «control» -- LoginController и DataAccess. Удостоверьтесь, что классу User назначен стереотип «entity». Начальный вариант UML-диаграммы классов LoginVOPC приведён на рисунке 4.3.1. Рис. 4.3.1. Начальный вариант UML-диаграммы классов LoginVOPC (моделируется только в варианте 4). Работа над диаграммой не завершена! Если у Вас 4й вариант, то анализ варианта использования Войти в систему надо продолжить. Откройте диаграмму последовательности LoginBasicFlow. Добавьте на диаграмму 6 линий жизни (Lifeline): линию жизни действующего лица Пользователь; lf -- экземпляр формы LoginForm; m -- экземпляр формы MainMenu; c -- экземпляр LoginController; dao -- экземпляр класса DataAccess; cu -- экземпляр класса User. Проще всего добавлять линии жизни, перенося действующее лицо и классы из браузера на диаграмму. При переносе класса укажите, что добавляется линия жизни. Добавьте линиям жизни стереотипы. Заметьте, что линию жизни объекта граничного класса следует расположить рядом с линией жизни, представляющей то действующее лицо, за общение с которыми отвечает граничный класс, а линии объектов контроллеров следует расположить в середине UML-диаграммы. В правой части UML-диаграммы располагают линии жизни объектов-сущностей. Добавьте на диаграмму сообщения и комбинированные фрагменты согласно рисунку 4.3.2. Редактирование осуществите по аналогии с CRUDOrdersBasicFlow. Комбинированный фрагмент с оператором opt следует добавлять как элемент палитры Loop Combined Fragment с последующей заменой в спецификации фрагмента оператора на нужный (контекстное меню -> Operator Kind). Создайте рефлексивное сообщение (SelfMessage) к линии жизни cu : User и укажите его тип (контекстное меню -> Type, Call), свяжите его с новой создаваемой операцией. Остановленную линию жизни (с крестиком на конце) пометьте как Stopped (контекстное меню -> Model Element Properties -> Stopped). Рис. 4.3.2. UML-диаграмма последовательности LoginBasicFlow (моделируется только в варианте 4) Если у Вас 4й вариант, то анализ варианта использования «Войти в систему» надо продолжить. Откройте диаграмму классов LoginVOPC. Добавьте ассоциации, необходимые для того, чтобы взаимодействие, описанное диаграммой последовательности LoginBasicFlow, было осуществимо. Расставьте мощности и имена ролей на полюсах ассоциаций. Укажите направления навигации (на противоположном полюсе с помощью контекстного меню укажите Navigable Unspecified). Итоговый вид UML-диаграммы приведён на рисунке 4.3.3. Рис. 4.2.10. Итоговая версия UML-диаграммы классов LoginVOPC (моделируется только в варианте 4) Упражнения по эскизному моделированию закончены. Предполагается, что реализация всех вариантов использования выполняется не за один раз. Часть вариантов использования могут быть реализована не на первой итерации, а на последующих. Мы не будем моделировать остальные потоки событий всех вариантов использования, чтобы не терять время на рутину. Созданную эскизную модель следует сохранить отдельно. Если при проектном моделировании эта модель разрушится, можно будет использовать её копию, сохранённую отдельно. При сдаче выполненных упражнений полезно иметь с собой два файла проекта: один, сохранённый на момент окончания эскизного моделирования; второй, представляющий модель после выполнения всех упражнений. Закройте проект и сделайте копию файла проекта в workspace. |
Во время эскизного моделирования всё внимание уделялось реализации функциональных требований. При проектном моделировании круг рассматриваемых вопросов раширяется, учитываются нефункциональные требования. Модель системы адаптируется к каркасам, библиотекам, языкам, которые будут использованы при реализации. Процесс анализа и проектирования возглавляется архитектором, а значит, он отвечает и за создание проектной модели. Под руководством архитектора трудятся разработчики, к которым при необходимости подключают разработчиков БД и разработчиков компонент реального времени. Проектная модель системы создаётся итерационно. На каждой итерации ставится цель спроектировать часть системы. Для достижения этой цели друг за другом выполняются два вида работ: проектирование архитектуры системы и проектирование элементов системы. Т. е. сначала определяются крупные части системы, их связи и взаимодействие, а потом детально проектируется внутреннее устройство этих частей и их внутреннее поведение. При проектировании архитектуры выделяются проектные элементы (классы, интерфейсы, подсистемы), формируется иерархия архитектурных уровней, идентифицируются проектные механизмы, создаётся структура потоков управления системы, разрабатывается конфигурация системы на вычислительной среде. Осуществляет эти работы архитектор системы.
|
Упражнение 5.1. Проектирование архитектуры системы (общее для всех вариантов) |
Система обработки заказов будет работать с собственной реляционной базой данных, в которой будут сохраняться сведения о заказах, клиентах, продаваемых предметах мебели, остатках и проч., следовательно, будет использован проектный механизм RDBMS (relational database management system) для обеспечения работы с устойчивыми данными (т. е. данными сохраняемыми и после завершения сеанса работы с системой). Система обработки заказов также взаимодействует с внешней программой -- бухгалтерской системой. Значит, будет использован проектный механизм RemoteInterchange для обеспечения обмена запросами и/или данными с внешней системой. Существуют готовые каркасы, обеспечивающие доступ к реляционным базам данных. К таким относится RDBMS-JDBC (Relational DataBase Management System - Java Database Connectivity). Каркас XMLRPCInterchange (eXtensible Markup Language Remote Procedure Call Interchange) обеспечивает межсистемное взаимодействие. Проектные механизмы уже добавлены в нашу модель (они входят в состав заготовки проекта, с которой мы начали выполнять упражнения). См. пакеты Architectural Mechanisms и Middleware в составе Design Model внутри архитектурного представления Logical View. В Design Model создайте ещё два пакета: Application и BusinessServices. На уровень приложения следует поместить элементы пользовательского интерфейса и элементы, реализующие логику приложения. На уровень бизнес-служб -- элементы, относящиеся к предметной области. Уровень промежуточного ПО содержит элементы, обеспечивающие сервисы, независимые от платформы. Назначьте пакетам стереотип «layer» -- архитектурный уровень. В Design Model создайте диаграмму пакетов (Package Diagram) Main. Вытащите на неё все три архитектурных уровня и соедините их зависимостями (Dependency), как указано на рис. 5.1.1. Также из пакета Architectural Mechanisms вытащите на диаграмму пакеты RemoteInterchange и Persistency. Проведите к ним зависимости от пакета BusinessServices, т. к. там будут использованы описания этих механизмов. Настройте отображение имени родительского пакета на диаграмме (контекстное меню пакета -> Presentation Options -> Show Owner -> Show Name Only). Если в заготовке проекта отсутствовали зависимости пакетов RemoteInterchange и Persistency от уровня Middleware, то добавьте их в модель. Создана иерархия архитектурных уровней системы, т. е. её устройство с точки зрения самых крупных блоков. Рис. 5.1.1. UML-диаграмма пакетов Main (для всех вариантов) Следующие действия нацелены на трансформацию классов анализа в проектные элементы (классы, интерфейсы и подсистемы) и распределение проектных элементов по уровням системы. Часто при трансформации простые классы анализа преобразуются в проектные классы один в один. Сложный класс анализа может преобразовываться в несколько связанных проектных классов или в подсистему. При эскизном моделировании не были учтены полностью все вопросы, связанные с обеспечением работы с устойчивыми данными. В потоке событий система предпринимала некоторые действия, чтобы введённые данные были доступны не только в текущем сеансе работы, но и в последующих. Для этого отправлялись сообщения объекту доступа к данным (DAO), но его действия по обработке этих сообщений не были промоделированы. В этом нет ошибки, во время эскизного моделирования эти вопросы рассматривать рано, надо сосредоточиться на основных функциях системы. В ходе проектного моделирования приходит время обратиться к решению этих вопросов. Должно быть смоделировано то, что ранее было временно отложено на потом. Реализация обязанностей, назначенных классу DataAccess, сложна. Поэтому при отображении в проектные классы он трансформируется в одноимённую подсистему обеспечения устойчивости DataAccess. Граничный класс ASAccess, обеспечивающий взаимодействие с бухгалтерской системой, также трансформируется в подсистему для того, чтобы возможные изменения во взаимодействии с внешней программой мало затрагивали остальные части системы и были локализованы в подсистеме. Остальные классы анализа переводятся в проектные один в один. Чтобы не испортить эскизную модель, скопируйте её содержимое внутрь проектной модели. Для этого в браузере выделите пакет Analysis Model, вызовите его контекстное меню и выберите в нём пункт Duplicate Recursively. Будет осуществлено дублирование пакета и всех его элементов. Дубль пакета получит имя Analysis Model2. Стереотипы анализа («boundary», «control», «entity») в проектной модели не имеют смысла, поэтому их следует удалить со всех классов пакета Analysis Model2 и с линий жизни на диаграммах последовательности внутри него. Создайте в пакете Application пакеты Login и CRUDOrders. В созданный пакет CRUDOrders переместите классы участники реализации варианта использования «CRUD данных о заказах»: OrderForm, OrderListForm (этот класс есть в модели только в варианте 2), OrderController из корня Analysis Model2. Для этого воспользуйтесь контекстным меню элемента в браузере модели и пунктом Move... либо перетащите мышью. Создайте диаграмму классов в пакете CRUDOrders. Дайте ей имя -- CRUDOrders. Перетащите на неё все классы пакета. UML-диаграмма примет вид, похожий на рис. 5.1.2. В зависимости от Вашего варианта класс OrderListForm может отсутствовать. На рисунке 5.1.2 вывод операций классов отключён. Если на Вашей диаграмме операции присутстуют, то в этом нет ошибки.
Рис. 5.1.2. UML-диаграмма классов CRUDOrders (для всех вариантов; класс OrderListForm есть только в варианте 2) Если Вы выполняли упражнение по моделированию реализации варианта использования «Войти в систему» (вариант 4), то в пакет Login переместите классы участники этой реализации: LoginForm, MainMenu, LoginController из корня Analysis Model2. Если у Вас другой вариант, то переместите туда только класс MainMenu. Для этого воспользуйтесь контекстным меню элемента в браузере модели и пунктом Move... либо перетащите мышью. Создайте диаграмму классов в пакете Login. Дайте ей имя -- Login. Перетащите на неё все классы этого пакета. UML-диаграмма примет вид, похожий на рис. 5.1.3. На рисунке 5.1.3 вывод операций классов отключён. Если на Вашей диаграмме операции присутстуют, то в этом нет ошибки.
Рис. 5.1.3. UML-диаграмма классов Login (для всех вариантов, в зависимости от варианта присутствуют все классы или только класс MainMenu) Класс MainMenu из пакета Login связан ассоциацией с классом OrderController из пакета CRUDOrders. Раз так, то следует провести зависимость пакета Login от пакета CRUDOrders. Создайте в пакете Application диаграмму пакетов (контекстное меню пакета, Sub Diagrams -> New Diagram... -> Package Diagram). Назовите её Application по имени пакета. Перетащите пакеты Login и CRUDOrders на созданную диаграмму. Проведите зависимость от пакета Login в направлении пакета CRUDOrders.
Рис. 5.1.4. UML-диаграмма классов Application (для всех вариантов) В пакете BusinessServices создайте пакет WarehouseArtefacts (т. е. артефакты склада, в нем разместите классы-сущности предметной области, а также перечислимые типы UserType и OrderStatus). Прежние стереотипы классов («entity») удалите, если не сделали этого ранее. Через контекстное меню откройте спецификацию UML-диаграммы классов Key Abstractions2. Введите её новое имя в поле Diagram name: WarehouseArtefacts. Укажите новую родительскую модель Parent model: пакет WarehouseArtefacts. Примените изменения. В результате этих действий UML-диаграмма вместе со всеми её элементами и связями переместится в пакет WarehouseArtefacts. В зависимости от Вашего варианта некоторые операции классов могут отсутствовать, в этом нет ошибки.
Рис. 5.1.5. UML-диаграмма классов WarehouseArtefacts (для всех вариантов) В пакете BusinessServices создайте пакет Interfaces (где будут находиться все интерфейсы системы). В пакет Interfaces перенесите классы DataAccess и ASAccess из Analysis Model2. Переименуйте DataAccess в IDataAccess, ASAccess в IASAccess. (По соглашениям моделирования имена интерфейсов следует начинать с буквы I.) Назначьте классам стереотипы «Interface». Прежние стереотипы («control», «boundary») удалите, если не удалили ранее. Создайте диаграмму классов Interfaces и разместите на ней интерфейсы IDataAccess, IASAccess. UML-диаграмма примет вид, похожий на рис. 5.1.6. В зависимости от Вашего варианта некоторые операции интерфейса IDataAccess могут отсутствовать, в этом нет ошибки.
Рис. 5.1.6. UML-диаграмма классов Interfaces (для всех вариантов) Пакет Use Case Realizations из Analysis Model2 перенесите в Design Model и переименуйте его в Design Use Case Realizations. Пакет Analysis Model2 удалите (в браузере модели откройте его контекстное меню и выберите Delete). Переименуйте кооперации и UML-диаграммы из пакета Design Use Case Realizations (диаграмму Use Case Realizations2 -- в Design Use Case Realizations; кооперацию CRUDOrders2 -- в DesignCRUDOrders; кооперацию Login2 -- в DesignLogin; диаграмму CRUDOrdersVOPC2 -- в DesignCRUDOrdersVOPC; диаграмму LoginVOPC2 -- в DesignLoginVOPC; диаграмму CRUDOrdersBasicFlow2 в DesignCRUDOrdersBasicFlow; диаграмму LoginBasicFlow2 в DesignLoginBasicFlow; диаграмму CreateOrderSubflow2 в DesignCreateOrderSubflow; диаграмму UpdateOrderSubflow2 в DesignUpdateOrderSubflow; диаграмму DeleteOrderSubflow2 в DesignDeleteOrderSubflow; диаграмму Order2JSON2 в DesignOrder2JSON). В зависимости от Вашего варианта некоторые UML-диаграммы могут отсутствовать в пакете Design Use Case Realizations, в этом нет ошибки. Рис. 5.1.7. UML-диаграмма Design Use Case Realizations (для всех вариантов) При реализации подсистемы DataAccess будет задействован механизм RDBMS-JDBC из одноимённого пакета, расположенного в Design Model::Architectural Mechanisms::Persistency. При реализации подсистемы ASAccess будет задействован механизм XMLRPCInterchange из одноимённого пакета, расположенного в Design Model::Architectural Mechanisms::RemoteInterchange. Чтобы не повредить части модели, описывающие механизмы, скопируйте их в подсистемы. Для этого продублируйте (Duplicate Recursively) пакет RDBMS-JDBC и пакет XMLRPCInterchange, а затем переместите полученные дубли на уровень Business Services и переименуйте их в DataAccess и ASAccess, соответственно. Назначьте пакетам DataAccess и ASAccess стереотип «subsystem», уберите стереотип «mechanism», если он у них есть. Стереотипы анализа в проектной модели смысла не имеют, их лучше убрать (снять флажки в контекстном меню -> Stereotypes). Создайте диаграмму пакетов BusinessServices в пакете BusinessServices. Разместите на ней пакеты Interfaces и WarehouseArtefacts, а также подсистемы DataAccess и ASAccess. Укажите зависимости (Dependency). Элементы подсистем будут реализовывать интерфейсы из пакета Interfaces. В интерфейсе подсистемы DataAccess содержатся операции, обеспечивающие сохранение в БД, подкачку из БД экземпляров классов из WarehouseArtefacts. Это обуславливает смоделированные на диаграмме зависимости. UML-диаграмма примет вид, представленный на рис. 5.1.8. Рис. 5.1.8. UML-диаграмма пакетов BusinessServices (для всех вариантов) Откройте диаграмму пакетов Main в корне пакета Design Model. Перетащите на неё пакеты Login и CRUDOrders, так, чтобы они оказались внутри своего архитектурного уровня (Application). Чтобы отобразить зависимость между этими пакетами, добавленную нами ранее в модель, зывовите контекстное меню пакета Login, выберите Related Elements -> Visualize Related Model Element... . Отметьте флажком нужную зависимость и отобразите её. Аналогично поступите с пакетами Interfaces и WarehouseArtefacts внутри архитектурного уровня BusinessServices. Аналогично отобразите зависимость между ними. Классы LoginController и OrderController обращаются к DataAccess и к экземплярам классов WarehouseArtefacts. Добавьте зависимости для того, чтобы это было осуществимо. UML-диаграмма примет вид, представленный на рис. 5.1.9.
Рис. 5.1.9. UML-диаграмма пакетов Main в корне пакета Design Model (для всех вариантов) Структура проектной модели в браузере примет вид, похожий на рис. 5.1.10. Убедитесь, что Вы верно распределили элементы проектной модели по пакетам.
Рис. 5.1.10. Структура проектной модели в браузере (для всех вариантов) Моделирование структуры потоков управления системы в упражнения не включено. Этот вопрос будет рассматриваться только на лекциях. В системе можно выделить следующие процессы: WarehousemanApplication -- процесс, исполняемый на рабочем месте заведующего складом; SalespersonApplication -- процесс, исполняемый на рабочем месте продавца; StockmanApplication -- процесс, исполняемый на рабочем месте кладовщика; DataAccessProcess -- процесс, обеспечивающий доступ к БД системы. Смоделируйте конфигурацию вычислительной среды системы обработки заказов. Она состоит из трёх типов узлов -- сред выполнения (Execution Environment); компонентов-процессов (Component), которые могут быть размещены внутри сред выполнения; устройств (Device). Связи между узлами -- пути коммуникации (Communication Line) -- являются подвидом ассоциаций. Другой вид связей -- вложение (Containment) -- указывает, что компоненты должны быть инсталлированы на среде выполнения. Откройте диаграмму размещения Main внутри архитектурного представления Deployment View. Создайте на ней узлы и связи между узлами. Компоненты следует создавать, размещая их внутри родительского узла. Окончательный вид UML-диаграммы приведён на рис. 5.1.11. По получившейся диаграмме можно судить, что в вычислительной среде могут быть узлы разных типов: принтер, коммутатор, бухгалтерская система, сервер магазина, рабочие станции трёх видов. Различные виды рабочих станций созданы для того, чтобы предоставлять разным типам пользователей разные функциональные возможности. Лишний функционал не будет включаться в сборку компонента, инсталируемого на рабочее место. На диаграмме указан тип узла, относящийся к внешнему окружению системы -- сервер бухгалтерской системы, подключённый к общей локальной сети магазина. СУБД развёрнута на сервере магазина. К коммутатору подключён принтер по USB интерфейсу. Каждая рабочая станция подключена к коммутатору.
Рис. 5.1.11. UML-диаграмма размещения Main (для всех вариантов) UML-диаграмма Main задаёт перечень типов узлов и возможные конфигурации, составленные из узлов разных типов. Дополнительно может быть составлена диаграмма с конкретными узлами (не с типами узлов, а с их экземплярами) для того, чтобы, например, привести пример конкретной конфигурации системы. Создайте вторую диаграмму размещения внутри пакета Delpoyment Model. Назовите её Installation Example. Поместите на неё 8 экземпляров (Instance Specification): asys : Бухгалтерская система, pc01 : Рабочее место заведующего складом, pc02 : Рабочее место кладовщика, pc03 : Рабочее место продавца, pc04 : Рабочее место продавца, srv01 : Сервер магазина, prn : Принтер, switch : Коммутатор. При размещении на диаграмме экземпляр выглядит как обычный прямоугольник. Сразу после размещения дайте имя экземпляру. Затем укажите тип (Classifier), экземпляром которого он является. Вызовите контекстное меню экземпляра, выберите Add Classifier. В открывшемся окне добавьте тип узла. После того, как экземпляру добавлен классификатор -- тип узла, он изображается на диаграмме как прямоугольный параллепипед, т. е. как узел на диаграмме размещения. Между собой экземпляры следует связать соединениями (Link). Соединения выглядят также как ассоциации, но связывать экземпляры можно только ими, а не ассоциациями. Рис. 5.1.12. UML-диаграмма размещения Installation Example (для всех вариантов) На этом упражнения по проектирование архитектуры завершены, можно перейти к упражнениям по проектирование элементов системы. |
Упражнение 5.2. Проектирование элементов системы обработки заказов |
Проектирование элементов системы включает в себя следующие виды работ: уточнение реализаций вариантов использования; проектирование подсистем; проектирование классов и проектирование схемы реляционной базы данных. Проектные реализации вариантов использования являются более полными, чем реализации, созданные в ходе эскизного моделирования. В них вместо экземпляров классов анализа должны присутствовать экземпляры проектных классов, т. е. должны быть учтены трансформации классов анализа в проектные элементы. |
Упражнение 5.2.1. Уточнение основного сценария варианта использования «CRUD данных о заказах» |
Откройте диаграмму последовательности DesignCRUDOrdersBasicFlow из кооперации DesignCRUDOrders в пакете LogicalView::Design Model::Design Use Case Realizations. На диаграмме DesignCRUDOrdersBasicFlow следует изменить стереотип на линии жизни объекта asa : IASAccess. Удалите стереотип «boundary» (если он не был удалён ранее), добавьте стереотип «interface». Тем самым смодериловано, что происходит обращение к экземпляру класса, реализующего интерфейс подсистемы. Какой именно это будет класс -- это для реализации варианта использования неважно. Реализация варианта использования не определяет, как подсистема ASAccess должна обрабатывать вызовы операций из её интерфейса. Это будет определено при проектировании подсистемы. Внутреннее поведение подсистемы скрыто, чтобы обеспечить возможность лёгкой модификации её реализации. По этой причине следует удалить сообщение-вызов, идущее от asa : IASAccess к действующему лицу Бухгалтерская система. Также удалите со всех линий жизни стереотипы анализа, если не удалили их ранее, так как в проектной модели они неуместны. Скройте линию жизни действующего лица Бухгалтерская система, к которой теперь не отправляются сообщения, чтобы UML-диаграмма DesignCRUDOrdersBasicFlow приняла вид, представленный на рисунке 5.2.1. В проектной реализации следует указать более полные сигнатуры вызываемых операций по сравнению с эскизной моделью. При уточнении реализаций вариантов использования можно детализировать сигнатуры операций, т. е. добавить их параметры и типы результатов (в браузере раскройте класс, выберите операцию, откройте её спецификацию и введите сведения на вкладках General и Parameters). Но это необязательно, т. к. можно составить полные сигнатуры операций при проектировании классов. Если Вы будете выполнять уточнения сигнатур операций, убедитесь, что работаете с проектными классами, т. е. с элементами Design Model. У сообщений new сигнатуры целиком указывают как имена сообщений. Ниже дан список сигнатур операций с UML-диаграммы DesignCRUDOrdersBasicFlow: Рис. 5.2.1. Уточнённая UML-диаграмма последовательности DesignCRUDOrdersBasicFlow (для всех вариантов) Обычно при трансформации классов анализа в проектные элементы граничные классы, отвечающие за взаимодействие с пользователем, преобразуются не в один класс, а в группу классов GUI. Упражнения по проектированию пользовательского интерфейса в рамках нашего курса не рассматриваются. Учебная модель упрощена. Каждый такой класс переведён в проектный один в один. |
Упражнение 5.2.2. Уточнение подчинённого потока «Создать заказ» варианта использования «CRUD данных о заказах» |
Если у Вас 1й вариант, то откройте диаграмму последовательности DesignCreateOrderSubflow из кооперации DesignCRUDOrders в пакете LogicalView::Design Model::Design Use Case Realizations. На диаграмме DesignCreateOrderSubflow следует изменить стереотип на линии жизни объекта dao : IDataAccess. Удалите стереотип «control» и добавьте стереотип «interface». Тем самым смоделировано, что происходит обращение к экземпляру класса, реализующего интерфейс подсистемы. Какой именно это будет класс -- это для реализации варианта использования неважно. Реализация варианта использования не определяет, как подсистема DataAccess должна обрабатывать вызовы операций своего интерфейса. Это будет определено при проектировании подсистемы. Внутреннее поведение подсистемы скрыто, чтобы обеспечить возможность лёгкой модификации её реализации. По этой причине следовало бы удалить сообщения-вызовы, идущие от линии жизни dao : IDataAccess к другим линиям жизни, если бы таковые были на диаграмме. Удалите со всех линий жизни стереотипы анализа, если не удалили их ранее, так как они неуместны в проектной модели. Убедитесь, что UML-диаграмма DesignCreateOrderSubflow приняла вид, представленный на рисунке 5.2.2. В проектной реализации следует указать более полные сигнатуры вызываемых операций по сравнению с эскизной моделью. При уточнении реализаций вариантов использования можно детализировать сигнатуры операций, т. е. добавить их параметры и типы результатов (в браузере раскройте класс, выберите операцию, откройте её спецификацию и введите сведения на вкладках General и Parameters). Но это необязательно, так как можно составить полные сигнатуры операций при проектировании классов. Если Вы будете выполнять уточнения сигнатур операций, убедитесь, что работаете с проектными классами, т. е. с элементами Design Model. У сообщений new сигнатуры целиком указываются как имена сообщений. Ниже дан список сигнатур операций с UML-диаграммы DesignCreateOrderSubflow: Рис. 5.2.2. Уточнённая UML-диаграмма последовательности DesignCreateOrderSubflow (только для варианта 1) |
Упражнение 5.2.3. Уточнение подчинённого потока «Удалить заказ» варианта использования «CRUD данных о заказах» |
Если у Вас 2й вариант, то откро диаграмму последовательности DesignDeleteOrderSubflow из кооперации DesignCRUDOrders в пакете LogicalView::Design Model::Design Use Case Realizations. На диаграмме DesignDeleteOrderSubflow измените стереотип на линии жизни объекта dao : IDataAccess. Удалите стереотип «control», если не удалили его ранее, и добавьте стереотип «interface». Тем самым смоделировано, что происходит обращение к экземпляру класса, реализующего интерфейс подсистемы. Какой именно это будет класс -- это для реализации варианта использования неважно. Реализация варианта использования не определяет, как подсистема DataAccess должна обрабатывать вызовы операций своего интерфейса. Это будет определено при проектировании подсистемы. Внутреннее поведение подсистемы скрыто, чтобы обеспечить возможность лёгкой модификации её реализации. По этой причине следовало бы удалить сообщения-вызовы, идущие от линии жизни dao : IDataAccess к другим линиям жизни, если бы таковые были на диаграмме. Удалите со всех линий жизни стереотипы анализа, если они не были удалены ранее, так как они неуместны в проектной модели. Убедитесь, что UML-диаграмма DesignDeleteOrderSubflow приняла вид, представленный на рисунке 5.2.3. В проектной реализации следует указать более полные сигнатуры вызываемых операций по сравнению с эскизной моделью. При уточнении реализаций вариантов использования можно детализировать сигнатуры операций, т. е. добавить их параметры и типы результатов (в браузере раскройте класс, выберите операцию, откройте её спецификацию и введите сведения на вкладках General и Parameters). Но это необязательно, так как можно составить полные сигнатуры операций при проектировании классов. Если Вы будете выполнять уточнения сигнатур операций, убедитесь, что работаете с проектными классами, т. е. с элементами Design Model. У сообщений new сигнатуры целиком указываются как имена сообщений. Ниже дан список сигнатур операций с UML-диаграммы DesignDeleteOrderSubflow: Рис. 5.2.3. Уточнённая UML-диаграмма последовательности DesignDeleteOrderSubflow (только для варианта 2) |
Упражнение 5.2.4. Уточнение UML-диаграммы «DesignOrder2JSON» варианта использования «CRUD данных о заказах» |
Если у Вас 3й вариант, то откройте диаграмму последовательности DesignOrder2JSON из кооперации DesignCRUDOrders в пакете LogicalView::Design Model::Design Use Case Realizations. На диаграмме DesignOrder2JSON следует удалить со всех линий жизни стереотипы анализа, если они не были удалены ранее, так как они неуместны в проектной модели. Убедитесь, что UML-диаграмма DesignOrder2JSON приняла вид, представленный на рисунке 5.2.4. В проектной реализации следует указать более полные сигнатуры вызываемых операций по сравнению с эскизной моделью. При уточнении реализаций вариантов использования можно детализировать сигнатуры операций, т. е. добавить их параметры и типы результатов (в браузере раскройте класс, выберите операцию, откройте её спецификацию и введите сведения на вкладках General и Parameters). Но это необязательно, так как можно составить полные сигнатуры операций при проектировании классов. Если Вы будете выполнять уточнения сигнатур операций, убедитесь, что работаете с проектными классами, т. е. с элементами Design Model. У сообщений new сигнатуры целиком указываются как имена сообщений. Ниже дан список сигнатур операций с UML-диаграммы DesignOrder2JSON: Рис. 5.2.4. Уточнённая UML-диаграмма последовательности DesignOrder2JSON (только для варианта 3) |
Упражнение 5.2.5. Уточнение основного сценария варианта использования «Войти в систему» |
Если у Вас 4й вариант, то откройте диаграмму последовательности DesignLoginBasicFlow из кооперации DesignLogin в пакете LogicalView::Design Model::Design Use Case Realizations. На диаграмме DesignLoginBasicFlow следует изменить стереотип на линии жизни объектов dao : IDataAccess. Удалите стереотип «control» и добавьте стереотип «interface». Тем самым мы показываем, что происходит обращение к экземпляру класса, реализующего интерфейс подсистемы. Какой именно это будет класс -- это для реализации варианта использования неважно. Реализация варианта использования не определяет, как подсистема DataAccess должна обрабатывать вызовы операций своего интерфейса. Это будет определено при проектировании подсистемы. Внутреннее поведение подсистемы скрыто, чтобы обеспечить возможность лёгкой модификации её реализации. По этой причине следовало бы удалить сообщения-вызовы, идущие от линии жизни dao : IDataAccess к другим линиям жизни, если бы таковые были на диаграмме. Удалите со всех линий жизни стереотипы анализа, если не сделали этого ранее, так как они неуместны в проектной модели. Убедитесь, что UML-диаграмма DesignLoginBasicFlow приняла вид, представленный на рисунке 5.2.5. В проектной реализации следует указать более полные сигнатуры вызываемых операций по сравнению с эскизной моделью. При уточнении реализаций вариантов использования можно детализировать сигнатуры операций, т. е. добавить их параметры и типы результатов (в браузере раскройте класс, выберите операцию, откройте её спецификацию и введите сведения на вкладках General и Parameters). Но это необязательно, так как можно составить полные сигнатуры операций при проектировании классов. Если Вы будете выполнять уточнения сигнатур операций, убедитесь, что работаете с проектными классами, т. е. с элементами Design Model. У сообщений new сигнатуры целиком указываются как имена сообщений. Ниже дан список сигнатур операций с UML-диаграммы DesignLoginBasicFlow: Рис. 5.2.5. Уточнённая UML-диаграмма последовательности DesignLoginBasicFlow (только для варианта 4) |
Вводные замечания по проектированию подсистем |
Следующей технологической операцией является проектирование подсистем. В рассматриваемой модели в ходе этой операции нам предстоит на основе механизма RDBMS-JDBC спроектировать подсистему DataAccess, а на основе механизма XMLRPCInterchange спроектировать подсистему ASAccess. При этом механизм выполнит роль шаблона, описывающего с точки зрения структуры и поведения либо типовую организацию доступа к устойчивым данным, либо типовую организацию обмена данными с внешней системой. В шаблоне (параметризованном пакете) RDBMS-JDBC параметрами являются классы PersistentObject, PersistentObjectList и DBClass, а в шаблоне (параметризованном пакете) XMLRPCInterchange -- классы ObjectToSend, ObjectToReceive, CustomTypeFactory, CustomParser, CustomSerializer и XMLRPCConnector. Проектирование подсистемы, в основном, сводится к конкретизации шаблона, в ходе которой класс-параметр (например, PersistentObject) заменяется на конкретный класс из модели (например, на класс Client, сведения об экземплярах которого хранятся в БД, и/или другие подобные классы из пакета WarehouseArtefacts). Класс-параметр DBClass заменяется на прокси-класс подсистемы DataAccess. Класс-параметр XMLRPCConnector заменяется на прокси-класс подсистемы ASAccess, обеспечивающий передачу данных во внешнюю систему. |
Упражнение 5.2.6. Проектирование подсистемы DataAccess на основе механизма RDBMS-JDBC |
Для начала убедитесь, что интерфейс подсистемы IDataAccess верно представлен в модели. В ходе предшествующих упражнений в интерфейс были добавлены следующие операции: Если у Вас вариант 1, 2 или 3, то класс PersistentObject переименуйте в класс Client и с помощью контекстного меню объедините класс Client из подсистемы DataAccess с одноимённым классом Client из пакета WarehouseArtefacts (Merge to Model Element..., так чтобы целевым был класс из пакета WarehouseArtefacts). Из получившегося в результате объединения класса Client удалите атрибут attribute и переименуйте операции getAttribute в getName, setAttribute в setName. Класс PersistentObjectList переместите в пакет WarehouseArtefacts и переименуйте его в ClientList. Откройте спецификацию класса ClientList. Найдите вкладку Relations. Измените имя у связи зависимости связывания (Binding) на < E->Client >. Ту же строку <E->Client> укажите в поле Template info. Тем самым смоделировано, что элементами этого списка будут экземпляры класса Client. Если у Вас вариант 4, то класс PersistentObject переименуйте в класс User и с помощью контекстного меню объедините класс User из подсистемы DataAccess с одноимённым классом User из пакета WarehouseArtefacts (Merge to Model Element..., так чтобы целевым был класс из пакета WarehouseArtefacts). Из получившегося в результате объединения класса User удалите атрибут attribute и переименуйте операции getAttribute в getLogin, setAttribute в setLogin. Класс PersistentObjectList переместите в пакет WarehouseArtefacts и переименуйте его в ClientList. Откройте спецификацию класса ClientList. Найдите вкладку Relations. Измените имя у отношения зависимости связывания (Binding) на < E->Client >. Ту же строку <E->Client> укажите в поле Template info. Тем самым смоделировано, что элементами этого списка будут экземпляры класса Client. Удалите зависимость (Dependency) ClientList от Client кнопкой Remove. Продолжая выполнять любой вариант задания, класс DBClass с помощью контекстного меню объедините c классом DataAccess (Merge to Model Element..., так чтобы целевым был класс DataAccess). Удалите из класса DataAccess шаблонные операции create, read, update, delete. Операции initialize и disconnect оставьте. В подсистеме DataAccess переименуйте кооперацию JDBC2 в IDataAccessRealization. Добавьте ей стереотип «interface realization» и удалите стереотип «mechanism». Откройте диаграмму классов Main в подсистеме DataAccess. На ней указано, что при реализации доступа к БД используются элементы, описанные в пакетах java::lang и java::sql. Поэтому откройте диаграмму пакетов из пакета DataAccess, перенесите на неё пакеты java::lang и java::sql с уровня Middleware из пакета java. Убедитесь, что отобразились зависимости импорта (Dependency или Import) от подсистемы DataAccess к пакетам java::lang и java::sql. Если нет, то добавьте их на диаграмму пакетов. При этом зависимости должны быть направлены от зависящего пакета в сторону пакетов, от которых он зависит. Пакет-подсистема DataAccess является конкретизацией параметризованного пакета RDBMS-JDBC. Добавьте пакет RDBMS-JDBC на диаграмму и проведите к нему связь привязки шаблона (зависимость связывания, помеченную стереотипом «bind»). Откройте спецификацию этой зависимости и в поле Name на вкладке General введите: <DBClass -> DataAccess; PersistentObject -> Client, User, Order, ArticleOfFurniture; PersistentObjectList -> ClientList> (переводы строк при работе под Windows можно вставить как Alt+Enter). В результате, диаграмма пакетов подсистемы DBAccess должны быть похожа на рисунок 5.2.6. Рис. 5.2.6. UML-диаграмма пакетов в подсистеме DataAccess (для всех вариантов) Внутри кооперации IDataAccessRealization диаграмму последовательности initialize2 переименуйте в initialize, create2 -- в newClient, read2 -- в getClient в вариантах 1, 2, 3 и в getUserByLogin в варианте 4, disconnect2 -- в disconnect, update2 -- в createOrder, delete2 -- в deleteOrder, диаграмму составной структуры Main2 в Main. Рис. 5.2.7.A. Структура подсистемы DataAccess в браузере модели (для вариантов 1, 2 и 3) Рис. 5.2.7.B. Структура подсистемы DataAccess в браузере модели (для варианта 4) Теперь откройте находящуюся внутри подсистемы DataAccess диаграмму классов Main. Поместите на неё классы Order, User, Article и проведите зависимости к этим классам от класса DataAccess. Скройте с UML-диаграммы классы ArrayList и ClientList, так как подсистема не работает со списками и не возвращает их в результате вызовов своих операций. Добавьте на диаграмму интерфейс IDataAccess и переключите его отображение на «леденцовую» нотацию (контекстное меню, Presentation Options -> Interface Ball). Проведите связь реализации между интерфейсом IDataAccess и классом DataAccess. В результате, UML-диаграмма классов подсистемы должна быть похожа на изображённую на рисунке 5.2.8. Благодаря использованию механизма, было затрачено меньше сил на обдумывание и моделирование, чем если бы подсистема моделировалась с чистого листа. Переходите к моделированию внутреннего поведения подсистемы DataAccess. Рис. 5.2.8. UML-диаграмма классов Main подсистемы DataAccess (для всех вариантов) Внутри кооперации IDataAccess находятся 6 диаграмм последовательности: deleteOrder, disconnect, getClient (в вариантах 1, 2, 3) или getUserByLogin (в варианте 4), initialize, newClient, newOrder. Каждая из них описывает то, что делают объекты подсистемы при вызове соответствующей операции. Реализацию операций deleteOrder, getAvailableArticle и newOrder не будут смоделированы, остальные -- будут. Продолжая выполнять любой вариант задания, смоделируйте реализацию операции disconnect(). На диаграмме последовательности disconnect левая линия жизни должна представлять объект dao:DataAccess, входящее сообщение, принимаемое им, должно быть связано с операцией disconnect(). Внесите необходимые изменения так, чтобы UML-диаграмма приняла вид, изображённый на рисунке 5.2.9.
Рис. 5.2.9. UML-диаграмма последовательности, описывающая реализацию операции disconnect() (для всех вариантов) Аналогично, продолжая выполнять любой вариант задания, смоделируйте реализацию операции initialize(). UML-диаграмма последовательности initialize должна иметь вид, изображённый на рисунке 5.2.10.
Рис. 5.2.10. UML-диаграмма последовательности, описывающая реализацию операции initialize() (для всех вариантов) Если у Вас вариант 2, то смоделируйте реализацию операции newClient(clientName):Client. На диаграмме последовательности newClient левая линия жизни должна представлять экземпляр dao:DataAccess, самая правая -- obj:Client. Свяжите найденное сообщение с операцией newClient. Свяжите второе сверху сообщение с вызовом операции initialize. Свяжите четвёртое сверху сообщение с вызовом операции setName. UML-диаграмма должна иметь вид, изображённый на рисунке 5.2.11.A.
Рис. 5.2.11.A. UML-диаграмма последовательности, описывающая реализацию операции newClient(clientName:string):Client (только для варианта 2) Если у Вас вариант 3, то смоделируйте реализацию операции getClient(clientName):Client. На диаграмме последовательности getClient левая линия жизни должна представлять объект dao:DataAccess, а вторая слева -- obj:Client (снимите у неё флажок множественности). Линия жизни объекта ClientList должна быть удалена. Свяжите найденное сообщение, принимаемое экземпляром DataAccess, с операцией getClient. Добавьте классу Client новые операции setAddress(value:string[3]):void, setPhones(value:string[*]):void. Проще всего геттеры и сеттеры атрибута добавлять через его контекстное меню (откройте диаграмму классов WarehouseArtefacts в одноимённом пакете, выделите атрибут для сеттера, вызовите контекстное меню -> Create Getter and Setter). Замените на диаграмме последовательности оператор взаимодействия в комбинированном фрагменте с loop на opt. Добавьте новое сообщение-вызов isAfterLast() до комбинированного фрагмента. Добавьте новые сообщения внутрь фрагмента. Удалите лишнее сообщение-вызов next() внутри фрагмента. UML-диаграмма должна иметь вид, изображённый на рисунке 5.2.11.B.
Рис. 5.2.11.B UML-диаграмма последовательности, описывающая реализацию операции getClient(clientName:string):Client (только для варианта 3) Если у Вас вариант 4, то смоделируйте реализацию операции getUserByLogin(login):User. На диаграмме последовательности getUserByLogin левая линия жизни должна представлять объект dao:DataAccess, а вторая слева -- obj:User (снимите у неё флажок множественности). Линия жизни объекта ClientList должна быть удалена. Свяжите найденное сообщение, принимаемое экземпляром DataAccess, с операцией getUserByLogin. Добавьте классу User новые операции setType(type:UserType):void, setPasswordHash(passwordHash:long[2]):void. Проще всего геттеры и сеттеры атрибута добавлять через его контекстное меню (откройте диаграмму классов WarehouseArtefacts в одноимённом пакете, выделите атрибут для сеттера, вызовите контекстное меню -> Create Getter and Setter). Замените на диаграмме последовательности оператор взаимодействия в комбинированном фрагменте с loop на opt. Добавьте новое сообщение-вызов isAfterLast() до комбинированного фрагмента. Добавьте новые сообщения внутрь фрагмента. Удалите лишнее сообщение-вызов next() внутри фрагмента. UML-диаграмма должна иметь вид, изображённый на рисунке 5.2.11.C.
Рис. 5.2.11.C. UML-диаграмма последовательности, описывающая реализацию операции getUserByLogin(login):User (только для варианта 4) Упражнения по проектированию подсистемы DataAccess завершены. Переходим к проектированию подсистемы ASAccess. |
Упражнение 5.2.7. Проектирование подсистемы ASAccess на основе механизма XMLRPCInterchange |
Для начала убедитесь, что интерфейс подсистемы IASAccess верно представлен в модели. В ходе предшествующих упражнений в интерфейс добавлена единственная операция: IASAccess::orderoperation(json:string[]):boolean. Если такой операции интерфейса в модели нет, или если её сигнатура не полна, то следует дополнить модель. Далее следует создать прокси-класс подсистемы ASAccess. Экземпляр этого класса будет принимать и обрабатывать все вызовы операций, входящие в подсистему. В браузере найдите интерфейс IASAccess, откройте его контекстное меню и создайте дубль интерфейса при помощи Duplicate (не Duplicate Recursively). Переименуйте дубль из IASAccess2 в ASAccess. Уберите стереотип «interface», добавьте стереотип «subsystem proxy». Переместите прокси-класс в подсистему ASAccess. Переименуйте внутри пакета ASAccess диаграмму классов XMLRPCInterchange2 в Main, диаграмму пакетов XMLRPCInterchange2 также в Main. Так как единственная операция не содержит в своей сигнатуре параметров -- экземпляров нестандартных классов, и так как она возвращает булево значение, то в подсистеме не нужны классы ObjectToSend, ObjectToReceive, CustomTypeFactory, CustomParser и CustomSerializer. Удалите их из браузера модели. Класс XMLRPCConnector с помощью контекстного меню объедините c классом ASAccess (Merge to Model Element..., так чтобы целевым был класс ASAccess). Удалите из класса ASAccess шаблонную операцию sendRequest. В подсистеме ASAccess переименуйте кооперацию XMLRPCInterchange2 в IASAccessRealization. Добавьте ей стереотип «interface realization» и удалите стереотип «mechanism». Откройте диаграмму классов Main в подсистеме ASAccess. На ней указано, что при обмене данными с внешней подсистемой по протоколу XML-RPC используются элементы, описанные в пакетах java::net и org::apache::xmlrpc. Поэтому откройте диаграмму пакетов из пакета ASAccess, перенесите на неё пакеты java::net и org::apache::xmlrpc с уровня Middleware из пакетов java и org::apache. Убедитесь, что отобразились зависимости импорта (Dependency или Import) от подсистемы ASAccess к пакетам java::net и org::apache::xmlrpc. Если нет, то добавьте их на диаграмму пакетов. При этом зависимости должны быть направлены от зависящего пакета в сторону пакетов, от которых он зависит. Пакет-подсистема ASAccess является конкретизацией параметризованного пакета XMLRPCInterchange. Добавьте пакет XMLRPCInterchange на диаграмму и проведите к нему связь привязки шаблона (зависимость связывания, помеченную стереотипом «bind»). Откройте спецификацию этой зависимости и в поле Name на вкладке General введите: <XMLRPCConnector -> ASAccess>. В результате, диаграмма пакетов подсистемы DBAccess должны быть похожа на рисунок 5.2.12. Рис. 5.2.12. UML-диаграмма пакетов в подсистеме ASAccess (для всех вариантов) Внутри кооперации IASAccessRealization диаграмму последовательности init2 переименуйте в init, sendRequest2 -- в orderOperation, диаграмму составной структуры XMLRPCInterchange Main2 в Main. Рис. 5.2.13. Структура подсистемы ASAccess в браузере модели (для всех вариантов) Теперь откройте находящуюся внутри подсистемы ASAccess диаграмму классов Main. Скройте с UML-диаграммы интерфейсы TypeSerializer и TypeParser, так как подсистема не работает с пользовательскими типами данных. Также скройте ненужные классы Object и TypeFactoryImpl. Добавьте на диаграмму интерфейс IASAccess и переключите его отображение на «леденцовую» нотацию (контекстное меню, Presentation Options -> Interface Ball). Проведите связь реализации между интерфейсом IASAccess и классом ASAccess. В результате, UML-диаграмма классов подсистемы должна быть похожа на рисунок 5.2.14. Благодаря использованию механизма мы затратили меньше сил на обдумывание и моделирование, чем если бы делали подсистему с чистого листа. Рис. 5.2.14. UML-диаграмма классов в подсистеме ASAccess (для всех вариантов) Если у Вас вариант 1, то выполните моделирование поведения подсистемы ASAccess. При других вариантах переходите к проектированию классов. Внутри кооперации IASAccess находятся UML-диаграммы последовательности init, orderOperation. Каждое взаимодействие будет описывать, что делают объекты подсистемы при вызове соответствующей операции. На диаграмме последовательности init вторая слева линия жизни должна представлять объект cn:ASAccess (добавьте ей стереотип «subsystem proxy»), входящее сообщение, принимаемое им, должно быть связано с операцией init. Так как обмен происходит данными только стандартных типов, то следует удалить линию жизни объекта-фабрики (вторую справа) и два нижних сообщения. UML-диаграмма примет вид, изображённый на рисунке 5.2.15. Взаимодействие описывает инициализацию подсистемы перед первым обменом данными с внешней системой. Рис. 5.2.15. UML-диаграмма последовательности, описывающая реализацию операции init() в подсистеме ASAccess (только для варианта 1) Если у Вас вариант 1, то продолжите моделирование поведения подсистемы ASAccess. При других вариантах переходите к проектированию классов. На диаграмме последовательности orderOperation левая линия жизни должна представлять cn:ASAccess (добавьте ей стереотип «subsystem proxy»), а самая правая -- действующее лицо Бухгалтерская система (следует переименовать XMLRPCServer в Бухгалтерскую систему). Шаблонная UML-диаграмма описывает сложное взаимодействие, при котором не только пересылается объект данных во внешнюю систему, но и в ответ получается объект-результат. Моделируемая нами операция ничего такого не предусматривает, а значит, лишние линии жизни следует удалить из модели (из фрейма orderOperation): result, cp, cs, cf. Должны остаться только три линии жизни: cn:ASAccess, client:XMLRpcClient и Бухгалтерская система. Свяжите найденное сообщение, принимаемое экземпляром ASAccess, с операцией orderOperation. Свяжите рефлексивное сообщение внутри opt-фрагмента с операцией init. У третьего сверху сообщения измените связанную операцию на execute(XmlRpcClientConfig, String, Object[]) (контекстное меню -> Select Operation...). Задайте аргументы в сообщении execute (контекстное меню, Open Specification, вкладка Arguments). Удалите примечания с UML-диаграммы последовательности. Добавьте нижнее потерянное сообщение (Lost Message) от объекта cn:ASAccess и укажите его тип -- возврат (контекстное меню -> Type(Reply)). В спецификации сообщения в поле Name укажите, что возвращается. UML-диаграмма примет вид, изображённый на рисунке 5.2.16. Рис. 5.2.16. UML-диаграмма последовательности, описывающая реализацию операции orderOperation() в подсистеме ASAccess (только для варианта 1) Упражнения по проектированию подсистемы ASAccess завершены. |
Упражнение 5.2.8. Проектирование классов системы |
Проектирование классов включает следующие действия: детализацию проектных классов; уточнение операций и атрибутов; моделирование состояний для экземпляров классов; уточнение связей между классами. При детализации проектный класс может быть разбит на несколько классов из соображений, связанных с его реализацией в коде. Класс может быть удалён из модели, если его экземпляры являются посредниками, не несущими содержательных обязанностей. Обязанности классов, определённые в при эскизном моделировании и документированные в виде операций анализа, преобразуются в операции, которые будут реализованы в коде. При этом каждой операции присваивается краткое имя, характеризующее её, определяется полная сигнатура операции, создаётся краткое описание операции, содержащее смысл всех её параметров, определяется видимость операции, определяется область действия операции (операция экземпляра или операция класса). Если метод, реализующий операцию, реализует нетривиальный алгоритм, то он моделируется на диаграмме деятельности. Уточнение атрибутов классов заключается в следующем: задаются типы атрибутов, их множественность и значения по умолчанию (необязательно); задаётся видимость атрибутов; при необходимости определяются производные (вычисляемые) атрибуты, статические атрибуты. Если экземпляры некоторого класса реализуют сложное поведение, меняют своё поведение в зависимости от состояния, то для этого класса строят диаграмму состояний. При построении UML-диаграммы состояний уточняются операции, так как они могут быть связаны с событиями, вызывающими смену состояний, и с действиями на переходах и внутри состояний. Уточняются атрибуты, так как текущее состояние экземпляра определяется совокупностью значений его атрибутов. Затем производится уточнение связей между классами. Ассоциации, созданные при эскизном моделировании, которые соответствуют временным соединениям между объектами, заменяются на зависимости. Часть оставшихся ассоциаций могут быть заменены на агрегации или композиции, если они не симметричны и если их экземпляры соединяют объекты-владельцы с объектами-частями. При полюсах ассоциаций указываются мощности, направления связей, свойства полюсов с максимальной мощностью больше 1 (set, ordered, bag, sequence или unique / nonunique, ordered / unordered), квалификаторы. Классы ассоциаций могут быть трансформированы в классы материалиализованной связи ради облегчения их воплощения в коде. Некоторые связи обобщения могут быть преобразованы применением метаморфозы подтипов. Выполните упражнения по проектированию классов системы обработки заказов. Откройте в пакете WarehouseArtefacts диаграмму классов. Добавьте и уточните атрибуты и операции классов, чтобы придать диаграмме вид, схожий с рисунком 5.2.17. Статические (подчеркнутые) атрибуты и операции пометьте, указав в их спецификации в поле Scope значение сlassifier. Аналогично поступите с выводимыми (начинающимися со слэша) атрибутами (отметив флажок Derived). Укажите квалификатор, используя контекстное меню ассоциации. Рис. 5.2.17. UML-диаграмма классов WarehouseArtefacts (для всех вариантов) Экземпляры класса Order должны по-разному обрабатывать вызовы их операции в зависимости от состояния заказа. Например. если сборка заказа закончена, то в него нельзя добавлять новые позиции. Это признак сложного поведения и причина для создания UML-диаграммы состояний. Добавьте классу Order диаграмму состояний Lifeсycle. Создайте начальное псевдосостояние (Initial), финальное состояние (FinalState) и состояние Active (State). Внутри состояния Active разместите подсостояния InProcess, Cancelled, Filled, Delivered и псевдосостояние выбора (Choice). Чтобы была возможность создавать подсостояния, предварительно добавьте внутрь состояния Active регион (контекстное меню -> Add Horizontal Region). Соедините состояния переходами, как указано на рисунке 5.2.18. Переходу может быть добавлено событие (триггер), указываемое до слэша; действие, указываемое после слэша; сторожевое условие, записываемое в прямоугольных скобках. События addItem, removeItem, delete, markDelivery, markFilledItem, cancel и when(numOfItems>0 && numOfItems == numOfFilledItems) добавьте на вкладку Triggers спецификаций переходов. Типы всех событий, кроме последнего -- события вызова (Call Trigger). Тип последнего события -- событие изменения (Change Trigger). Событие removeItem приписано разным переходам. Не следует создавать дважды это событие. Привяжите одно и то же событие обоим переходам. Действия при переходах укажите в поле Effect, текст действия укажите в имени создаваемой деятельности. Значок "^" в записи действия обозначает отправку сообщения другому объекту. Чтобы добавить внутренние переходы (переходы без стрелок на диаграмме) внутри состояния InProcess добавьте сначала ему внутренний регион с помощью контекстного меню (Add Horizontal Region). В итоге модель состояний должна соответствовать изображённому на рисунках 5.2.18, 5.2.19.
Рис. 5.2.18. UML-диаграмма состояний Lifecycle внутри класса Order (для всех вариантов) Рис. 5.2.19. Структура модели состояний в браузере (для всех вариантов) К проектированию классов также относится моделирование нетривиальных реализаций операций (т. е. методов). Например, тривиальными являются операции-геттеры. Нетривиальная операция содержит в своём методе ветвления и/или циклы. В модель внутрь проектного класса OrderController можно добавить диаграмму деятельности newOrderData (см. рис. 5.2.20), а также внутрь проектного класса Order -- диаграмму деятельности toJSON (см. рис. 5.2.21). По желанию Вы можете построить эти UML-диаграммы.
Рис. 5.2.20. UML-диаграмма деятельности OrderController::newOrderData, моделирующая реализацию одноимённой операции (моделируется по желанию) Рис. 5.2.21. UML-диаграмма деятельности Order::toJSON, моделирующая реализацию одноимённой операции (моделируется по желанию) Уточните связи между классами на диаграмме DesignCRUDOrdersVOPC проектной реализации варианта использования CRUD данных о заказах. Откройте диаграмму (Design Model -> Use Case Realization -> DesignCRUDOrdersVOPC). Удалите из модели (в Model Explorer) лишние ассоциации между проектными классами. Добавьте недостающую зависимость OrderController от Client (она есть, т. к. при создании заказа используется локальный объект -- экземпляр Client). Осуществите уточнение связей. OrderController использует интерфейс, для этого в нём хранится ссылка на экземпляр класса, реализующего этот интерфейс. На диаграмме этот факт отображается агрегацией, направленной к интерфейсу. OrderController также хранит ссылку на текущий заказ. Укажите направления ассоциаций и мощности при их полюсах. Ассоциации без явных стрелочек являются двунаправленными. Рис. 5.2.22. Уточненная UML-диаграмма классов DesignCRUDOrdersVOPC (для всех вариантов) |
Упражнение 5.3. Проектирование схемы реляционной базы данных |
Если среди проектных классов есть устойчивые, чьи экземпляры должны сохраняться в периодах между запусками системы, следует обеспечить сохранение их в базе данных (например, реализовав подсистему обеспечения устойчивости на базе RDBMS-JDBC) и создать схему реляционной базы данных. Фактически, следует отобразить объектную модель в реляционную. Одна из стратегий при этом состоит в том, что для каждого устойчивого класса создаётся собственная таблица. Атрибуты класса переводятся в столбцы таблицы. Столбцы для хранения выводимых атрибутов не заводятся, т. к. эти значения вычисляются при выполнении запросов. Атрибуты с нескалярными значениями (массивами) переводятся в отдельные таблицы, чтобы не нарушать ограничений 1й нормальной формы. Атрибут-идентификатор (или набор атрибутов) переводится в первичный ключ. Ассоциации моделируются с помощью связей между таблицами (связывающими значения первичного ключа записей одной таблицы со значениями внешнего ключа другой таблицы). Заметим, что связи между таблицами обычно двунаправленные, по записям любой из связанных таблиц можно найти соответствующие записи другой таблицы. Связи между таблицами могут быть идентифицирующими и не идентифицирующими. Идентифицирующая связь указывает, что внешний ключ включает в себя часть первичного ключа, то есть ключ родительской записи является частью ключа дочерних записей. Связь отображается как композиция, если требуется указать на каскадированное удаление связанных записей из подчинённой таблицы. В некоторых случаях для ассоциации (например, с максимальными мощностями обоих полюсов *) требуется создавать дополнительную служебную таблицу, хранящую соединения между объектами. Для отображения обобщений используются разные способы. Один из них -- "отдельная таблица для каждого класса". В этом случае у всех получившихся таблиц будет один и тот же первичный ключ, который в таблицах подклассов будет также внешним ключом. Выполните упражнение по проектированию схемы реляционной базы данных. Продублируйте рекурсивно пакет WarehouseArtefacts. Полученный дубль переименуйте в Database Schema и переместите в корень Design Model. Назначим этому пакету стереотип «schema». С помощью Model Explorer удалите всё лишнее из этого пакета: зависимости, перечислимые типы, класс ClientList, диаграмму состояний, диаграммы деятельности, все операции всех классов, все выводимые атрибуты всех классов. Диаграмму WarehouseArtefacts2, находящуюся в пакете, переименуйте в Database Schema. Добавьте классам, находящимся на диаграмме стереотип «table» и уберите стереотип «entity». Переименуйте классы, добавив к именам приставку Table. Добавьте класс (таблицу) TableStatic для хранения значений статических атрибутов. Добавьте класс (таблицу) TablePhone для хранения телефонов клиентов. См. рисунок 5.3.1. Эту схему можно использовать для хранения сведений о заказах, клиентах, пользователях, предметах мебели. Таблица с записями о заказах состоит из 7 столбцов, один из которых является первичным ключом («PK»), а два -- внешними ключами («FK») для связи с записями из таблиц клиентов и пользователей. Позиции заказа хранятся в отдельной таблице TableOrderItem. В этой таблице 6 столбцов, один из которых является первичным ключом («PK»), а два других -- внешними ключами («FK») для связи с таблицами артикулов и заказов. У таблицы есть составной альтернативный ключ («AK») из двух столбцов. Связь между таблицами TableOrder и TableOrderItem не идентифицирующая, так как никакая часть первичного ключа не является внешним ключом. Сведения о заказываемых предметах мебели хранятся в таблице TableArticleOfFurniture. В ней 4 столбца, один из которых является первичным ключом, а ещё один -- альтернативным ключом. Связь этой таблицы с таблицей TableOrderItem также не идентифицирующая. Заметим, что всякий раз внешний ключ для связи 1 к * добавляется в таблицу со стороны *. В таблице TableClient значение атрибута address:string[3] хранится в трёх столбцах-строках. Значение атрибута phones:string[*] хранится в отдельной таблице TablePhone. Заметьте, как связана эта таблица с таблицей TableClient. Связь идентифицирующая, так как первичный ключ таблицы TablePhone состоит из двух столбцов, и один из них -- clientId -- также является внешним ключом. Связь промоделирована как композиция. Это означает, что при удалении записи о клиенте удаляются и все связанные записи о телефонах удаляемого клиента. Такое же каскадированное удаление записей о позициях заказа, происходящее при удалении записи о заказе, показано композицией между таблицами TableOrder и TableOrderItem. Согласно этой схеме одному объекту -- экземпляру класса Order -- будут соответствовать одна запись в таблице TableOrder и связанные с ней записи в таблице TableOrderItem. Во всех этих записях будет одно и то же значение номера заказа. Для любой записи в таблице TableOrderItem можно найти связанную с ней запись из таблицы TableOrder о заказе, к которому относится эта позиция. И наоборот, для любой записи из таблицы TableOrder можно найти связанные с ней записи из таблицы TableOrderItem о позициях этого заказа. Можно видеть, что связь между таблицами двунаправленная. Каждой записи в таблице TableOrderItem соответствует одна запись из таблицы TableArticleOfFurniture. Соответствие между объектами других классов-сущностей и записями других таблиц определите самостоятельно.
Рис. 5.3.1. UML-диаграмма классов Database Schema (для всех вариантов) Упражнения по анализу и проектированию системы обработки заказов на этом закончены. Остались не реализованными остальные варианты использования, но не преследовалась цель полностью спроектировать систему. В рамках упражнений были рассмотрены различные виды работ, выполняемых в рамках моделирования создаваемой системы. Перед тем как сдавать полученную модель, попробуйте ответить на вопросы из списка. |
Предупреждение |
Размещение на других ресурсах, а также коммерческое использование материалов, опубликованных в данном разделе, возможно только с разрешения авторов. По всем вопросам пишите: © Кафедра системного программирования ВМК МГУ. Обновлено: 21.III.2021 |