Главная страница « Информация « 3 курс « ООАП«

UML-моделирование системы обработки заказов в среде Visual Paradigm 15.2


Пособие составлено доц. кафедры СП, канд. физ.-мат. наук Малышко В. В.

Размещение на других ресурсах, а также коммерческое использование материалов, опубликованных в данном разделе, возможно только с разрешения авторов. По всем вопросам пишите:   

Содержание


1. Сведения о среде Visual Paradigm 15.2
2. Система обработки заказов. Начальное описание
3. Определение требований к системе
      Упражнение 3.1. Создание действующих лиц
      Упражнение 3.2. Создание вариантов использования
      Упражнение 3.3. Добавление описаний вариантов использования
      Упражнение 3.4. Построение диаграмм деятельности в модели вариантов использования
4. Анализ системы
      Упражнение 4.1. Создание структуры модели в соответствии с соглашениями моделирования
      Упражнение 4.2. Анализ варианта использования «CRUD данных о заказах»
      Упражнение 4.3. Анализ варианта использования «Войти в систему»
5. Проектирование системы
      Упражнение 5.1. Проектирование архитектуры системы
      Упражнение 5.2. Проектирование элементов системы
      Упражнение 5.3. Проектирование базы данных

1. Сведения о среде Visual Paradigm 15.2


      Visual Paradigm Community Edition [www.visual-paradigm.com] версии 15.2 -- среда объектно-ориентированного проектирования на языке UML, распространяемая бесплатно для некоммерческого использования. Для установки следует загрузить дистрибутив со страницы загрузки, установить его. Среда является многоплатформенной. GUI среды для разных платформ различается. В пособии описана реализация для Windows. При установке укажите путь, например, C:\Program Files\Visual Paradigm CE. Для запуска среды вызывается исполняемый файл Visual Paradigm.exe из директории C:\Program Files\Visual Paradigm CE\bin. При первых запусках среда будет предлагать сообщить своё имя и e-mail для получения регистрационного кода. Получив код по электронной почте, следует активировать лицензию. Некоторые функции среды доступны только в её платных версиях. Упражнения составлены с таким расчётом, что для их выполнения достаточно возможностей бесплатной версии (Community Edition).

      Запустив среду, указываем путь к рабочей области (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, а также возможные варианты пунктов меню и проч.

      Необходимо начинать не с пустого проекта, а с шаблона, в котором уже создана основная структура модели, добавлены стереотипы и проектные механизмы JDBC и XMLRPCInterchange. Загружаем архив шаблона [zip] с веб-странички курса. Разворачиваем его в рабочую область. В рабочей области появился каталог с пиктограммами стереотипов, описание стереотипов stereotypes.xml и файл проекта -- myProject.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. в интерфейсе Classic, или вид на рисунке 1.1.a в интерфейсе Sleek.


Рис. 1.1. Окно среды после создания модели

Рис. 1.1. Окно среды после создания модели (Classic).


Рис. 1.1.a. Окно среды после создания модели

Рис. 1.1.a. Окно среды после создания модели (Sleek).


      В левой верхней части находится навигатор или браузер, показывающий структуру проекта и модели. Для наших целей больше всего подходит вторая закладка -- Model Explorer (или возможный вариант: Model Structure). Преимущественно будем использовать его. В этот браузер мы будем добавлять диаграммы, пакеты, и другие составляющие модели с помощью контекстного меню. Правая часть окна состоит из редактора диаграмм.

      Согласно технологии 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», указывающий, что пакет является архитектурным представлением.

      Вводные замечания даны, переходим к моделированию.

2. Система обработки заказов. Начальное описание


      В софтверную компанию обратился директор мебельного магазина с контрактом на создание программной системы учёта заказов. Из-за наплыва клиентов учёт заказов на бумаге и в электронных таблицах перестал быть возможен. Создаваемая программная система должна решить эту проблему.

      Система должна обеспечивать следующие возможности: добавление сведений о новых заказов, изменение сведений о ранее введённых заказах, учёт хода выполнения заказов, учёт сведений об текущих остатках на складе. При получении сведений о новом заказе система должна также послать сообщение внешней программе -- бухгалтерской системе, которая выписывает счёт заказчику. Любой заказ может содержать одну или более товарных позиций. Для каждой позиции заказа указывается наименование товара и его количество. Заполненный заказ получает кладовщик, который начинает сборку заказа. Если для каждой позиции товара на складе находится товар в достаточном количестве, то товар резервируется, и заказ помечается выполненным. Если требуемого товара нет на складе, то заказ может быть отменён, либо выполнение заказа задерживается до поступления товара на склад.

3. Определение требований к создаваемой системе


      Выполняя упражнения, мы сразу переходим к определению требований, минуя моделирование бизнес-процессов. Позволительно так поступать в случаях, когда предметная область, для которой разрабатывается ПО, сравнительно проста или хорошо знакома разработчикам.

      Определение требований -- процесс, в ходе которого определяются задачи, поставленные перед разработчиками, и создаются модели, на основе которых планируется разработка системы. Требование -- это условие, которому должно удовлетворять программное обеспечение, или свойство, которым оно должно обладать, чтобы удовлетворить потребность пользователя в решении некоторой задачи, или чтобы соответствовать условиям контракта, спецификации или стандарта. Все требования делятся на функциональные и нефункциональные. Функциональные требования определяют действия, которые должна выполнять система, без учёта ограничений, связанных с её реализацией. Нефункциональные требования не определяют поведение системы, но описывают её свойства или атрибуты системного окружения. Например, нефункциональными являются требования к производительности системы и требования к аппаратуре, на которую может быть установлена система.

      Требования оформляются в виде ряда документов и моделей. К основным документам, согласно технологии Unified Process, относятся: концепция, глоссарий предметной области, дополнительная спецификация. Концепция определяет глобальные цели проекта и основные особенности разрабатываемой системы. Существенной частью концепции является постановка задачи разработки, определяющая требования к функциям системы. Словарь предметной области (глоссарий) определяет общую терминологию для всех моделей и описаний требований к системе. Дополнительная спецификация (технические требования) содержит описание нефункциональных требований к системе, таких, как надёжность, удобство использования, производительность, сопровождаемость и др.

      Постановка задачи разработки системы обработки заказов:

      Пользователями новой системы будут продавцы и работники склада (заведующий и кладовщики).

      База данных системы будет поддерживаться реляционной СУБД. Система должна обеспечивать возможность продавцам вводить сведения о новых заказах и изменять сведения о заказах, хранящиеся в системе. Сведения о заказе могут быть изменены до тех пор пока ведётся работа на складе по его сборке. Собранные (выполненные) заказы поставляются заказчикам, внесение изменений в сведения о них запрещено. Дата окончания сборки заказа хранится в системе. По её наступлении заказ считается выполненным. Не выполненный заказ может быть отменен. Сведения об отменённых заказах изменению не подлежат.

      При вводе сведений о заказе важно сохранить дату, когда был принят заказ, и дату, до которой нужно осуществить сборку и доставку заказа. Каждый заказ содержит одну или несколько позиций. В любой позиции указывается наименование предмета мебели и количество штук. После ввода заказа данные передаются в бухгалтерскую систему для составления счёта на оплату.

      Работают несколько продавцов, поэтому необходимо обеспечить защиту данных, чтобы продавец мог работать только с собственными заказами, и не имел доступа к данным чужих заказов. Продавец может удалить данные о любом из своих заказов.

      Заведующий складом использует систему, чтобы работать с данными об остатках -- описями, в которых указываются текущие (на момент составления описей) количества предметов мебели на складе. Остатки определяются системой по данным последней инвентаризации и данным о выполнении заказов. Например, если по данным инвентаризации было 10 стульев и 8 стульев отмечены как выполненные позиции заказов введённых после инвентаризации, (т. е. стулья переданы заказчикам или отложены в собираемые заказы), то текущий остаток -- 2 стула. При проведении инвентаризации для каждого предмета мебели со склада текущее его количество заносится в опись. Данные из описи вводятся в систему. Относительно этих данных будут рассчитываться остатки до ввода следующей описи.

      Кладовщики отмечают в системе ход выполнения заказов. Любой кладовщик может работать с любым заказом. Кладовщик может пометить какую-либо позицию заказа как выполненную. При этом соответствующее количество предметов мебели вычитается при расчёте текущих остатков. Если выполнены все позиции заказа, он также считается выполненным. Кладовщик может пометить невыполненный заказ как отменённый, если нужной для выполнения заказа мебели на складе нет. При этом снимается резерв с выполненных позиций отменённого заказа и, соответственно, увеличиваются остатки.

      Глоссарий предметной области создаётся на основе описания системы выполнения заказов и постановки задачи, а также глоссария деятельности предприятия, созданного в ходе бизнес-моделирования, и концепции. Глоссарий предназначен для описания терминологии области, в которой будет работать ПО. Выделяются термины, им даётся описание, рассчитанное на широкий круг читателей (пользоваться этим описанием будут все лица, заинтересованные в разработке системы). Глоссарий составляется на русском языке. Термины сопровождаются переводом на английский на тот случай, если термин будет использован в модели системы как название класса, пакета и т. п.

      Глоссарий:

Бухгалтерская система
(Accounting System)

Внешняя система, в которую передаются данные обо всех введённых заказах.

Заведующий складом
(Warehouseman)

Пользователь системы. Имеет возможность работать с данными об остатках (вносить данные новой описи, просматривать и распечатывать данные описей, введённых ранее, удалять неактуальные данные описей, узнать остатки, рассчитанные по данным описей и принятых заказов).

Заказ
(Order)

Непустой перечень требуемых заказчиком позиций. Дата заказа указывает момент его создания. Дата поставки заказа отмечает день, к которому должны быть завершены работы по сборке и поставке заказа. Дата выполнения заказа указывает день, когда была помечена выполненной последняя из невыполненных позиций заказа.

Заказчик
(Client)

Покупатель мебельного магазина. Данные о покупателе включают в себя ф., и., о., список его телефонов, адрес для доставки мебели.

Инвентаризационная опись
(Inventory)

Перечень, в котором для каждого предмета мебели, хранящегося на складе, указано его количество, имеющееся в наличии на дату, когда была составлена опись.

Кладовщик
(Stockman)

Пользователь системы. Работник склада, отвечающий за сборку заказов. Может помечать позиции заказов как выполненные, а невыполненные заказы -- как отменённые.

Остатки
(Balance)

Данные о количестве предметов мебели на складе, рассчитываемые по сведениям из последней описи и данным о выполненных позициях заказов.

Позиция заказа
(Order Item)

Один или более одинаковых предметов мебели, указанных в заказе. Позиция характеризуется наименованием, количеством, номером по порядку и статусом (выполнена или нет)

Предмет мебели
(Article of furniture)

Предмет обстановки, хранящийся на складе. Может быть указан в позиции заказа. Характеризуется наименованием. Количество предметов мебели указывается в инвентаризационных описях.

Продавец
(Salesperson)

Пользователь системы. Автор произвольного количества заказов. Может вводить заказы и изменять введённые им ранее заказы.

      Дополнительная спецификация определяет нефункциональные требования к системе, такие, как надёжность, удобство использования, производительность, сопровождаемость, а также ряд функциональных требований, являющихся общими для нескольких вариантов использования. Назначение дополнительных спецификаций -- определить требования к системе обработки заказов, которые не отражены в других документах и моделях. Вместе они образуют полный набор требований к системе. Рассмотрим дополнительную спецификацию:

  1. Функциональные возможности
    Система должна обеспечивать многопользовательский режим работы. Несколько кладовщиков и/или продавцов могут одновременно использовать систему.
    Система должна обеспечивать выполнение следующих правил:

    • В заказе должна быть хотя бы одна позиция. Пустые заказы не сохраняются в системе.

    • Количество предметов мебели в любой позиции заказа -- натуральное число.

    • Если в заказе все позиции помечаются как выполненные, то он считается собранным, т. е. готовым к отправке заказчику.

    • Невыполненный заказ может быть отменен. При этом позиции, которые были отмечены как выполненные, отменяются, остатки увеличиваются.

    • Дата поставки заказа не может предшествовать дате его создания.

    • И т. п.

  2. Требования по реализации
    Система должна быть совместима с Windows.

  3. Надёжность
    Система должна быть в работоспособном состоянии 24 часа в день 7 дней в неделю, время простоя -- не более 10%.

  4. Производительность
    Система должна поддерживать до 30 одновременно работающих пользователей.

  5. Безопасность
    Система должна запрещать каждому продавцу изменять заказы, которые созданы другими продавцами. Только кладовщики имеют право отмечать выполнение и отмену заказов. Только заведующий складом может работать со сведениями об описях.

  6. Проектные ограничения
    Система должна поддерживать протокол обмена данных с бухгалтерской системой.

      Функциональные требования к системе моделируются и документируются с помощью вариантов использования (use case). Вариант использования (use case) -- связный элемент функциональности, предоставляемый системой при взаимодействии с действующими лицами, и соответствующий цели некоторого действующего лица. Действующее лицо (actor) -- роль, обобщение элементов внешнего окружения системы, ведущих себя по отношению к системе одинаковым образом. Такие роли исполняют либо пользователи системы, либо внешние системы, взаимодействующие с системой. Изредка роль действующего лица исполняет некий невычислительный процесс, протекающий во внешней среде: ход времени, изменение температуры воздуха и т. п..

      В контексте процесса управления требованиями варианты использования трактуются следующим образом:

  • вариант использования фиксирует соглашение между участниками проекта относительно поведения системы;

  • вариант использования описывает поведение системы при различных условиях, когда система отвечает на запрос одного из участников, называемого основным действующим лицом;

  • основное действующее лицо инициирует взаимодействие с системой, чтобы добиться некоторой цели (если вариант использования имеет уровень «цель пользователя»). Система отвечает, соблюдая интересы всех действующих лиц.

      Модель вариантов использования состоит из диаграмм вариантов использования, текстовых описаний вариантов использования и диаграмм деятельности, моделирующих потоки событий вариантов использования. Диаграмма вариантов использования составляется системным аналитиком, который сначала выявляет элементы модели, а затем устанавливает связи между ними, а также структурирует модель. Элементами диаграмм вариантов использования являются варианты использования и действующие лица, соединённые разного рода связями.

      Из постановки задачи разработки и глоссария системный аналитик может выделить список действующих лиц и их интересов:

  • Продавец -- вводит заказ, изменяет заказ, удаляет заказ;

  • Кладовщик -- выполняет заказ, помечает заказ как отменённый;

  • Заведующий складом -- создаёт, просматривает, удаляет сведения об остатках;

  • Бухгалтерская система -- получает данные о введённых заказах.

Упражнение 3.1. Создание действующих лиц


      1. В Model Explorer найдите пакет Use Case View, а внутри него модель Use Case Model. В модели находится диаграмма вариантов использования Main. Откройте её двойным кликом. Диаграмма пуста. Заполним её. Если Вы работаете на FullHD-дисплее или с ещё большим разрешением, то желательно установить увеличение 130% или выше (Ctrl+), чтобы Ваши диаграммы были обозримы на обычном дисплее. С таким увеличением все элементы диаграммы и все связи между ними должны помещаться на экране. В палитре найдите элемент System. Нажмите на него. Затем поместите курсор на диаграмму и кликните. Система появится на диаграмме. Назовите добавленный элемент "Система обработки заказов". Этим элементом в модели представляется рамка моделируемой программной системы. С помощью контекстного меню добавьте системе стереотип «subject». В палитре редактора выберите элемент Actor и добавьте действующее лицо на диаграмму. Введите имя актора: Продавец. Повторите те же действия и добавьте оставшихся действующих лиц: заведующего складом, кладовщика, бухгалтерскую систему. Увеличьте размеры элемента System, чтобы он вместил варианты использования системы. Получившаяся диаграмма примет вид, показанный на рисунке 3.1.1.

Рис. 3.1.1. Диаграмма вариантов использования после добавления действующих лиц

Рис. 3.1.1. Диаграмма вариантов использования после добавления действующих лиц

      Исходя из потребностей действующих лиц, системный аналитик может предложить следующие варианты использования: CRUD данных о заказах, CRUD данных об остатках, Выполнить заказ, Отменить заказ. Все эти варианты использования относятся к «уровню моря», т. е. соответствуют цели одного из пользователей системы. Такую цель пользователь может достичь в течение одного сеанса работы с системой. CRUD рашифровывается как Create, Read, Update, Delete (или как Create, Retrieve, Update, Destroy). Предполагается, что вариант использования «CRUD данных о заказах» описывает все функции системы, предоставляемые продавцу для управления сведениями о заказах. «CRUD данных об остатках» описывает все функции системы, предоставляемые заведующему складом для управления сведениями об остатках.

      Вариант использования «Войти в систему» не соответствует какой-либо явной цели какого-нибудь действующего лица. Он описывает функциональные требования к системе по обеспечению защиты данных. Про каждого своего пользователя система должна знать, какую роль по отношению к ней он выполняет: продавца, заведующего складом, кладовщика, к каким функциям и данным ему можно предоставлять доступ. Этот вариант использования не относится к «уровню моря». Такого рода служебные варианты использования относят к «уровню рыбы», т. е. считают соответствующими подфункциям.

Упражнение 3.2. Создание вариантов использования


Рис. 3.2.1. Начальная версия диаграммы вариантов использования (красным отмечены ошибочные связи)

Рис. 3.2.1. Начальная версия диаграммы вариантов использования (красным отмечены ошибочные связи)

      1. В палитре редактора выберем элемент Use Case и добавим вариант использования на диаграмму (внутрь System). Введём название: «CRUD данных о заказах». Повторим те же действия для добавления оставшихся вариантов использования: CRUD данных об остатках, Выполнить заказ, Отменить заказ, Войти в систему. Каждый вариант использования пометим стереотипом, указывающим его уровень. Для этого вызываем контекстное меню правым кликом, выбираем пункт Stereotypes и нужный стереотип в списке. Размещаем варианты примерно так, как показано на рисунке 3.2.1.

      2. В палитре редактора выберем ассоциацию Association и проведём её от действующего лица Продавец к варианту использования »CRUD данных о заказах». Чтобы было видно направление связи, вызовем контекстное меню у левого конца ассоциации и выберем пункт Navigable. Установим флажок на значении Unspecified. По умолчанию связь была двунаправленная, теперь же она явно указывает, направление от действующего лица к варианту использования.

      3. Повторим те же действия для добавления связей других действующих лиц и вариантов использования. Получившаяся диаграмма изображена на рис. 3.2.1. Направления связей между действующими лицами и вариантами использования показывают, какое лицо является основным, а какое второстепенным. Для варианта использования CRUD данных о заказах Продавец -- основное действующее лицо (он инициирует запуск варианта использования), а Бухгалтерская система -- второстепенное (сведения о заказах пересылаются в бухгалтерскую систему).

      4. Добавим связь расширения (Extend) от варианта использования «Отменить заказ» к варианту использования «Выполнить заказ». Связь расширения показывает, что в ходе выполнения варианта использования «Выполнить заказ» могут возникнуть условия, при которых реализуется особый сценарий, описываемый вариантом использования «Отменить заказ». Заметим, что переключение происходит не всегда. Обратите внимание, что рисовать связь следует, указав сначала расширяемый вариант использования (в который входит стрелка), а затем -- расширяющий (из которого исходит связь). Переименовать точку расширения можно, открыв спецификацию расширяемого варианта использования через контекстное меню (контекстное меню -> Open specification), и перейдя на вкладку Extension Points.

      5. Созданная диаграмма имеет недостаток в том, что у варианта использования «Войти в систему» несколько основных действующих лиц. Стандартное её прочтение предполагает, что при входе в систему с ней взаимодействуют одновременно три экземпляра действующего лица -- один продавец, один кладовщик и один заведующий. Полагая поведение системы одинаковым при входе любого пользователя, полагая что вход в систему каждый пользователь производит сам по себе, введём абстрактное действующее лицо Пользователь, подвидами которого будут лица Продавец, Заведующий складом, Кладовщик. Указать, что действующее лицо является абстрактным, нужно в спецификации (контекстное меню -> Open specification) на вкладке General, поставив флаг в поле Abstract. Другой вариант: контекстное меню -> Model Element Properties -> Abstract. Для добавления связей обобщения используйте связь обобщения (Generalization). Лишние ассоциации удалите из модели, выделяя их в Model Explorer и нажимая Del. Чтобы связи отображались в Model Explorer, осуществите его настройку: вызовите контекстное меню на белом поле Model Explorer и отметьте флажками Show Relationships. Обратите внимание, что лишний элемент (или связь) следует удалить из модели (выделяя их в Model Explorer и нажимая Del). Если необходимо сохранить элемент (или связь) в модели и всего лишь убрать с диаграммы, на которую он случайно попал по какой-то причине, выделите элемент или связь на диаграмме и используйте пункт контекстного меню Delete -> Delete View Only. Следует чётко понимать, удаляете ли Вы текущий элемент из модели или всего лишь убираете с диаграммы, оставляя в модели (маскируете). Удаление вместо маскирования (как и обратное) может быть нежелательным. Случайно удалённый элемент можно попытаться восстановить, нажав Ctrl+z. Маскированный по ошибке элемент можно снова поместить на диаграмму, перетаскивая его из Model Explorer. Маскированную по ошибке связь можно снова поместить на диаграмму с помощью контекстного меню одного из связываемых ей элементов (Related Elements -> Visualize Related Model Element, флаг Visualize, кнопка Visualize). Работать с моделью следует аккуратно, не оставляя в ней «мусора» -- случайно созданных элементов и/или связей, не видимых на диаграммах.


      Диаграмма вариантов использования должна принять вид, изображённый на рисунке 3.2.2.

Рис. 3.2.2. Итоговая диаграмма вариантов использования после исправления ошибки

Рис. 3.2.2. Итоговая диаграмма вариантов использования после исправления ошибки

      Теперь на нашей диаграмме каждый вариант использования связан ровно с одним действующим лицом, которое для него является основным, и с произвольным количеством дополнительных действующих лиц. Каждое действующее лицо прямо или косвенно связано хотя бы с одним вариантом использования. Никакие два варианта использования между собой не связаны ассоциацией. Связи между вариантами использования допускаются, если они имеют тип, отличный от ассоциации. Это могут быть связи обобщения, включения и расширения. О них рассказывается на лекциях. Системный аналитик с их помощью производит структурирование модели вариантов использования. Модель с большим количеством вариантов использования может быть разбита им на части -- пакеты. Никакие действующие лица не связаны между собой ассоциацией. Между ними допускаются лишь связи обобщения. Самостоятельно создавая диаграммы вариантов использования, старайтесь, чтобы их элементы и связи удовлетворяли таким же ограничениям. Также рекомендуется действующих лиц, являющихся ролями пользователей-людей, размещать в левой части диаграммы, а остальных, являющихся ролями программных систем или невычислительных процессов -- на правой. Рекомендуется родительские элементы в иерархии наследования/обобщения размещать выше и/или левее их сыновних элементов (наследников).

      Получившаяся диаграмма является примерным оглавлением проекта. Мы видим, какие функции и кому предоставляет система. По ней архитектор проекта может составить примерную оценку трудоёмкости всего проекта, основанную на прогнозируемой трудоёмкости реализации каждого из вариантов использования. Также архитектор может ранжировать варианты использования по приоритету. Отмеченные им более важные варианты использования будут проанализированы, спроектированы и реализованы в первую очередь.

      Для каждого варианта использования составляется описание. Выполняют эту работу use case писатели.

Упражнение 3.3. Добавление описаний вариантов использования


      Функциональные требования подробно фиксируются в описаниях вариантов использования. Описания составляются специальным образом, чтобы уменьшить вероятность неверного толкования и облегчить восприятие текста. Каждое описание включает в себя:
а) краткое описание, являющееся сжатым обзором варианта использования;
б) основной поток событий, описывающий взаимодействие системы и действующих лиц, при котором достигается цель основного действующего лица;
в) альтернативные потоки, описывающие обработку ошибок и исключительных ситуаций;
г) подчинённые потоки, которые облегчают описание основного и альтернативных потоков;
д) предусловия (которые могут отсутствовать) и постусловия (которые всегда есть).

      Каждый поток событий задаётся перенумерованным набором шагов. Используются шаги трёх типов: действие системы (например, «Система запрашивает имя пользователя и пароль»); реакция действующего лица («Пользователь вводит имя и пароль»); управление потоком («Выполнение переходит на начало основного потока»). Структура предложений, описывающих шаги, одинакова: подлежащее, сказуемое и прочее. От неё отходят лишь при описании циклов и ветвлений.

      Цикл задаётся составным описанием, в начале которого указывается условие цикла («Для каждого незафиксированного курса в плане-графике выполняется») или количество повторений. Далее следует тело цикла -- последовательность вложенных шагов (см. подчинённый поток «8Г. Утвердить график» варианта использования «Зарегистрироваться на курсы»).

      Ветвление в тривиальных случаях, когда альтернативная ветвь пуста, допускается описывать предложением с союзом если («Система помечает курс как закрытый, если в списке студентов содержится 10 записей»). Чаще ветвление описывают с помощью альтернативных потоков. В основном потоке варианта использования «Войти в систему» 3-ий шаг указывает основное продолжение потока, а альтернативный поток «3А. Неправильное имя/пароль» содержит второй вариант развития событий. Почти всегда действия по проверке условия ветвления не описывают. Вместо этого указывается шаг на котором система (или действующее лицо) подтверждает, что условие выполнено, в основном потоке, или обнаруживает, что условие нарушено, в альтернативном потоке.

      Добавьте в модель описания, приведённые ниже. Для этого скопируйте текст описания, выделите нужный вариант использования, откройте его спецификацию и на вкладке General вставьте текст в поле Description. Обратите внимание, что в описании любого варианта использования должен присутствовать хотя бы один шаг для каждого действующего лица, связанного с ним. Постусловие в описании не может отсутствовать, так как по нему тестировщики составляют тестовые сценарии. Постусловие состоит из двух частей: гарантии успеха и минимальных гарантий. Первая часть описывает, что должно быть истинно при успешном завершении варианта использования. Вторая часть -- это гарантии системы во всех случаях, в том числе в случаях неуспеха. Например, при успешном входе в систему гарантируется доступ пользователя к главному меню, но в любом случае (даже при неуспехе) -- гарантируется, что доступ не будет предоставлен тем, кто не может указать верную комбинацию пароля и логина. Пустое постусловие допускало бы произвольное поведение системы и было бы не пригодно для тестирования.

      В реальном рабочем процессе описания составляются для всех вариантов использования. Выполняя упражнения, мы создадим лишь три описания.

      Вариант использования «Войти в систему»:

Краткое описание
Данный вариант использования описывает вход пользователя в систему обработки заказов.
Основной поток событий
1. Пользователь запускает приложение.
2. Система запрашивает имя пользователя и пароль.
3. Пользователь вводит имя и пароль.
4. Система подтверждает правильность имени и пароля.
5. Система определяет тип пользователя (продавец, кладовщик или завскладом) и выводит главное меню, дающее доступ к её функциям в соответствии с типом пользователя.
Альтернативные потоки
4А. Неправильное имя/пароль
1. Система обнаруживает, что комбинация имени и пароля не верна.
2. Система сообщает об ошибке и предлагает пользователю либо заново ввести имя и пароль, либо отказаться от входа в систему.
3. Пользователь сообщает системе свой выбор.
4. В соответствии с выбором пользователя либо выполнение переходит шаг 2 основного потока, либо вариант использования завершается неуспешно.
Предусловия
Отсутствуют.
Постусловия
Гарантии успеха: Если вариант использования выполнен успешно, система предоставляет доступ к главному меню пользователю, сообщившему верную комбинацию имени и пароля.
Минимальные гарантии: В любом случае система гарантирует, что пользователю, не сообщившему верную комбинацию имени и пароля, доступ к меню не будет предоставлен.


      Обратите внимание на номера альтернативных потоков. Цифра указывает номер шага основного потока, на котором может произойти переключение на альтернативный поток, буква позволяет различить несколько альтернативных потоков, на которые можно переключиться на одном и том же шаге. Если переход на альтернативный поток может происходить в течение нескольких подряд идущих шагов, указывают их номера через дефис (например, 1-3Б). Если поток вызывается из разных шагов, он может иметь несколько номеров, перечисленных через запятую.

      Вариант использования «CRUD данных о заказах»:

Краткое описание
Данный вариант использования позволяет продавцу ввести данные о новом заказе, изменить ранее введённые данные о заказе или удалить данные о заказе. Сведения о заказе включают в себя данные о заказчике, дату поставки заказа и перечень позиций в заказе. При вводе заказа система присваивает ему дату создания. Новые сведения о заказе (изменения в заказе или сведения об удалении заказа) передаются системой в бухгалтерскую систему.
Основной поток событий
1. Продавец сообщает системе о желании работать с заказами.
2. Система запрашивает связь с бухгалтерской системой.
3. Бухгалтерская система подтверждает, что связь установлена.
4. Система запрашивает у продавца требуемое действие (ввести заказ, изменить заказ, удалить заказ).
5. Продавец сообщает системе свой выбор.
6. Согласно выбору продавца выполняется один из подчинённых потоков (ввести, изменить или удалить заказ).
7. Система заканчивает сеанс связи с бухгалтерской системой.
8. Бухгалтерская система подтверждает, что сеанс закончен.
Подчинённые потоки:
6.А. Ввести заказ
1. Система запрашивает у продавца данные о заказе.
2. Продавец вводит данные о заказчике и дате поставки заказа.
3. Для каждой позиции нового заказа выполняется:
3.1. Продавец вводит наименование и количество.
3.2. Система принимает данные о введённой позиции заказа.
4. Продавец сообщает системе о необходимости сохранить заказ.
5. Система сохраняет принятые от продавца данные о заказе.
6. Система передаёт данные о новом заказе бухгалтерской системе.
7. Бухгалтерская система принимает данные о новом заказе и отправляет подтверждение об этом в систему.
8. Управление передаётся на шаг 7 основного потока событий
6.Б. Изменить заказ
1. Система выводит список заказов, созданных продавцом.
2. Продавец выбирает заказ из списка.
3. Система выводит все сведения о выбранном заказе.
4. Продавец изменяет сведения о заказе и сообщает системе о необходимости сохранить заказ.
5. Система сохраняет обновлённые данные о заказе.
6. Система передаёт обновлённые данные о заказе бухгалтерской системе.
7. Бухгалтерская система принимает данные об изменённом заказе и отправляет подтверждение об этом в систему.
8. Управление передаётся на шаг 7 основного потока событий
6.В. Удалить заказ
1. Система выводит список заказов, созданных продавцом.
2. Продавец выбирает заказ из списка.
3. Система выводит все сведения о выбранном заказе и запрашивает подтверждение удаления заказа.
4. Продавец подтверждает удаление заказа.
5. Система удаляет все данные о заказе.
6. Система сообщает бухгалтерской системе об удалении заказа.
7. Бухгалтерская система отправляет в систему подтверждение о том, что сообщение об удалении заказа принято.
8. Управление передаётся на шаг 7 основного потока событий
Альтернативные потоки
3.А. Бухгалтерская система недоступна
1. Система обнаруживает, что невозможно установить связь с бухгалтерской системой.
2. Система выдаёт сообщение об ошибке.
3. Вариант использования завершается неуспешно.
6.А.4.А. Отмена создания заказа
1. Продавец сообщает системе об отмене создания заказа.
2. Система обнуляет принятые данные о новом заказе и его позициях.
3. Управление передаётся на шаг 7 основного потока событий
6.Б.4.А. 6.В.4.А. Отмена действия с заказом
1. Продавец сообщает системе об отмене операции с заказом.
2. Управление передаётся на шаг 7 основного потока событий
Предусловия
Перед началом выполнения данного варианта использования продавец должен войти в систему.
Постусловия
Гарантии успеха: Если вариант использования завершится успешно, то операция с данными о заказе, требуемая продавцом, будет осуществлена, изменения в данных о заказах будут внесены в систему обработки заказов и переданы в бухгалтерскую систему.
Минимальные гарантии: В любом случае система гарантирует, что доступ к данным о заказе предоставляется только тому продавцу, который создал заказ, что операции в данными о заказе производятся только тогда, когда доступна бухгалтерская система, и что при отмене операции с заказом, не изменятся сведения о нём, хранящиеся в системе.

      Для остальных вариантов использования мы составим только краткие описания. В рамках работ по определению требований в ходе одной итерации допускается составлять полные описания лишь для нескольких приоритетных вариантов использования. Менее приоритетные варианты использования описываются кратко. Их полные описания могут быть составлены на последующих итерациях.

      Вариант использования «Обработать заказ»:

Точки расширения
Отмена

Краткое описание
Данный вариант использования позволяет кладовщику отметить ход выполнения одного из заказов, собираемых на складе. Система по запросу кладовщика выводит список собираемых заказов. Кладовщик выбирает заказ. Система выводит сведения о выбранном заказе. Кладовщик может отметить позицию заказа как выполненную, либо удалить позицию из заказа. Система отмечает выполненным заказ, если в нём выполнены все позиции.

      Вариант использования «Отменить заказ»:

Краткое описание
Данный вариант использования позволяет кладовщику отменить заказ, собираемый на складе, если заказанных позиций нет в наличии. Выполнение варианта использования начинается в точке расширения «Отмена» расширяемого варианта использования «Обработать заказ». Кладовщик сообщает системе, что заказ следует отменить. Система помечает заказ как отменённый и сохраняет сведения об этом.

      Вариант использования «CRUD данных об остатках»:

Краткое описание
Данный вариант использования позволяет заведующему складом ввести данные о новой описи остатков на складе, изменить данные из ранее введённой описи или удалить данные об описи остатков. Сведения об описи включают в себя дату проведения описи и перечень позиций в описи. В каждой позиции описи указан каталожный номер предмета мебели, количество штук в наличии на складе, номер места хранения. Заведующий складом может пометить введённую опись как текущую. Система будет использовать сведения из неё для расчёта текущих остатков.

Упражнение 3.4. Построение диаграмм деятельности в модели вариантов использования


      Все потоки событий одного варианта использования, взаимосвязанные сценарии двух и более вариантов использования или отдельный поток событий могут быть смоделированы на диаграммах деятельности. Построим диаграмму деятельности для варианта использования «Войти в систему».

      1. В браузере вызываем контекстное меню варианта использования «Войти в систему» и выбираем Subdiagrams -> New diagram. В открывшемся окне указываем тип создаваемой диаграммы: Activity diagram.

      2. На появившейся в редакторе диаграмме создаём два раздела (Vertical Swimlane) -- Пользователь, Система регистрации на курсы -- каждый из которых обозначает область ответственности. Связываем каждый раздел с элементом модели, который он представляет, в окне спецификации на вкладке General в поле Represents (первый -- с актором Пользователь, второй с системой). Деятельности, соответствующие узлам, которые будут расположены в области ответственности пользователя, будут выполняться пользователем, остальные -- системой. Входной узел (Initial Node) помещаем в раздел Пользователь. Заметим, что если бы с вариантом использования были бы связаны два действующих лица, на диаграмме следовало бы создать три раздела (два для действующих лиц и один для системы).

      3. Согласно описаниям потоков событий варианта использования создаём узлы действий (Action): Запустить приложение, Запросить логин и пароль; Ввести логин и пароль; Проверить логин и пароль; Сообщить об ошибке; Выбрать действие, Вывести меню. Узлы действий размещаем по разделам в соответствии с тем, кто выполняет действия.

      4. Добавляем узлы логического ветвления (Decision Node). Соединяем узлы рёбрами потоков управления (Control Flow). Задать нетривиальные сторожевые условия можно, открыв спецификацию потока, на вкладке General в поле Guard. Не следует указывать сторожевые условия в названиях потоков управления.

      5. Добавляем два узла завершения деятельности (Activity Final Node) с именами, указывающими на успешное и безуспешное завершение варианта использования. Вид получившейся диаграммы представлен на рис. 3.4.1.

Рис. 3.4.1. Начальная версия диаграммы деятельности (красным отмечены ошибочные связи)

Рис. 3.4.1. Начальная версия диаграммы деятельности (красным отмечены ошибочные связи)

      Диаграмма деятельности задаёт потоки передачи управления между узлами. Изначально курсор управления порождается во входном узле. Оттуда он передаётся по ребру на вход узла действия (Запустить приложение). Узел действия ждёт, когда курсоры управления придут на все входящие ребра, после чего запускается действие, а по окончании действия курсоры управления подаются на все исходящие из узла действия ребра. Очевидно, наша диаграмма содержит ошибку. В узел действия (Запросить логин и пароль) по второму ребру курсор управления придёт не раньше, чем узел действия выдаст его на выходящий из него поток управления. Тупик. Чтобы исправить ошибку, добавим узел логического объединения (Merge Node) так, чтобы в узел действия входило одно ребро (и чтобы для запуска действия требовался один входящий курсор). Узел логического объединения принимает курсор с любого входящего ребра и сразу передаёт его на исходящее ребро, которое у него одно. Дополнительно укажем действующих лиц, которых представляют собой разделы диаграммы. Для этого выберите раздел на диаграмме и откройте его спецификацию. Во вкладке General заполните поле Represents. Исправленная диаграмма показана на рисунке 3.4.2.

Рис. 3.4.2 Исправленная диаграмма деятельности

Рис. 3.4.2. Исправленная диаграмма деятельности

      Когда курсор попадает в узел логического ветвления, проверяются сторожевые условия на исходящих рёбрах этого узла. Исходящих рёбер может быть два и более. По одному из рёбер, на котором сторожевое условие истинно, курсор управления передаётся дальше. Если таких рёбер (с истинными сторожевыми условиями) несколько, то произвольным образом выбирается одно. Если все сторожевые условия ложны, то курсор не может быть передан дальше. Поток управления заблокирован, а диаграмма нарушает правила стандарта языка. Во избежание ошибок следует внимательно формулировать сторожевые условия. Рекомендуется делать их взаимоисключающими и покрывающими все возможные случаи. Часто используется условие [else], способствующее выполнению этих требований.

      При попадании курсора управления в (любой) узел завершения деятельности вся деятельность прекращается. Уничтожаются все курсоры управления на всех рёбрах диаграммы. В случаях, когда требуется остановить один поток, оставив другие активными, применяется узел завершения потока (Flow Final Node), изображаемый кружком с крестиком.

      Самостоятельно постройте диаграмму для варианта использования «CRUD данных о заказах». Обратите внимание, что подчинённый поток может быть представлен на диаграмме в виде одного узла (см. узлы «Ввести заказ», «Изменить заказ», «Удалить заказ»). Тип этих узлов -- Call Behavior Action (узел вызова деятельности). С каждым из них связана деятельность, которая может быть промоделирована отдельной диаграммой деятельности. При создании диаграммы следует сначала создать внутри варианта использования три деятельности (Activity): Ввести заказ, Изменить заказ, Удалить заказ. Затем разместите на диаграмме деятельности три узла действия (Action). В окне спецификации каждого созданного узла на вкладке General в поле Type укажите тип узла: Call Behaviour Action, после чего нажмите на кнопку с многоточием. В открывшемся окне следует выбрать подходящую деятельность. Обратите внимание, что если деятельности созданы в корне проекта, то следует перетащить их внутрь варианта использования «CRUD данных о заказах» в браузере модели.


      Может оказаться, что какая-то диаграмма создана Вами в корне проекта, а не внутри элемента проекта. Перетащить диаграмму в нужное место Model Explorer не даёт. Тем не менее, переместить диаграмму из корня можно. Откройте спецификацию диаграммы. На закладке General второе сверху поле Parent model: <No parent model>. Нажмите "..." и укажите нужный элемент проекта как родительскую модель для диаграммы.

Рис. 3.4.3. Диаграмма деятельности варианта использования «CRUD данных о заказах»

Рис. 3.4.3. Диаграмма деятельности варианта использования «CRUD данных о заказах»

      Моделирование требований следовало бы продолжить дальше, описав все варианты использования и построив для них диаграммы деятельности. Однако, не имеет смысла сразу описывать все требования. Работа осуществляется последовательными итерациями, в ходе которых составляются описания отдельных вариантов использования в порядке их важности. Когда описания важных вариантов использования составлены, выполняются работы по анализу и проектированию частей системы, реализующих их. Use case писатели приступают к работе над менее приоритетными вариантами использования во время последующих итераций, или занимаются ими на той же итерации, если они мало загружены во время анализа и проектирования. Следует быть готовыми к пересмотру требований в ходе проекта. Изменчивость требований обусловлена тем, что заказчики и будущие пользователи системы не могут сразу точно указать свои пожелания, и тем, что по ходу проекта разработчики лучше узнают предметную область и контекст системы. Из-за изменения требований переделываются описания вариантом использования, исправляются диаграммы деятельности.

      Прежде чем перейти к анализу, сравним две построенные диаграммы. На первой смоделирован цикл, а на второй цикла нет. Из-за цикла первая диаграмма содержит излишнюю сложность. Можно было бы описать вариант использования «Войти в систему» и построить для него диаграмму деятельности без цикла. Так, при неверной комбинации логина и пароля вариант использования мог быть сразу завершён неуспешно. Для учебной модели это допустимо. Заметим, что излишняя сложность дала повод к совершению ошибки (см. рис. 3.4.1) и последующему исправлению её (см. рис. 3.4.2). Выполняя индивидуальные задания, не зацикливайте варианты использования без необходимости. Более простая модель легче строится и в ней, обычно, меньше ошибок.

4. Анализ системы


      При анализе системы производится трансформация требований в системный проект, создание эскизной архитектуры, соответствующей функциональным требованиям. Эскизная архитектура включает в себя набор ключевых абстракций, набор классов анализа, перечень механизмов анализа, иерархию уровней системы, реализации вариантов использования. В ходе жизненного цикла эскизная архитектура подлежит уточнению, на её основе создаётся проектная архитектура, учитывающая нефункциональные требования и подлежащая реализации в коде. Анализ нацелен на прояснение проблемы, решаемой в проекте, построение её решения, простого насколько это возможно, но удовлетворяющего функциональным требованиям.

      Анализ разбивается на несколько итераций, в ходе которых выполняется анализ части вариантов использования. Работа ведётся в соответствии с приоритетом вариантов использования, самые важные анализируются в первую очередь. Результаты каждой итерации интегрируются в общую модель. При анализе последовательно выполняются два вида работ: архитектурный анализ и анализ вариантов использования. Исполнителями процесса анализа являются архитектор, разработчик. Обязанности архитектора состоят в координации и руководстве процессом, определении структуры каждого архитектурного представления, осуществлении архитектурного анализа. Обязанности разработчика включают анализ вариантов использования, определение обязанностей, поведения, свойств классов и связей между классами.

      Архитектурный анализ выполняется архитектором и включает в себя следующие технологические операции:

  1. Утверждение общих соглашений моделирования и документирования системы.

  2. Формирование набора ключевых абстракций предметной области.

      Соглашения моделирования фиксируются в документе «Руководящие указания по проектированию» (Design Guidelines). Они определяют: перечень используемых диаграмм и элементов модели; правила применения диаграмм; соглашения по именованию элементов модели; организацию модели (пакеты).

      Будем придерживаться следующих соглашений:

  1. Используются английские имена (поскольку на основе моделей могут быть получены заготовки кода, которые при использовании русских имён будут бесполезны).

  2. Имена классов (и типов данных) должны быть существительными, соответствующими, по возможности, понятиям предметной области.

  3. Имена классов (и типов данных) должны начинаться с заглавной буквы.

  4. Имена атрибутов и операций должны начинаться со строчной буквы.

  5. Составные имена должны быть сплошными, без подчёркиваний, каждое слово в составе сложного имени, кроме, быть может, первого, должно начинаться с заглавной буквы.

  6. Модель анализа (Analysis Model) представляет собой пакет внутри логического архитектурного представления (Logical View). Внутри модели анализа помещается пакет Use Case Realizations, содержащий в себе все реализации вариантов использования. Также внутри модели создаётся диаграмма классов -- ключевых абстракций -- Key Abstractions.

  7. Для каждого варианта использования должна быть создана кооперация (Collaboration), внутри которой будут размещены элементы модели, относящиеся к реализации варианта использования. Каждая такая кооперация содержит диаграммы взаимодействия, описывающие потоки событий варианта использования (базовый, альтернативные и подчинённые потоки). Также кооперация содержит диаграмму классов VOPC (View Of Participating Classes), изображающую классы, экземпляры которых участвуют в реализации этого варианта использования.

Упражнение 4.1. Создание структуры модели в соответствии с соглашениями моделирования


Рис. 4.1.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 создадим диаграмму составной структуры (Composite Structure Diagram), на которой покажем связи между вариантами использования и их реализациями. Перетащим кооперации и варианты использования из браузера модели на диаграмму. Проведём от коопераций связи реализации (Realization, этот тип связи можно найти в палитре, если открыть выпадающий список у связи Generalization) к тем вариантам использования, которые они реализуют. Важно, чтобы стрелки у связей показывали от коопераций в сторону реализуемых вариантов использования. Получившаяся диаграмма примет вид, показанный на рис. 4.1.2.

Рис. 4.1.2 Диаграмма Use Case Realizations

Рис. 4.1.2. Диаграмма Use Case Realizations

      3. Внутри каждой кооперации, являющейся реализацией варианта использования, создадим диаграмму последовательности BasicFlow (LoginBasicFlow, CRUDOrdersBasicFlow) и диаграмму классов VOPC (LoginVOPC, CRUDOrdersVOPC). Воспользуйтесь контекстным меню кооперации -> Sub Diagrams -> New Diagram. Диаграммы BasicFlow служат для моделирования реализации основных сценариев. VOPC это сокращение View Of Participating Classes. Назначение диаграмм VOPC -- отображение классов, экземпляры которых участвуют в реализации варианта использования, и связей между этими классами.

      4. Если в заготовке проекта нет диаграммы классов Key Abstractions в корне пакета Analysis Model, то создадим её. Контекстное меню пакета Analysis Model-> Sub Diagrams -> New Diagram -> Class Diagram. Дополнительно в кооперацию CRUDOrders добавьте три диаграммы последовательности, моделирующие подчинённые потоки: CreateOrderSubflow, UpdateOrderSubflow, DeleteOrderSubflow.

      Структура модели в браузере должна соответствовать рис. 4.1.1.

      5. В модели Analysis Model присутствует диаграмма классов Key Abstractions. На ней будут представлены классы, представляющие собой основные абстракции предметной области. Каждый из них является абстрактным типом данных, имеющим отношение к предметной области -- к обработке заказов мебельного магазина. Откроем диаграмму ключевых абстракций двойным щелчком в Model Explorer.

      Ключевые абстракции -- основные понятия предметной области -- архитектор выделяет, анализируя требования и пользуясь, глоссарием и моделью бизнес-анализа, если таковая была создана. Каждый термин из глоссария является кандидатом для того, чтобы быть трансформированным в класс ключевой абстракции (или в несколько классов, если структура данных, связанная с ним, слишком сложна для представления одним классом). Некоторые термины могут быть источником для атрибутов классов. В системе обработки заказов можно выделить следующие ключевые абстракции: Order (данные о заказе), OrderItem (данные о позиции заказа), ArticleOfFurniture (данные о предмете мебели), Client (данные о заказчике), User (учётная запись пользователя системы), Inventory (инвентаризационная опись), InventoryItem (позиция описи с данными об остатке мебели на складе). Ассоциации между абстракциями показывают типы соединений между экземплярами ключевых абстракций. Мощности у полюсов указывают ограничения на количество соединений у одного экземпляра. Ассоциация может быть рефлексивной, т. е. соединяющей класс с ним самим. Такая связь описывает соединения между разными экземплярами одного класса. Чтобы различать роли объектов, участвующих в таких соединениях, полюсам рефлексивных ассоциаций обязательно дают имена. Также поступают при наличии двух ассоциаций между одной парой классов. Иногда имена полюсов указывают, чтобы пояснить назначение конкретной ассоциации. На диаграмме классов помимо ассоциаций могут присутствовать и другие связи. Так, связь между классом User и перечислимым типом TypeOfUser, указывает, что описание класса зависит от описания типа (так как атрибут type имеет тип TypeOfUser).

Рис. 4.1.3 Диаграмма ключевых абстракций

Рис. 4.1.3. Диаграмма ключевых абстракций

      Предварительно настроим среду для более удобной работы. Меню 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 может потребоваться дополнительно на каждой диаграмме классов. Вызовите контекстное меню на поле диаграммы классов, нужный флажок спрятан в Presentation Options. Также в Presentation Options диаграммы Key Abstractions найдите и установите флажок Attribute Display Options -> Show Property Modifiers.

      1. Откроем диаграмму Key Abstractions. Выберем в палитре инструмент Class. Добавим классы Order, OrderItem, ArticleOfFurniture, Client, User, Inventory, InventoryItem.

      2. Добавим перечислимые типы (Enumeration) TypeOfUser (Тип пользователя) и StatusOfOrder (Статус заказа). Внутри них расположим значения перечислимого типа (enumeration literal): SALESMAN, WAREHOUSEMAN, STOCKMAN; INPROCESS, CANCELLED, FILLED, DELIVERED, ARCHIVED.

      3. Выберем в палитре инструмент Association. Проведём ассоциации между классами. Укажем мощности у полюсов -- концов ассоциаций (контекстное меню полюса Multiplicity). Укажем, что связь между заказом и позицией заказа -- композиция (контекстное меню полюса, Association Kind -> Composited).

      4. Добавим атрибуты (Attribute) классов: классу Order -- number:long, creation:Date, delivery:Date, filling:Date, status:StatusOfOrder; классу OrderItem -- quantity:byte, number:byte, filled:boolean; классу ArticleOfFurniture -- code: string, description:string, isDiscontinued:boolean, balance:int; классу Client -- name:string, address:string[3], phones:string[*]; классу User -- login:string, passwordHash: long[2]; type:TypeOfUser; классу Inventory -- number:long, date:Date, approved:boolean; классу InventoryItem -- quantity:int.

      5. Проведём зависимости (Dependency) от класса User к перечислимому типу TypeOfUser; от класса Order к перечислимому типу StateOfOrder.

      6. Добавим всем классам -- ключевым абстракциям -- стереотип «entity». Эта пометка означает, что каждый экземпляр класса-сущности имеет явно выраженную индивидуальность, и что обязанностью класса будет хранение данных об объектах предметной области. Для добавления стереотипа выделим нужный класс в браузере, вызовем контекстное меню, Stereotypes -> Edit Stereotypes... -> entity.

      7. Пометим, что класс InventoryItem является классом ассоциации (инструмент палитры Association Class). В итоге диаграмма должна соответствовать рисунку 4.1.3.

      Мы не описали операции, не уточнили направления всех ассоциаций. Дело в том, что нет необходимости сразу указывать все детали ключевых абстракций. Можно даже не указывать типы некоторых атрибутов. Важно определить начальный набор классов, установить между ними связи, вытекающие из свойств предметной области, указать основные данные, хранимые в объектах. В ходе проекта возможности уточнить набор ключевых абстракций ещё представятся.

      Мы готовы перейти к выполнению анализа вариантов использования. В технологии Unified Process он выполняется разработчиками и включает в себя следующие технологические операции:

  1. Идентификацию классов, экземпляры которых участвуют в реализациях потоков событий (так называемых, классов анализа).

  2. Определение обязанностей классов анализа, уточнение их атрибутов и связей.

  3. Унификацию классов анализа, в ходе которой делается попытка упростить модель, исключая лишние классы, объединяя классы с общими обязанностями в один.

      Классы анализа отражают функциональные требования к системе и моделируют типы объектов. Совокупность классов анализа представляет собой начальную концептуальную модель системы. Эта модель проста и позволяет сосредоточиться на реализации функциональных требований, не отвлекаясь на детали реализации, обеспечение эффективности и надёжности. Для решения этих вопросов впоследствии модель анализа будет трансформирована в проектную модель. В ходе анализа вариантов использования в их потоках событий выявляются классы трёх типов:

  • граничные классы (boundary classes), являющиеся посредниками при взаимодействии системы с действующими лицами и с аппаратной базой;

  • классы-сущности (entity classes), отвечающие за хранение данных;

  • управляющие классы (control classes), реализующие бизнес-логику и обеспечивающие координацию поведения объектов в системе.

      Правило выделения граничных классов: для каждой связи между действующим лицом и вариантом использования создаётся или назначается граничный класс, отвечающий за данное взаимодействие. Правило выделения классов-сущностей: классы-сущности -- это, обычно, классы, представляющие ключевые абстракции системы. Правило выделения управляющих классов: для каждого варианта использования создаётся ответственный за его реализацию класс управления.

      Выполним анализ варианта использования CRUD данных о заказах.

Упражнение 4.2. Анализ варианта использования «CRUD данных о заказах»


      Идентифицируем классы анализа. Согласно диаграмме вариантов использования имеются два действующих лица (Продавец и Бухгалтерская система), связанных с нашим вариантом использования. Создадим в пакете Analysis Model граничные классы: MainMenuForm -- форму главного меню, OrderForm -- форму заказа, AccSystemAccess -- класс-посредник, реализующий протокол взаимодействия с Бухгалтерской системой. Первые два класса обеспечат взаимодействие системы с действующим лицом Продавец в рамках нашего варианта использования. В браузере вызовем контекстное меню пакета Analysis Model, Model Element -> Class. Создадим управляющие классы OrderController, отвечающий за реализацию бизнес-логики, и TransactionManager, отвечающий за передачу запросов к базе данных (действия аналогичны). Из описания варианта использования следует, что в потоках событий будут задействованы экземпляры классов User, Order, OrderItem, ArticleOfFurniture, Client. Без данных, которые хранятся в экземплярах этих классов, потоки событий не могут быть реализованы. Открываем в редакторе диаграмму классов CRUDOrdersVOPC. Перетаскиваем на неё вышеупомянутые классы из браузера.

      Назначим классам стереотипы. Выделите в браузере класс OrderController. С помощью контекстного меню добавьте стереотип «control». Повторите то же самое с управляющим классом TransactionManager. Аналогично добавьте стереотип «boundary» граничным классам MainMenuForm, OrderForm, AccSystemAccess. Классам-сущностям User, Order, OrderItem, ArticleOfFurniture, Client назначьте стереотип «entity», если не сделали этого ранее.

      Вид диаграммы, которая должна получиться, изображён на рис. 4.2.1.. Скриншот диаграммы сделан с отключённым выводом членов классов (атрибутов и операций). Выполняя моделирование Вы можете не отключать их вывод, так как при дальнейшей работе они на диаграмме понадобятся.

Рис. 4.2.1 Начальная версия диаграммы CRUDOrdersVOPC. Работа над диаграммой не завершена!

Рис. 4.2.1. Начальная версия диаграммы CRUDOrdersVOPC. Работа над диаграммой не завершена!

      Распределение поведения, предусматриваемого вариантом использования, между классами анализа реализуется при построении диаграмм взаимодействия. На основе описания варианта использования для каждого потока событий (основного, альтернативных, подчинённых) строится отдельная диаграмма взаимодействия -- диаграмма последовательности, или диаграмма коммуникации, или обе. Перейдём к моделированию потоков событий с помощью диаграмм последовательности.

      Откроем диаграмму последовательности CRUDOrdersBasicFlow. Добавим на диаграмму 5 линий жизни (Lifeline). Ими будут являться взаимодействующие объекты: s : Продавец -- экземпляр действующего лица; m : MainMenuForm -- экземпляр граничного класса; oc : OrderController -- экземпляр управляющего класса; asys : AccSystemAccess -- экземпляр граничного класса; a : Бухгалтерская система -- экземпляр действующего лица. Заметьте, что линии жизни объектов граничных классов следует располагать рядом линиями жизни, представляющими действующих лиц, за общение с которыми они отвечают. Линия жизни экземпляра класса-контроллера расположена в середине диаграммы.

      Выберем на палитре синхронное сообщение (Call Message) и проведём его от линии жизни s : Продавец к линии жизни m : MainMenuForm. Дадим имя сообщению crudOrders. Вызовем контекстное меню сообщения и выберем в нём Select Operation -> Create Operation. Дадим имя операции crudOrders. Также поступим, добавляя второе синхронное сообщение с тем же именем, которым форма извещает контроллер о выборе продавца (также создаём одноимённую операцию). Экземпляр контроллера запрашивает соединение с бухгалтерской системой у экземпляра граничного класса. Он, в свою очередь пересылает запрос от контроллера экземпляру действующего лица. Каждое сообщение к экземпляру класса должно быть связано с операцией данного класса. Сообщения, получаемые экземплярами действующих лиц связывать с операциями не следует. На диаграмме классов CRUDOrdersVOPC можно видеть, что в классе MainMenuForm появилась операция crudOrders. Также можно видеть операцию crudOrders в классе-контроллере и startSession в AccSystemAccess.

Рис. 4.2.2. Начальный вид диаграммы последовательности CRUDOrdersBasicFlow. Работа над диаграммой не завершена!

Рис. 4.2.2. Начальный вид диаграммы последовательности CRUDOrdersBasicFlow. Работа над диаграммой не завершена!

      Далее есть два варианта развития событий. Либо удаётся связаться с бухгалтерской системой и всё идёт своим чередом, либо экземпляр формы MainMenuForm выводит сообщение об ошибке, посылая самому себе сообщение displayError. Добавим на диаграмму альтернативный комбинированный фрагмент взаимодействия (Alt. Combined Fragment). Откроем контекстное меню комбинированного фрагмента и выберем Operand -> Manage Operands. В открывшемся окне в поле Guard укажем сторожевые условия операндов: oc.crudOrders() == TRUE -- верхнему операнду, else -- нижнему. Для моделирования вариантов продолжения потока событий создадим внутри верхнего операнда взаимодействия вложенный альтернативный комбинированный фрагмент. Добавим к созданному фрагменту третий операнд взаимодействия (контекстное меню Operand -> Add Operand). Добавим операндам сторожевые условия (см. диаграмму 4.2.3). Внутри каждого их трёх операндов комбинированного фрагмента будет происходить одно из взаимодействий, соответствующих трём подчинённым потокам варианта использования. Чтобы не загромождать диаграмму основного потока для каждого подчинённого потока создаётся отдельная диаграмма. На основной диаграмме будут размещены лишь ссылки на используемые взаимодействия. Вернёмся к диаграмме последовательности CRUDOrdersBasicFlow. В созданный нами последним комбинированный фрагмент взаимодействия с тремя операндами добавим указанные на диаграмме сообщения, а также элементы Interaction Use. С помощью контекстного меню каждого Interaction Use укажем на какое взаимодействие он ссылается (Refers to). В нижней части верхнего операнда обрамляющего фрагмента взаимодействия нарисуем сообщения от объекта-контроллера к экземпляру граничного класса и далее к экземпляру действующего лица Бухгалтерская система. Поместим в нижнем операнде взаимодействия на линию жизни m : MainMenuForm рефлексивное сообщение (Self Message) для вывода предупреждения об ошибке. Диаграмма примет вид, схожий с рисунком 4.2.3. Не забудьте создать операции closeSession() и displayError() и связать их с сообщениями. Для disconnect создавать операцию не следует, достаточно только указать имя сообщения.

Рис. 4.2.3. Окончательный вид диаграммы CRUDOrdersBasicFlow

Рис. 4.2.3. Окончательный вид диаграммы последовательности CRUDOrdersBasicFlow

      Чтобы у взаимодействующих экзепляров классов была возможность обмениваться сообщениями, проведём на диаграмме классов CRUDOrdersVOPC две ассоциации: от MainMenuForm к OrderController и от OrderController к AccSystemAccess. Так как сообщения-вызовы идут в одну сторону, то можно указать направление навигации. Диаграмма CRUDOrdersVOPC примет вид как на рис. 4.2.4.. Скриншот диаграммы сделан со включённым выводом операций классов, но с отключённым выводом атрибутов классов.

Рис. 4.2.4. Промежуточный вид диаграммы CRUDOrdersVOPC

Рис. 4.2.4. Промежуточный вид диаграммы CRUDOrdersVOPC. Работа над диаграммой не завершена!

      Смоделируем один из подчинённых потоков CreateOrderSubflow. Вид диаграммы последовательности, которая должна получиться, показан на рисунке 4.2.5.

      Создание заказа моделируется на диаграмме последовательности созданной внутри взаимодействия CreateOrder. Продавец посылает дату поставки и сведения о заказчике в форму of : OrderForm. Форма, получив эти данные, передаёт запрос о создании заказа OrderController'у. Тот с помощью менеджера транзакций TransactionManager либо получает из базы данных сведения о ранее созданном заказчике, либо добавляет в базу данных запись со сведениями о новом заказчике. Затем создаётся экземпляр класса Order и добавляется в список заказов, заведённых текущим пользователем. Далее в цикле для каждой позиции заказа Продавец вводит данные. Данные из формы попадают к контроллеру. Он проверяет, что предмет мебели из введённой позиции заказа есть в базе данных через менеджера транзакций. Если проверка успешна, контроллер запрашивает у Order добавление новой позиции. Логично возложить эту обязанность на сам заказ, чтобы оградить контроллер от лишних знаний о внутреннем устройстве заказа. Как заказ работает с собственными позициями -- это его личное дело. Если данные от Продавца ошибочны, данные о такой позиции заказа в системе не сохраняются.

      Далее продавец нажимает кнопку Сохранить заказ в форме. Форма передаёт сообщение об этом контроллеру. Контроллер передаёт менеджеру транзакций запрос на сохранение заказа в базе данных. Далее контроллер сообщает экземпляру AccSystemAccess о том, что следует передать сведения о новом заказе в бухгалтерскую систему. Тот, в свою очередь, передаёт данные в бухгалтерскую систему.

      На диаграмме использованы комбинированные фрагменты с оператором opt (Optional), представляющие ветвления с единственной содержательной альтернативой, а также комбинированный фрагмент с оператором loop, описывающий цикл, и элемент Interaction Use. Создавая цикл, следует задать в сторожевых условиях ограничения на количество итераций. Обратите внимание, что на рис. 4.2.5 есть сообщения new, которые имеют тип Creation Message. Не забудьте для всех сообщений-вызовов добавить соответствующие операции в классы и связать их вызовы с сообщениями. Действующему лицу создавать операции не следует. Операции-конструкторы вроде new в аналитической модели можно не заводить.

Рис. 4.2.5 CreateOrderSubflow

Рис. 4.2.5. Диаграмма CreateOrderSubflow

      Каждое сообщение на диаграмме последовательности назначает экземплярам классов обязанности по отправке или приёму и обработке сообщений. Для приёма сообщения в классе объекта-приёмника должна быть одноимённая операция. Для отправки сообщения между экземплярами классов должно быть соединение. Возможность соединения проще всего обеспечить, проведя ассоциацию между классами, экземпляры которых обмениваются сообщениями. На диаграмме 4.2.5 форма OrderForm отправляет сообщение newOrderData() контроллеру OrderController. Значит, в классе OrderController должна быть одноимённая операция, которая обрабатывает сообщение от формы OrderForm, а между классом-формой и классом-контроллером должна быть ассоциация. Нарисуем ассоциацию на диаграмме CRUDOrdersVOPC. Мощности полюсов этой ассоциации указывать не будем, уточним их позже при проектировании. По схожим причинам проведём ассоциации: от OrderController к TransactionManager; от OrderController к User; от OrderController к Order; от TransactionManager к Client; от TransactionManager к ArticleOfFurniture. Вид обновлённой диаграммы приведён на 4.2.6..

      Обратите внимание, что на диаграмме отражены новые операции, сообщениями-вызовами которых обмениваются экземпляры классов в ходе взаимодействия. Проверьте, что для каждого сообщения, принимаемого экземпляром любого класса (но не действующего лица), существует связанная операция. Не следует лишь давать имя сообщению-вызову, направленному экземпляру класса системы, необходимо создать вызываемую операцию и связать её с сообщением. Пропускать создание операций можно лишь у действующих лиц.

Рис. 4.2.6 Вид обновлённой диаграммы CRUDOrdersVOPC

Рис. 4.2.6. Вид обновлённой диаграммы CRUDOrdersVOPC после моделирования подпотока CreateOrderSubflow

      Моделировать потоки событий в реализациях вариантов использования можно не только с помощью диаграмм последовательности. Также для этой цели применяют коммуникационные диаграммы (communication diagram). Об этих диаграммах рассказывается на лекции. При выполнении упражнений мы создавать такие диаграммы не будем.

      Если у Вас 1й вариант, то составьте диаграмму последовательности DeleteOrderSubflow и диаграмму последовательности Order2StringSubflow. Вид диаграмм последовательности, которые должны получиться приведён на рис. 4.2.7, 4.2.8.. Выполняющим 1й вариант также следует пополнить набор ассоциаций на диаграмме CRUDOrdersVOPC. Её итоговый вид приведён на рис. 4.2.9.. Линии жизни o[i] : Order следует отметить флажок Multi-object в её спецификации на вкладке General. Остановленные линии жизни (с крестиками на концах) следует пометить как Stopped (контекстное меню -> Model Element Properties -> Stopped). Сообщения с вызовами деструкторов (close, destroy) лучше создавать как Destroy Message и просто давать им имя, не заводя операцию-деструктор в классе явно. На CRUDOrdersVOPC следует поместить новый класс-участник SelectOrderForm и соединить его ассоциацией с контроллером. Следует расширить размеры классов, чтобы были видны новые добавленные операции, необходимые для моделируемого взаимодействия.



Рис. 4.2.7. Диаграмма последовательности DeleteOrderSubflow

Рис. 4.2.7. Диаграмма последовательности DeleteOrderSubflow

Рис. 4.2.8. Диаграмма последовательности Order2StringSubflow

Рис. 4.2.8. Диаграмма последовательности Order2StringSubflow

Рис. 4.2.9 Итоговый вид диаграммы CRUDOrdersVOPC

Рис. 4.2.9. Итоговый вид диаграммы CRUDOrdersVOPC после моделирования подпотоков DeleteOrderSubflow, Order2StringSubflow

Упражнение 4.3. Анализ варианта использования «Войти в систему»

(только для варианта 2)


      Если у Вас 2й вариант, то проведите анализ варианта использования «Войти в систему». Откроем диаграмму LoginVOPC внутри кооперации Login из пакета Use Case Realizations. Поместим на неё классы User, LoginForm, MainMenuForm, TransactionManager. Классы, пока отсутствующие в модели, лучше не создавать на диаграмме, а создавать в браузере через контекстное меню пакета Analisys Model, так чтобы все классы анализа оказались в корне этого пакета. Если Вы создали классы на диаграмме, то найдите их в браузере (внутри кооперации) и переместите (перетащите) в корень пакета Analisys Model. Назначьте стереотипы: «boundary» -- LoginForm, «control» -- TransactionManager. Удостоверьтесь, что классу User назначен стереотип «entity», а классу MainMenuForm -- «boundary». Начальный вариант диаграммы классов LoginVOPC приведён на рисунке 4.3.1.


Рис. 4.3.1. Начальный вариант диаграммы классов LoginVOPC. Работа над диаграммой не завершена!

Рис. 4.3.1. Начальный вариант диаграммы классов LoginVOPC. Работа над диаграммой не завершена!

      Если у Вас 2й вариант, то анализ варианта использования «Войти в систему» надо продолжить. Откроем диаграмму последовательности LoginBasicFlow. Добавим на диаграмму 5 линий жизни (Lifeline): линию жизни действующего лица Пользователь; lf -- экземпляр формы LoginForm; m -- экземпляр формы MainMenuForm; tm -- экземпляр класса TransactionManager; cu -- экземпляр класса User. Проще всего добавлять линии жизни перенося действующее лицо и классы из браузера на диаграмму. При переносе класса укажем, что добавляется линия жизни. Добавим линиям жизни стереотипы. Заметим, что линию жизни объекта граничного класса следует расположить рядом с линией жизни, представляющей то действующее лицо, за общение с которыми отвечает граничный класс, а линии объектов контроллеров следует расположить в середине диаграммы. В правой части диаграммы располагают линии объектов-сущностей.

      Добавим на диаграмму сообщения и комбинированные фрагменты согласно рисунку 4.3.2. Редактирование осуществите по аналогии с CRUDOrdersBasicFlow. Комбинированные фрагменты с операторами opt и break следует добавлять как элемент палитры Loop Combined Fragment с последующей заменой в спецификации фрагмента оператора на нужный (контекстное меню -> Operator Kind). Удаляющее сообщение LoginForm создадим как рефлексивное (SelfMessage) и укажем его тип (контекстное меню -> Type).


Рис. 4.3.2. Диаграмма последовательности LoginBasicFlow

Рис. 4.3.2. Диаграмма последовательности LoginBasicFlow

      Если у Вас 2й вариант, то анализ варианта использования «Войти в систему» надо продолжить. Откроем диаграмму классов LoginVOPC. Добавим ассоциации, необходимые для того, чтобы взаимодействие, описанное диаграммой последовательности LoginBasicFlow, было осуществимо. Расставим мощности и имена ролей на полюсах ассоциаций. Укажем направления навигации (на противоположном полюсе с помощью контекстного меню укажите Navigable Unspecified). Итоговый вид диаграммы приведён на рисунке 4.3.3.


Рис. 4.3.3. Итоговая версия диаграммы классов LoginVOPC

Рис. 4.2.10. Итоговая версия диаграммы классов LoginVOPC

      Упражнения по анализу закончены. Предполагается, что реализация всех вариантов использования выполняется не за один раз. Часть вариантов использования могут быть реализована не на первой итерации, а на последующих. Мы не будем моделировать остальные потоки событий всех вариантов использования, чтобы не терять время на рутину.

      Созданную модель анализа следует сохранить отдельно. Если при проектировании модель анализа разрушится, можно будет использовать сохранённую отдельно её копию. При сдаче выполненных упражнений полезно иметь с собой два проекта: один, сохранённый на момент окончания анализа; второй, представляющий модель после выполнения всех упражнений. Закройте проект и сделайте копию файла проекта в workspace.

5. Проектирование системы


      Во время анализа мы уделяли внимание реализации функциональных требований, при проектировании учитываются нефункциональные требования. Проект адаптируется к каркасам, библиотекам, языкам, которые будут использованы при реализации. Проектирование возглавляется архитектором. Под его руководством работают разработчики, к которым при необходимости подключают разработчиков БД и систем реального времени.

      Проектирование системы осуществляется итерационно. На каждой итерации ставится цель спроектировать часть системы. Для достижения этой цели друг за другом выполняются два вида работ: проектирование архитектуры системы и проектирование элементов системы. Т. е. сначала определяются крупные части системы и их взаимодействие, а потом детально проектируется внутреннее устройство и поведение частей. При проектировании архитектуры выделяются проектные элементы (классы, интерфейсы, подсистемы), формируется иерархия архитектурных уровней, идентифицируются проектные механизмы, создаётся структура потоков управления, разрабатывается конфигурация системы на вычислительной среде.

Упражнение 5.1. Проектирование архитектуры системы обработки заказов


      Система обработки заказов будет работать с реляционной базой, в которой будут сохраняться данные о заказах, клиентах, продаваемых предметах мебели, остатках и проч., следовательно, при проектировании мы будем использовать RDBMS (relational database management system) -- механизм обеспечения работы с устойчивыми данными (т. е. данными сохраняемыми и после завершения сеанса работы с системой). Система обработки заказов также взаимодействует с внешней программой -- бухгалтерской системой. Значит, мы будем использовать при проектировании RemoteInterchange -- механизм обмена запросами и/или данными с внешней системой . Существуют готовые каркасы, обеспечивающие доступ к реляционным БД. К таким относится JDBC (Java Database Connectivity). Каркас XML-RPC обеспечивает межсистемное взаимодействие. Проектные механизмы уже добавлены в нашу модель (они входят в состав заготовки проекта, с которой мы начали выполнять упражнения). См. пакеты Architectural Mechanisms и Middleware в Logical View внутри Design Model.

      В Design Model создайте два пакета: Application и BusinessServices. На уровень приложения мы будем размещать элементы пользовательского интерфейса. На уровень бизнес-служб -- элементы, специфические для предметной области. Уровень промежуточного ПО -- Middleware -- содержит элементы, обеспечивающие сервисы, независимые от платформы. Назначьте пакетам Application и BusinessServices стереотип «layer» -- архитектурный уровень. В Design Model откройте диаграмму пакетов Main, находящуюся в корне Design Model. Вытащите на неё все три архитектурных уровня и соедините их зависимостями (Dependency), как указано на рис. 5.1.1. Мы создали иерархию уровней системы, т. е. описали устройство системы с точки зрения самых крупных её блоков.

Рис. 5.1.1. Диаграмма пакетов Main

Рис. 5.1.1. Диаграмма пакетов Main

      Следующие наши действия нацелены на трансформацию классов анализа в проектные элементы (классы, интерфейсы и подсистемы) и распределение проектных элементов по уровням системы. Часто при трансформации простые классы анализа преобразуются в проектные классы один в один. Сложный класс анализа может преобразовываться в несколько связанных проектных классов или в подсистему.

      При анализе мы не учли полностью все вопросы, связанные с обеспечением работы с устойчивыми данными. В потоке событий система предпринимала некоторые действия, чтобы введённые данные были доступны не только в текущем сеансе работы, но и в последующих. Для этого отправлялись сообщения менеджеру транзакций, но действия менеджера по обработке этих сообщений не были промоделированы. В этом нет ошибки, во время анализа эти вопросы рассматривать рано, надо сосредоточиться на основных функциях системы. Начиная проектирование, мы обращаемся к этим вопросам и должны смоделировать то, что было пропущено при анализе. Реализация обязанностей, назначенных классу TransactionManager, сложна. Поэтому при отображении в проектные классы мы переводим его в подсистему обеспечения устойчивости DBAccess (сокращённо от DataBase Access). Граничный класс AccSystemAccess, обеспечивающий взаимодействие с бухгалтерской системой, также отображается в подсистему для того, чтобы возможные изменения во взаимодействии с внешней программой мало затрагивали остальные части системы и были локализованы в подсистеме. Остальные классы анализа переведём в проектные один в один.

      Чтобы не испортить модель анализа, скопируем её содержимое внутрь проектной модели. Для этого в браузере выделите пакет Analysis Model, вызовите его контекстное меню и выберите в нём пункт Duplicate Recursively. После этого будет осуществлено дублирование пакета и всех его элементов. Дубль пакета получит имя Analysis Model2. Создайте в пакете Application пакет CRUDOrders. В созданный пакет переместите классы классы MainMenuForm, SelectOrderForm, OrderForm, OrderController из корня Analysis Model2. Для этого воспользуйтесь контекстным меню элемента и пунктом Move... либо перетащите мышью. Создайте диаграмму классов в пакете CRUDOrders. Дайте ей имя -- CRUDOrders. Перетащите на неё все классы пакета. Прежние стереотипы классов («control», «boundary») удалите. Диаграмма примет вид, похожий на рис. 5.1.2.

Рис. 5.1.2. Диаграмма классов CRUDOrders

Рис. 5.1.2. Диаграмма классов CRUDOrders

      В пакете BusinessServices создайте пакет WarehouseArtefacts (т. е. артефакты склада, в нем разместим классы-сущности предметной области, а также перечислимые типы TypeOfUser и StatusOfOrder). Прежние стереотипы классов («entity») удалите. Через контекстное меню откройте спецификацию диаграммы классов Key Abstractions2. Введите её новое имя в поле Diagram name: WarehouseArtefacts. Укажите новую родительскую модель Parent model: пакет WarehouseArtefacts. Примените изменения. В результате этих действий диаграмма вместе со всеми её элементами и связями переместится в пакет WarehouseArtefacts.

Рис. 5.1.3. Диаграмма классов WarehouseArtefacts

Рис. 5.1.3. Диаграмма классов WarehouseArtefacts

      В пакете BusinessServices создайте пакет Interfaces (где будут находиться все интерфейсы). В пакет Interfaces перенесите классы TransactionManager и AccSystemAccess из Analysis Model2. Переименуйте TransactionManager в IDBAccess, AccSystemAccess в IASysAccess и назначьте им стереотипы «Interface». Прежние стереотипы («control», «boundary») удалите. Создайте диаграмму классов Interfaces и разместите на ней интерфейсы IDBAccess, IASysAccess. Диаграмма примет вид, похожий на рис. 5.1.4.

Рис. 5.1.4. Диаграмма классов Interfaces

Рис. 5.1.4. Диаграмма классов Interfaces

      Пакет Use Case Realizations из Analysis Model2 перенесите в Design Model и переименуйте его в Design Use Case Realizations. Пакет Analysis Model2 удалите. В нём, возможно, остались элементы и связи, моделирующие реализацию входа в систему. Мы не будем моделировать проектную реализацию этого варианта использования.

      При реализации подсистемы DBAccess будет задействован механизм RDBMS-JDBC из одноимённого пакета, расположенного в Design Model::Architectural Mechanisms::Persistency. При реализации подсистемы ASysAccess будет задействован механизм XMLRPCInterchange из одноимённого пакета, расположенного в Design Model::Architectural Mechanisms::RemoteInterchange. Чтобы не повредить части модели, описывающие механизмы, скопируйте их в подсистемы. Для этого продублируйте (Duplicate Recursively) пакет RDBMS-JDBC и пакет XMLRPCInterchange, а затем переместите полученные дубли на уровень Business Services и переименуйте их в DBAccess и ASysAccess, соответственно. Назначьте пакетам DBAccess и ASysAccess стереотип «subsystem», уберите стереотип «mechanism», если есть. Стереотипы анализа в проектной модели смысла не имеют, их лучше убрать (снимите флажки в контекстном меню -> Stereotypes). Структура проектной модели в браузере примет вид, похожий на рис. 5.1.5. Убедитесь, что Вы верно распределили элементы модели по пакетам.

Рис. 5.1.5. Структура проектной модели

Рис. 5.1.5. Структура проектной модели

      Переименуйте кооперации и диаграммы внутри пакета Design Model::Design Use Case Realizations, убрав цифру в окончании и добавив приставку Design (см. рис. 5.1.6). Диаграмма составной структуры внутри этого пакета примет вид, представленный на рис. 5.1.6.


Рис. 5.1.6. Диаграмма составной структуры Design Use Case Realizations

Рис. 5.1.6. Диаграмма составной структуры Design Use Case Realizations

      Создайте диаграмму пакетов CRUDOrders Dependencies в пакете CRUDOrders. Разместите на ней пакеты CRUDOrders, Interfaces и WarehouseArtefacts, укажите их зависимости (Dependency). Элементы пакета CRUDOrders используют классы-артефакты и интерфейсы подсистем, отсюда две зависимости. В интерфейсах подсистем содержатся операции, обеспечивающие сохранение в БД, подкачку из БД экземпляров классов из WarehouseArtefacts, а также отправку экземпляров этих классов во внешнюю программу, отсюда третья зависимость. Диаграмма примет вид, представленный на рис. 5.1.7.

Рис. 5.1.7. Связи пакета CRUDOrders на диаграмме пакетов CRUDOrders Dependencies

Рис. 5.1.7. Связи пакета CRUDOrders на диаграмме пакетов CRUDOrders Dependencies

      Создайте диаграмму пакетов BusinessServices Package Diagram в пакете BusinessServices. Разместите на ней пакеты этого архитектурного уровня, укажите их зависимости (Dependency). Подсистема реализует интерфейс, отсюда верхняя зависимость. Для описаний в верхних пакетах понадобятся классы-артефакты, отсюда две другие зависимости. Диаграмма примет вид, представленный на рис. 5.1.8.

Рис. 5.1.8. Структура уровня BusinessServices на диаграмме пакетов BusinessServices Package Diagram

Рис. 5.1.8. Структура уровня BusinessServices на диаграмме пакетов BusinessServices Package Diagram

      Моделирование структуры потоков управления системы в упражнения не включено. Этот вопрос будет рассматриваться только на лекциях. В системе можно выделить следующие процессы: WarehousemanApplication -- процесс, исполняемый на рабочем месте заведующего складом; SalespersonApplication -- процесс, исполняемый на рабочем месте продавца; StockmanApplication -- процесс, исполняемый на рабочем месте кладовщика; DBAccessProcess -- процесс, обеспечивающий доступ к БД системы.

      Промоделируйте конфигурацию вычислительной среды. Она состоит из трёх типов узлов -- сред выполнения (Execution Environment), компонентов-процессов, которые могут быть размещены внутри сред выполнения, и устройств (Device). Связи между узлами -- пути коммуникации -- являются подвидами ассоциации. Откройте диаграмму размещения Main внутри архитектурного представления Deployment View. Создайте на ней узлы и связи между узлами. Компоненты следует создавать, размещая их внутри родительского узла. Окончательный вид диаграммы приведён на рис. 5.1.9. По получившейся диаграмме можно судить, что в вычислительной среде могут быть узлы разных типов: сервер магазина, рабочие станции трёх видов -- наследники абстрактного рабочего места. Различные виды рабочих станций созданы для того, чтобы предоставлять разным типам пользователей разные функциональные возможности. Лишний функционал не будет включаться в сборку компоненты, устанавливаемой на рабочее место. Также на диаграмме указан тип узла, относящийся к внешнему окружению системы -- сервер бухгалтерской системы, подключённый к рабочим станциям. Коммуникации осуществляются через локальную сеть мебельного магазина. СУБД развёрнута на сервере магазина. К каждой рабочей станции подключён принтер по USB интерфейсу. Каждая рабочая станция подключена к единственному серверу магазина. Диаграмма задаёт перечень типов узлов и возможные конфигурации, составленные из узлов разных типов. Если есть необходимость, то рисуют диаграмму с конкретными узлами (не с типами) для того, чтобы, например, пояснить количество серверов магазина в системе. Те же сведения можно дать в примечании на диаграмме размещения с типами узлов.

Рис. 5.1.9. Диаграмма размещения

Рис. 5.1.9. Диаграмма размещения

      На этом проектирование архитектуры завершено, переходим к проектированию элементов системы.

Упражнение 5.2. Проектирование элементов системы обработки заказов


      Проектирование элементов системы включает в себя следующие виды работ: уточнение реализаций вариантов использования; проектирование подсистем; проектирование классов и проектирование баз данных.

      Проектные реализации вариантов использования являются более полными, чем реализации, созданные в ходе анализа. В них вместо экземпляров классов анализа должны присутствовать экземпляры проектных классов, т. е. должны быть учтены трансформации классов анализа в проектные элементы. Проведём уточнение реализаций вариантов использования. Переименуем некоторое содержимое пакета Design Model::Design Use Case Realizations: диаграмму классов LoginVOPC2 в DesignLoginVOPC, диаграмму последовательности LoginBasicFlow2 в DesignLoginBasicFlow, диаграмму классов CRUDOrdersVOPC2 в DesignCRUDOrdersVOPC, диаграмму последовательности CreateOrderSubflow2 в DesignCreateOrderSubflow, диаграмму последовательности DeleteOrderSubflow2 в DesignDeleteOrderSubflow, диаграмму последовательности UpdateOrderSubflow2 в DesignUpdateOrderSubflow, диаграмму последовательности CRUDOrdersBasicFlow2 в DesignCRUDOrdersBasicFlow.

      Откроем диаграмму последовательности DesignCreateOrderSubflow из взаимодействия DesignCRUDOrders в пакете LogicalView::Design Model::Design Use Case Realizations. На диаграмме DesignCreateOrderSubflow следует изменить стереотипы на линиях жизни объектов tm : IDBAccess и asys : IASysAccess. Удалите стереотипы «control» и «boundary», добавьте стереотипы «interface». Тем самым мы показываем, что происходит обращение к экземплярам классов, реализующих интерфейсы подсистем. Какие именно это будут классы -- это для реализации варианта использования неважно. Реализация варианта использования не определяет, как подсистема DBAccess (ASysAccess) должна обрабатывать такие вызовы. Эта часть относится к проектированию подсистем и может варьироваться в зависимости от реализаций подсистем. Внутреннее поведение подсистемы скрыто, чтобы обеспечить возможность лёгкой модификации её реализации. По этой причине следует удалить сообщения идущие от tm : IDBAccess и asys : IASysAccess к другим объектам (это два сообщения создающие объект cln : Client и art : ArticleOfFurniture соответственно). После удаления сообщений положение других сообщений может измениться. Верните их на свои места. Удалите с линий жизни стереотипы анализа. Скройте линии жизни, которым теперь не отправляются сообщения (cl : Client, af : ArticleOfFurniture) чтобы диаграмма DesignCreateOrderSubflow приняла вид, представленный на рисунке 5.2.1. В проектной реализации следует указать более полные сигнатуры вызываемых операций по сравнению с моделью анализа. При уточнении реализаций вариантов использования можно детализировать сигнатуры операций, т. е. добавить их параметры и типы результатов (в браузере раскройте класс, выберите операцию, откройте её спецификацию и введите сведения на вкладках General и Parameters). Но это необязательно, т. к. можно составить полные сигнатуры операций при проектировании классов. Если Вы будете выполнять уточнения сигнатур операций, убедитесь, что работаете с проектными классами, т. е. элементами Design Model. У сообщений new сигнатуры целиком указываются как имена сообщений. Перечислим сигнатуры операций с диаграммы:
OrderForm:newOrderData(clientName:string, delivery:Date)
OrderForm:newItemData(code:string, qty:byte)
OrderForm:saveNewOrder()
OrderController:newOrderData(clientName:string, delivery:Date)
OrderController:newItemData(code:string, qty:byte)
IDBAccess:getClient(clientName:string):Client
IDBAccess:createClient(clientName:string):Client
IDBAccess:getArticle(code:string):ArticleOfFurniture
User:addOrder(o:Order):boolean
Order:newItem(a:ArticleOfFurniture, qty:byte):boolean
User:addOrder(o:Order):boolean
User:addOrder(o:Order):boolean
User:addOrder(o:Order):boolean


Рис. 5.2.1. Уточнённая диаграмма DesignCreateOrderSubflow

Рис. 5.2.1. Уточнённая диаграмма DesignCreateOrderSubflow

      Обычно при проектировании граничные классы, отвечающие за взаимодействие с пользователем, трансформируются не в один класс, а в группу классов GUI, но упражнения по проектированию пользовательского интерфейса в рамках нашего курса не рассматриваются. Другие диаграммы последовательности в проектных реализациях вариантов использования мы уточнять не будет. Работы по проектированию реализаций вариантов использования на этом нами завершены.


Вводные замечания по проектированию подсистем
(общее для всех вариантов)


      Следующей технологической операцией является проектирование подсистем. В рассматриваемой модели в ходе этой операции для 1го варианта следует на основе механизма JDBC спроектировать подсистему DBAccess, а для 2го варианта следует на основе механизма XMLRPCInterchange спроектировать подсистему ASysAccess. При этом механизм выполняет роль шаблона, описывающего либо типовую организацию доступа к устойчивым данным, либо типовую организацию обмена данными с внешней системой с точки зрения структуры и поведения. В шаблоне JDBC своего рода параметрами являются классы PersistentObject, PersistentObjectList и DBClass, а в шаблоне XMLRPCInterchange -- классы ObjectToSend, ObjectToReceive, CustomTypeFactory, CustomParser, CustomSerializer и XMLRPCConnector. Проектирование подсистемы в основном сводится к конкретизации шаблона, в ходе которой класс-параметр (например, PersistentObject в варианте 1) заменяется на конкретный класс из модели (например, на класс Client, сведения об экземплярах которого хранятся в БД, и другие подобные классы из пакета WarehouseArtefacts). Класс-параметр DBClass заменяется на прокси-класс подсистемы DBAccess (в варианте 1). Класс-параметр XMLRPCConnector (в варианте 2) заменяется на прокси-класс подсистемы ASysAccess. Класс-параметр ObjectToSend (в варианте 2) заменяется на класс Order, сведения об экземплярах которого будут пересылаться во внешнюю систему. Классы-параметры CustomTypeFactory, CustomParser, CustomSerializer (в варианте 2) заменяются на классы подсистемы ASysAccess, обеспечивающие передачу экземпляров класса Order во внешнюю систему.


Проектирование подсистемы DBAccess на основе механизма JDBC
(только для варианта 1)


      Если у Вас 1й вариант, то переименуйте класс DBClass внутри пакета DBAccess в DBAccess и назначьте ему стереотип «subsystem proxy» -- тем самым будет указано, что экземпляр этого класса будет принимать все сообщения, идущие внутрь подсистемы DBAccess. Переименуем внутри пакета DBAccess диаграмму классов RDBMS-JDBC2 в DBAccess Class Diagram, а диаграмму пакетов RDBMS-JDBC2 в DBAccess Package Diagram. Класс PersistentObject переименуйте в класс Client и с помощью контекстного меню объедините класс Client из подсистемы DBAccess с одноимённым классом Client из пакета WarehouseArtefacts (Merge to Model Element...). Из класса Client удалите атрибут attribute и переименуйте операции getAttribute в getName, setAttribute в setName. Класс PersistentObjectList переместите в пакет WarehouseArtefacts, переименуйте его в ClientList. Откройте спецификацию класса ClientList. Найдите вкладку Relations. Измените имя у отношения реализации (Realization) на < E->Client >. Тем самым Вы укажете, что элементами этого списка будут экземпляры класса Client. В подсистеме DBAccess переименуйте кооперацию JDBC в IDBAccessRealization. Добавьте ей стереотип «interface realization» и удалите стереотип «mechanism».

      Если у Вас 1й вариант, то откройте диаграмму классов в пакете RDBMS-JDBC. На ней указано, что при реализации доступа к БД используются элементы, описанные в пакетах java.lang и java.sql. Поэтому откройте диаграмму пакетов из пакета BusinessServices, перенесите на неё пакеты lang и sql с уровня Middleware из пакета java. Убедитесь, что проведены зависимости (Dependency или Import) от подсистемы DBAccess к пакетам java.lang и java.sql. Если нет, то добавьте их на диаграмму пакетов. При этом не забудьте, что зависимости проводятся от зависящего пакета к пакетам, от которых он зависит.

      Если у Вас 1й вариант, то внутри кооперации IDBAccessRealization диаграмму последовательности initialize2 переименуйте в init, create2 -- в createClient, read2 -- в getClient, disconnect2 -- в close, update2 -- в createOrder, delete2 -- в deleteOrder. Теперь откройте находящуюся внутри подсистемы DBAccess диаграмму классов DBAccess Class Diagram. Поместите на неё классы Order, Client, User, Article и проведите зависимости от класса DBAccess. Добавьте на диаграмму интерфейс IDBAccess. Проведите связь реализации от класса DBAccess к интерфейсу IDBAccess. Измените сигнатуры операций интерфейса IDBAccess в соответствии с диаграммой 5.2.2: : create в createClient(name:string):Client, read(criteria:string):ClientList в getClient(name:string):Client, update(obj:Client):void в createOrder(o:Order, u:User):void, delete(obj:Client):void в deleteOrder(o:Order):void, initialize в init, disconnect в close. Затем продублируйте все операции интерфейса IDBAccess (контекстное меню -> Duplicate), перенесите их копии в класс DBAccess, уберите лишние "2" из их имён. С диаграммы классов DBAccess скройте класс ClientList и класс ArrayList, но не удаляйте их из модели. Удалите из класса DBAccess все лишние операции. Проведите недостающие зависимости. Добавьте диаграмму последовательности getArticle. Переименуйте диаграмму составной структуры Main2 в IDBAccess Structure. В результате, диаграмма классов и структура подсистемы должны быть похожи на изображённые на рисунках 5.2.2 и 5.2.3. Благодаря использованию механизма мы затратили меньше сил на обдумывание и моделирование, чем если бы делали подсистему с чистого листа. Переходим к моделированию внутреннего поведения подсистемы.


Рис. 5.2.2. Диаграмма классов подсистемы DBAccess

Рис. 5.2.2. Диаграмма классов подсистемы DBAccess

Рис. 5.2.3. Структура подсистемы DBAccess

Рис. 5.2.3. Структура подсистемы DBAccess

      Внутри кооперации IDBAccess находятся восемь диаграмм последовательности: init, close, getUserByLogin, createClient, getClient, createOrder, deleteOrder, getArticle. Каждое взаимодействие будет описывать, что делают объекты подсистемы при вызове соответствующей операции. Реализацию операций getArticle, createOrder, getUserByLogin и deleteOrder мы моделировать не будем, оставшиеся четыре промоделируем.

      На диаграмме последовательности внутри взаимодействия init левая линия жизни должна представлять объект db:DBAccess, входящее сообщение, принимаемое им, должно быть связано с операцией init. Диаграмма примет вид, изображённый на рисунке 5.2.4.

Рис. 5.2.4. Диаграмма последовательности, описывающая реализацию операции init()

Рис. 5.2.4. Диаграмма последовательности, описывающая реализацию операции init()

      Диаграмма close должна иметь вид, изображённый на рисунке 5.2.5.

Рис. 5.2.5. Диаграмма последовательности, описывающая реализацию операции close()

Рис. 5.2.5. Диаграмма последовательности, описывающая реализацию операции close()

      На диаграмме последовательности getClient левая линия жизни должна представлять объект DBAccess, а самая правая -- obj:Client. Вторая справа линия жизни -- объект ClientList должна быть удалена. Свяжите найденное сообщение, принимаемое экземпляром DBAccess, с операцией getClient. Добавьте классу Client новые операции setName(value:string):void, setAddress(value:string[3]):void, setPhones(value:string[*]):void. Проще всего геттеры и сеттеры атрибута добавлять через его контекстное меню. Замените оператор взаимодействия в комбинированном фрагменте с loop на opt. Исправьте сторожевое условие операнда взаимодействия. Добавьте новые сообщения внутрь фрагмента. Диаграмма должна иметь вид, изображённый на рисунке 5.2.6.

Рис. 5.2.6. Диаграмма последовательности, описывающая реализацию операции getClient(name: string): Client

Рис. 5.2.6. Диаграмма последовательности, описывающая реализацию операции getClient(name: string): Client

      На диаграмме последовательности createClient левая линия жизни должна представлять экземпляр DBAccess, самая правая -- объект Client. Свяжите найденное сообщение с операцией createClient. Свяжите четвёртое сверху сообщение с вызовом операции setName. Диаграмма должна иметь вид, изображённый на рисунке 5.2.7.

Рис. 5.2.7. Диаграмма последовательности, описывающая реализацию операции createClient(name: string): Client

Рис. 5.2.7. Диаграмма последовательности, описывающая реализацию операции createClient(name: string): Client

      Проектирование подсистемы DBAccess завершено. Если у Вас 1й вариант, то переходите к проектированию классов.

Проектирование подсистемы BSAccess на основе механизма XMLRPCInterchange
(только для варианта 2)


      Если у Вас 2й вариант, то Вам следует выполнить проектирование подсистемы ASysAccess. Переименуйте класс XMLRPCConnector внутри пакета ASysAccess в ASysAccess и назначьте ему стереотип «subsystem proxy» -- тем самым будет указано, что экземпляр этого класса будет принимать все сообщения, идущие внутрь подсистемы ASysAccess. Классы ObjectToSend и ObjectToRecieve с помощью контекстного меню объедините c классом Order из пакета WarehouseArtefacts (Merge to Model Element...). В подсистеме ASysAccess переименуйте кооперацию XMLRPCInterchange2 в IASysAccessRealization. Добавьте ей стереотип «interface realization» и удалите стереотип «mechanism». Диаграмму классов XMLRPCInterchange2 переименуйте в ASysAccess Class Diagram. Диаграмму пакетов XMLRPCInterchange2 переименуйте в ASysAccess Package Diagram.

      Если у Вас 2й вариант, то откройте диаграмму классов в пакете XMLRPCInterchange внутри архитектурного механизма RemoteInterchange. На диаграмме указано, что при реализации обмена данными с внешней системой используются элементы, описанные в пакетах java.net и org.apache.xmlrpc. Поэтому откройте диаграмму пакетов из пакета Business Services, перенесите на неё пакеты java.net и org.apache.xmlrpc с уровня Middleware. Убедитесь, что проведены зависимости (Dependency или Import) от подсистемы ASysAccess к пакетам java.net и org.apache.xmlrpc. Если нет, то добавьте их на диаграмму пакетов. При этом не забудьте, что зависимости проводятся от зависящего пакета к пакетам, от которых он зависит.

Рис. 5.2.8. Диаграмма пакетов уровня Business Services

Рис. 5.2.8. Диаграмма пакетов уровня Business Services


      Если у Вас 2й вариант, то внутри кооперации IASysAccessRealization диаграмму последовательности init2 переименуйте в init, sendRequest2 -- в sendNewOrder. Теперь откройте находящуюся внутри подсистемы ASysAccess диаграмму классов ASysAccess Class Diagram. Уберите дубль класса Order. Переименуйте классы: CustomTypeFactory в OrderFactory, CustomParser в OrderParser, CustomSerializer в OrderSerializer. Убедитесь, что отображены зависимости OrderParser и OrderSerializer от Order. Если это не так, то через контекстное меню класса, зависимость которого не видна, -> Related Elements -> Visualize Related Model Element... покажите зависимость на диаграмме. Повторно создавать зависимость не следует. Дважды один и тот же класс зависеть от другого не может. Добавьте на диаграмму интерфейс IASysAccess. Для его отображения в виде "леденца" используйте контекстное меню -> Presentation Option -> Interface Ball. Проведите связь реализации от класса ASysAccess к интерфейсу IASysAccess. Переименуйте операции интерфейса IASysAccess в соответствии с диаграммой 5.4.9, продублируйте их (контекстное меню -> Duplicate), копии переместите в класс ASysAccess. Удалите "2" в названиях перемещённых операций. Удалите из класса ASysAccess все лишние операции. Операцию init() удалять не следует, а наоборот, следует продублировать и дубль переместить в интерфейс. Исправьте сигнатуры операций в классах ASysAccess, OrderParser (createOrderToReceive ->createOrder). В результате, диаграмма классов и структура подсистемы должны быть похожи на изображённые на рисунках 5.2.9 и 5.2.10. Благодаря использованию механизма мы затратили меньше сил на обдумывание и моделирование, чем если бы делали подсистему с чистого листа. Переходим к моделированию внутреннего поведения подсистемы ASysAccess.


Рис. 5.2.9. Диаграмма классов подсистемы ASysAccess

Рис. 5.2.9. Диаграмма классов подсистемы ASysAccess Class Diagram


Рис. 5.2.10. Структура подсистемы ASysAccess в браузере модели

Рис. 5.2.10. Структура подсистемы ASysAccess в браузере модели

      Если у Вас 2й вариант, то проектирование подсистемы ASysAccess следует продолжить. Внутри кооперации IASysAccessRealization находятся диаграммы последовательности init, sendNewOrder. Каждое взаимодействие будет описывать, что делают объекты подсистемы при вызове соответствующей операции. Вообще говоря, диаграмма последовательности должна быть создана для каждой операции интерфейса подсистемы. Вы можете создать пустые диаграммы для операций startSession, closeSession, sendDeletedOrder. Их реализацию мы моделировать не будем, а первые две промоделируем (в рамках 2го варианта).

      На диаграмме последовательности init левая линия жизни должна представлять объект cn:ASysAccess, входящее сообщение, принимаемое им, должно быть связано с операцией init. Диаграмма примет вид, изображённый на рисунке 5.2.11. Взаимодействие описывает инициализацию подсистемы перед первым обменом данными с внешней системой.


Рис. 5.2.11. Диаграмма последовательности, описывающая реализацию операции init() в подсистеме ASysAccess

Рис. 5.2.11. Диаграмма последовательности, описывающая реализацию операции init() в подсистеме ASysAccess

      На диаграмме последовательности sendNewOrder левая линия жизни должна представлять cn:ASysAccess, а самая правая -- действующее лицо Бухгалтерская система. Шаблонная диаграмма описывает сложное взаимодействие, при котором не только пересылается объект данных во внешнюю систему, но и в ответ получается объект-результат. Моделируемая нами операция не предусматривает получение объекта извне, а значит, лишние линии жизни следует удалить из модели (из фрейма sendNewOrder): result:Order, cp:OrderParser. Свяжите найденное сообщение, принимаемое экземпляром ASysAccess, с операцией sendNewOrder. Добавьте классу Order новые операции-геттеры getNumber, getDelivery, getCreation, getFilling, getStatus, getOrderItems, getCustomer. Проще это сделать, открыв диаграмму классов WarehouseArtefacts Class Diagram, выбрав атрибут класса Order::number, вызвав его контекстное меню и указав Create Getter and Setter. Удалите примечания с диаграммы последовательности. Добавьте соответствующие сообщения от объекта cs:OrderSerializer к o:Order на диаграмму последовательности. Добавьте loop-фрагмент, описывающий сериализацию позиций заказа. Добавьте линию жизни клиента заказа и сообщение к ней. Добавьте нижнее потерянное сообщение (Lost Message) и укажите его тип -- возврат (контекстное меню -> Type(Reply)). В спецификации сообщения в поле Name укажите, что возвращается. Диаграмма примет вид, изображённый на рисунке 5.2.12.


Рис. 5.2.12. Диаграмма последовательности, описывающая реализацию операции sendNewOrder() в подсистеме ASysAccess

Рис. 5.2.12. Диаграмма последовательности, описывающая реализацию операции sendNewOrder() в подсистеме ASysAccess

      Проектирование подсистемы ASysAccess будем считать завершённым. Моделировать взаимодействие внутри подсистемы при вызовах операций startSession, closeSession и sendDeletedOrder мы не будем.


Проектирование классов системы
(общее для всех вариантов)


      Проектирование классов включает следующие действия: детализацию проектных классов; уточнение операций и атрибутов; моделирование состояний для экземпляров классов; уточнение связей между классами. При детализации проектный класс может быть разбит на несколько классов из соображений, связанных с его реализацией в коде. Класс может быть удалён из модели, если его экземпляры являются посредниками, не несущими содержательных обязанностей. Обязанности классов, определённые в процессе анализа и документированные в виде операций анализа, преобразуются в операции, которые будут реализованы в коде. При этом каждой операции присваивается краткое имя, характеризующее её, определяется полная сигнатура операции, создаётся краткое описание операции, содержащее смысл всех её параметров, определяется видимость операции, определяется область действия операции (операция экземпляра или операция класса). Если метод, реализующий операцию, реализует нетривиальный алгоритм, то он моделируется на диаграмме деятельности. Уточнение атрибутов классов заключается в следующем: задаются типы атрибутов, их множественность и значения по умолчанию (необязательно); задаётся видимость атрибутов; при необходимости определяются производные (вычисляемые) атрибуты, статические атрибуты.

      Если экземпляры некоторого класса реализуют сложное поведение, меняют своё поведение в зависимости от состояния, то для этого класса строят диаграмму состояний. При построении диаграммы уточняются операции, так как они могут быть связаны с событиями, вызывающими смену состояний, и с действиями на переходах и внутри состояний. Уточняются атрибуты, так как текущее состояние экземпляра определяется совокупностью значений его атрибутов.

      Затем производится уточнение связей между классами. Ассоциации, созданные на этапе анализа, которые соответствуют временным соединениям между объектами, заменяются на зависимости. Оставшиеся ассоциации заменяются на агрегации или композиции. Указываются мощности на полюсах, направления связей, типы множественных связей (set, ordered, bag, sequence), квалификаторы. Классы ассоциаций преобразуются в обычные с помощью материализации связей. Некоторые связи обобщения могут быть преобразованы применением метаморфозы подтипов.

      Рассмотрим проектирование классов на примере системы обработки заказов. Откройте в пакете WarehouseArtefacts диаграмму классов. Добавьте и уточните атрибуты и операции классов, чтобы придать ему вид, схожий с рисунком 5.2.13. Статические (подчеркнутые) атрибуты и операции пометьте, указав в их спецификации в поле Scope значение сlassifier. Аналогично поступите с выводимыми (начинающимися со слэша) атрибутами и операциями (отметьте флажок Derived). Чтобы указать квалификатор, используйте контекстное меню ассоциации.

Рис. 5.2.13. Диаграмма классов WarehouseArtefacts Class Diagram

Рис. 5.2.13. Диаграмма классов WarehouseArtefacts Class Diagram

      Экземпляры класса Order должны по-разному обрабатывать вызовы их операции в зависимости от состояния заказа. Например. если сборка заказа закончена, то в него нельзя добавлять новые позиции. Это признак сложного поведения и причина для создания диаграммы состояний. Добавьте классу Order диаграмму состояний Order Lifeсycle. Начальное состояние (Initial) создается автоматически. Создайте финальное состояние (FinalState) и состояние Active (State). Внутри состояния Active разместите подсостояния In Process, Cancelled, Filled, Delivered и псевдосостояние выбора (Choice). Соедините состояния переходами, как указано на рисунке 5.2.14.

      

      Переходу может быть добавлено событие (триггер), указываемое до слэша, действие, указываемое после слэша, сторожевое условие, записываемое в прямоугольных скобках. События addItem, removeItem, delete, markDelivery, markFilledItem, cancel и when(numOfItems>0 && numOfItems == numOfFilledItems) добавляйте на вкладку Triggers спецификаций переходов. Типы всех событий, кроме последнего -- события вызова (Call Trigger). Тип последнего события -- событие изменения (Change Trigger). Событие removeItem приписано разным переходам. Не следует создавать дважды это событие. Привяжите одно и то же событие обоим переходам. Действия при переходах указывайте в поле Effect, текст действия указывайте в имени создаваемой деятельности. Значок "^" в записи действия указывает на отправку сообщение другому объекту. Чтобы добавить внутренние переходы в состоянии In Process добавьте сначала ему внутреннюю область с помощью контекстного меню (Add Region).

      Постройте модель состояний в соответствии с рисунками 5.2.14, 5.2.15.

Рис. 5.2.14. Диаграмма состояний Order Lifecycle внутри класса Order

Рис. 5.2.14. Диаграмма состояний Order Lifecycle внутри класса Order

Рис. 5.2.15. Структура модели состояний

Рис. 5.2.15. Структура модели состояний

      К проектированию классов также относится моделирование нетривиальных реализаций операций (т. е. методов). Например, тривиальными являются операции-геттеры. Нетривиальная операция содержит в своём методе ветвления и/или циклы. В нашу модель внутрь проектного класса OrderController можно добавить диаграмму деятельности newOrderData (см. левую часть рис. 5.2.16), а также внутрь проектного класса Order -- диаграмму деятельности toString (см. правую часть рис. 5.2.16). По желанию Вы можете построить эти диаграммы. Сторожевое условие внутрь структурного узла Loop добавляется как Text Box.

Рис. 5.2.16. Диаграммы деятельности newOrderData и toString, моделирующие реализации одноимённых операций

Рис. 5.2.16. Диаграммы деятельности newOrderData и toString, моделирующие реализации одноимённых операций

      Уточним связи между классами на диаграмме Design CRUDOrdersVOPC проектной реализации варианта использования CRUD данных о заказах. Откройте диаграмму (Design Model -> Use Case Realization -> DesignCRUDOrdersVOPC). Удалите из модели (в Model Explorer) лишние ассоциации между проектными классами. Добавьте недостающие зависимости. Проведите уточнение связей. OrderController использует интерфейс, для этого в нём хранится ссылка на экземпляр класса, реализующего этот интерфейс. На диаграмме этот факт отображается агрегацией к интерфейсу. OrderController также хранит ссылку на текущий заказ. Укажите направления ассоциаций. Обратите внимание, что ассоциации без стрелочек являются двунаправленными.

Рис. 5.2.17. Уточненная диаграмма классов DesignCRUDOrdersVOPC

Рис. 5.2.17. Уточненная диаграмма классов DesignCRUDOrdersVOPC

Упражнение 5.3. Проектирование базы данных


      Если среди проектных классов есть устойчивые, чьи экземпляры должны сохраняться в периодах между запусками системы, следует обеспечить сохранение их в базе данных (например, реализовав подсистему обеспечения устойчивости на базе JDBC) и создать схему базы данных. Фактически, следует отобразить объектную модель в реляционную. Одна из стратегий при этом состоит в том, что для каждого устойчивого класса создаётся собственная таблица. Атрибуты класса переводятся в столбцы таблицы. Столбцы для хранения выводимых атрибутов не заводятся, т. к. эти значения вычисляются при выполнении запросов. Атрибуты с нескалярными значениями (массивами) переводятся в отдельные таблицы, чтобы не нарушать ограничений 1й нормальной формы. Атрибут-идентификатор становится первичным ключом. Ассоциации моделируются с помощью связей между таблицами (связывающими значения первичного ключа записей одной таблицы со значениями внешнего ключа другой таблицы). Заметим, что связи между таблицами обычно двунаправленные, по записям любой из связанных таблиц можно найти соответствующие записи другой таблицы. Связи между таблицами могут быть идентифицирующими и не идентифицирующими. Идентифицирующая связь указывает, что внешний ключ включает в себя часть первичного ключа, то есть ключ родительской записи является частью ключа дочерних записей. Связь отображается как композиция, если требуется указать на зависимость по существованию. В некоторых случаях для ассоциации (например, * к *) требуется создавать таблицу, хранящую соединения между объектами. Для отображения обобщений используются разные способы. Один из них -- "отдельная таблица для каждого класса". В этом случае у всех получившихся таблиц будет один и тот же первичный ключ, который в таблицах подклассов будет также внешним ключом.

      Осуществим проектирование базы данных. Продублируйте рекурсивно пакет WarehouseArtefacts. Полученный дубль переименуйте в Database Schema и переместите в корень Design Model. Назначьте ему стереотип «schema». С помощью Model Explorer удалите всё лишнее из этого пакета: зависимости, перечислимые типы, класс ClientList, диаграмму состояний, все операции классов. Диаграмму WarehouseArtefacts Class Diagram2, находящуюся в пакете, переименуйте в 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 -- также является внешним ключом. Связь промоделирована как композиция. Это означает, что при удалении записи о клиенте удаляются и все связанные записи о телефонах удаляемого клиента.

      Согласно этой схеме одному объекту -- экземпляру класса Order -- будут соответствовать одна запись в таблице TableOrder и связанные с ней записи в таблице TableOrderItem. Во всех этих записях будет одно и то же значение номера заказа. Для любой записи в таблице TableOrderItem можно найти связанную с ней запись из таблицы TableOrder о заказе, к которому относится эта позиция. И наоборот, для любой записи из таблицы TableOrder можно найти связанные с ней записи из таблицы TableOrderItem о позициях этого заказа. Очевидно, связь между таблицами двунаправленная. Каждой записи в таблице TableOrderItem соответствует одна запись из таблицы TableArticleOfFurniture. Соответствие между объектами других классов-сущностей и записями других таблиц определите самостоятельно.

Рис. 5.3.1. Диаграмма классов Database Schema

Рис. 5.3.1. Диаграмма классов Database Schema

      Упражнения по анализу и проектированию системы обработки заказов на этом закончены. Остались не реализованными остальные варианты использования, но мы не ставили целью полностью спроектировать систему, лишь рассмотрели работы, выполняемые в рамках разных процессов жизненного цикла. Перед тем как сдавать полученную модель, попробуйте ответить на вопросы из списка.

Предупреждение


Размещение на других ресурсах, а также коммерческое использование материалов, опубликованных в данном разделе, возможно только с разрешения авторов. По всем вопросам пишите:   

  

© Кафедра системного программирования ВМК МГУ.

Обновлено: 5.IV.2019