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

Моделирование системы обработки заказов. Выполнение учебного проекта в среде Modelio


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

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

Содержание


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

1. Сведения о работе в среде Modelio


      Modelio (www.modelio.org) -- среда объектно-ориентированного проектирования на языке UML. Для установки следует загрузить архив версии 3.0 RC2a со страницы загрузки и разархивировать его. Поскольку практикум в компьютерных классах проходит под операционной системой Windows, описывается работа в ней. При разархивировании укажите путь, например, C:\Program Files\Modelio. Для запуска среды вызывается исполняемый файл modelio.exe из директории C:\Program Files\Modelio. Для работы среды необходимо установить Java SE Runtime Environment 7 с сайта www.java.com. Следует убедиться, что в переменной среды Path прописан путь к файлу java.exe из JRE (что-то вроде C:\Program Files\Java\jre7\bin). Запуск может быть неудачен, если в качестве рабочей директории используется папка, в которую нет права записи у текущего пользователя. Следует запускать среду, используя директорию, на которую достаточно прав.

      Запустив среду, указываем путь к рабочей области (workspace), в которой будут находиться файлы нашего проекта (меню File -> Switch workspace). Для простоты воспользуемся шаблоном проекта, в котором уже создана основная структура модели, добавлены стереотипы и проектный механизм JDBC. Загружаем шаблон с веб-странички курса. Импортируем проект в рабочую область (меню File -> Import project). В рабочей области появился проект MyProject. Откроем его (Ctrl+O). После этого окно примет вид, показанный на рисунке 1.1.

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

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

      Согласно технологии Rational Unified Process на верхнем уровне модель должна состоять из четырёх пакетов, называемых архитектурными представлениями. Каждый из них показывает будущую систему с определённой точки зрения. Представление вариантов использования (Use Case View) содержит модель требований к системе. Логическое представление (Logical View) содержит логическую структуру системы, её организацию в классы и пакеты. Представление реализации (Component View) описывает организацию компонент из которых осуществляется сборка системы. Представление размещения (Deployment View) содержит модель вычислительной среды, в которой будет функционировать система.

      По содержимому вкладки Element можно узнать, что текущий элемент, выделенный в браузере, является пакетом Use Case View. К этому элементу применён стереотип <<architectural view>>, указывающий, что пакет является архитектурным представлением.

      В составе модели уже есть одна диаграмма -- overview diagram. Откроем её, выделив в браузере и сделав двойной клик. В редакторе диаграмм слева появится палитра элементов, остальную часть окна редактора займёт диаграмма. Окно примет вид, показанный на рисунке 1.2.

      Рис. 1.2. Окно среды после создания архитектурных представлений.

      Выделим в редакторе Use Case View. Откроем вкладку Symbol. Мы можем изменить отображение Use Case View на диаграмме. Например, можно выбрать режим отображения стереотипов Text+icon, чтобы стереотип был показан пиктограммой и дополнительно был подписан строчкой текста. Стереотип можно рассматривать как пометку элемента модели, сообщающую пользователю дополнительные сведения. Пакет, помеченный <<architectural view>>, отличается от обычного пакета. У него специальное назначение -- группировать элементы модели, представляющие систему с определённой точки зрения. Стереотипы бывают полезны при обработке моделей программами. При трансформации модели в текст (код или документ) или в другую модель стереотипы указывают на способы обработки элементов модели.

      Запишем сделанные изменения (Ctrl+S). Чтобы сохранить промежуточную копию, к которой можно будет вернуться, если что-то пойдёт не так, закроем проект (меню File -> Close project). Наведём курсор на MyProject в браузере и вызовем правым кликом контекстное меню. Выберем пункт Export the project. Укажем в появившемся окне расположение и имя архива с проектом. Этот архив можно скопировать в надёжное место (например, на флешку) и при необходимости импортировать сохранённый проект в рабочую область, как мы это делали в начале работы.

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

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


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

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

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


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

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

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

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

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

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

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

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

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

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

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

      Глоссарий:

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

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

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

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

Заказ
(Order)

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

Заказчик
(Customer)

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

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

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

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

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

Остатки
(Balance)

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

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

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

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

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

Продавец
(Salesperson)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


      1. В браузере найдите пакет Use Case View, а внутри него модель Use Case Model. Правым щелчком вызовите контекстное меню Use Case Model. Create element -> Class. Созданный класс назовите "Система обработки заказов". Для этого выделите его в браузере и нажмите F2. Назначьте классу стереотип <<subject>> (контекстное меню Add stereotype). Этим классом в модели представляется рамка моделируемой программной системы. Выделите Use Case Model и вызовите контекстное меню Create diagram -> Create a Use Case diagram. Даёте диаграмме имя Main. Диаграмма открылась в окне редактора и появилась палитра с элементами диаграмм. Перетащите из браузера систему на диаграмму. На вкладке Symbol измените параметры её отображения. Отмените отображение атрибутов (Class - Attributes Show) и операций (Class - Operations Show), установите отображение вложенных элементов (Class - Inner elements Display mode = Diagram). Вид окна с получившейся диаграммой представлен на рисунке 3.1.1.

      Рис. 3.1.1. Окно среды после создания диаграммы вариантов использования.

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

      3. Увеличим размеры элемента Subject, чтобы он вместил варианты использования системы. Получившаяся диаграмма примет вид, показанный на рисунке 3.1.2.

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

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

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

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


Рис. 3.2.1. Диаграмма вариантов использования

      Рис. 3.2.1. Диаграмма вариантов использования для системы обработки заказов.

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

      2. В палитре редактора выберем связь Communication Link и проведём связь от действующего лица Продавец к варианту использования »CRUD данных о заказах». В свойствах отображения (вкладка Symbol, Association Show navigability) зададим отображение направление, поставив галку. Также можно указать тип линии (Line path style): прямая (Direct), ломанная (Bendpoint), прямоугольная ломанная (Orthogonal). Можно управлять выводом мощностей связи (Association Show cardinality). Если мощность выводится, следует её отключить. Для управления отображения всех элементов некоторого типа воспользуйтесь меню Configuration -> Diagram styles.

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

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

      5. Созданная диаграмма имеет недостаток в том, что у варианта использования «Войти в систему» несколько основных действующих лиц. Полагая поведение системы одинаковым при входе любого пользователя, введём абстрактное действующее лицо Пользователь, подвидами которого будут лица Продавец, Заведующий складом, Кладовщик. Диаграмма примет вид, изображённый на рисунке 3.2.2. Для добавления связей обобщения используйте связь Generalization. Лишние связи удалите из модели (Del). Обратите внимание, что нажатие на Del удаляет элемент и с диаграммы и из модели. Если необходимо сохранить элемент в модели и всего лишь убрать его с диаграммы, на которую он случайно попал по какой-то причине, нажимайте Ctrl+M или используйте пункт контекстного меню Mask Selection. Следует чётко понимать удаляете ли Вы текущий элемент или всего лишь маскируете. Удаление вместо маскирования (как и обратное) может быть нежелательным. Случайно удалённый элемент можно попытаться восстановить, нажав Ctrl+Z. Маскированный по ошибке элемент можно снова поместить на диаграмму, перетаскивая его из браузера.

Рис. 3.2.2. Модифицированная диаграмма вариантов использования

      Рис. 3.2.2. Модифицированная диаграмма вариантов использования

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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


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

      При желании можно настроить редактор. Для этого в главном меню выберите Configuration -> Diagram styles -> ControlFlow -> Line path style = Orthogonal.

      1. В браузере вызываем контекстное меню варианта использования «Войти в систему» и выбираем Create diagram -> Create an Activity diagram.

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

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

      4. Добавляем узлы логического ветвления (Decision). Соединяем узлы рёбрами потоков управления (Control Flow). Задать нетривиальные сторожевые условия можно на вкладке Element в поле Guard.

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

Рис. 3.4.1. Диаграмма деятельности с ошибкой

      Рис. 3.4.1. Диаграмма деятельности с ошибкой

      Диаграмма деятельности задаёт потоки управления между узлами. Изначально курсор управления порождается во входном узле. Оттуда он передаётся по ребру на вход узла действия (Запрос имени и пароля). Узел действия ждёт, когда курсоры управления придут на все входящие ребра, после чего запускается действие, а по окончании действия курсоры управления подаются на все исходящие ребра. Очевидно, наша диаграмма содержит ошибку. По второму ребру курсор управления придёт не раньше, чем узел действия выдаст его на выход. Тупик. Чтобы исправить ошибку, добавим узел объединения (Merge), чтобы в узел действия входило одно ребро (и чтобы для выполнения действия требовался один входящий курсор). Узел объединения принимает курсор с любого входящего ребра и сразу передаёт его на исходящее ребро, которое у него одно. Дополнительно укажем действующих лиц, которых представляют собой разделы диаграммы. Для этого выберите раздел на диаграмме. Во вкладке Element поместите курсор ввода в поле Represented by. Затем выберите в браузере нужное действующее лицо (при расположении курсора рядом с действующим лицом появится пиктограмма горящей лампочки). Можно заполнять поле Represented by при помощи клавиатуры. Начните вводить имя элемента, а затем нажмите Ctrl+Space. Среда подскажет подходящие значения поля. Исправленная диаграмма показана на рисунке 3.4.2.

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

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

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

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

      Самостоятельно постройте диаграмму для варианта использования «CRUD данных о заказах». Обратите внимание, что подчинённый поток может быть представлен на диаграмме в виде одного узла (см. узлы «c1:call Ввести заказ», «c2:call Изменить заказ», «c3:call Удалить заказ»). Тип этих узлов -- Call Behavior (узел вызова действия). С каждым из них связана деятельность, которая может быть промоделирована отдельной диаграммой деятельности. При создании диаграммы следует сначала создать внутри варианта использования три деятельности (Activity): Ввести заказ, Изменить заказ, Удалить заказ. Затем создайте узлы вызова действия и в каждом из них укажите вызываемую деятельность на вкладке Element в поле Called element. Заполнять это поле следует так, как было описано при сопоставлении разделов диаграммы с действующими лицами.

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

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

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

      Перейдём к анализу.

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


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

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

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

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

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

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

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

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

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

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

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

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

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

  7. Для каждого варианта использования должна быть создано взаимодействие, моделирующее реализацию варианта использования. Каждое такое взаимодействие содержит вложенную кооперацию и диаграммы взаимодействия, описывающие базовый поток событий, а также альтернативные и подчинённые потоки событий. Кооперация -- это группа экземпляров классов или экземпляров интерфейсов, которые взаимодействуют, обеспечивая общее поведение (в нашем случае -- реализацию варианта использования). Участвующие в кооперации объекты представляются ролями, связанными соединениями.

  8. Для каждого варианта использования должна быть создана диаграмма классов VOPC (View Of Participating Classes) внутри пакета Use Case Realizations, изображающая классы, участвующие в его реализации.

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


Рис. 4.1.1 Структура модели анализа

      Рис. 4.1.1. Структура модели анализа

      1. В модели Analysis Model (модель анализа) создадим пакет Use Case Realizations. Для этого в браузере проекта вызовем контекстное меню пакета Analysis Model, Create element -> Package.

      2. В пакет Use Case Realizations добавим две диаграммы последовательности (контекстное меню пакета Use Case Realizations -> Create diagram -> Create a Sequence diagram). Среда сама создаёт взаимодействия и размещает внутри взаимодействий диаграммы последовательности. Переименуем созданные взаимодействия в Login, CRUD Orders. Диаграммы внутри взаимодействий переименуем в Basic flow. Каждое взаимодействие описывает сценарии одного из вариантов использования: Login -- Войти в систему, CRUD Orders -- CRUD данных о заказах. Диаграммы Basic flow служат для моделирования реализации основных сценариев.

      3. Создадим диаграммы классов VOPC (VOPC Login, VOPC CRUD Orders). Контекстное меню пакета Use Case Realizations, Create diagram -> Create a Class Diagram. VOPC это сокращение View Of Participating Classes. Назначение этих диаграмм -- отображение классов, участвующих в реализации варианта использования и связей между этими классами.

      4. Создадим диаграмму классов Key Abstractions. Контекстное меню пакета Analysis Model, Create diagram -> Create a Class Diagram.

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

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

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

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

      Предварительно настроим среду для более удобной работы. Меню Configuration -> Preferences. В открывшемся окне укажем тип атрибутов по умолчанию: undefined, видимость атрибутов по умолчанию: private, тип параметров операций по умолчанию undefined, тип результата операций по умолчанию undefined. Меню Configuration -> Diagram styles. В открывшемся окне в дереве настроек найдём Class. Укажем отображение стереотипов (Stereotypes display mode): Text + Icon. Установим метку Class Attributes ->Show для отображения атрибутов. Также отметим Show visibility. Class - Inner elements -> Display mode: Hidden. Class - Internal structure -> Display mode: Hidden. Отметим Class - Operations -> Show, и там же -- Display signatures, Show visibility. Можно аналогичные настройки сразу же установить для Interface. Сохраняем настройки, закрываем редактор стилей.

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

      2. Добавим перечислимый тип (Enumeration) TypeOfUser (Тип пользователя). Внутри него расположим три значения перечислимого типа (enumeration literal): salesman, warehouseman, stockman.

      3. Выберем в палитре инструмент Association. Проведём связи между классами. Уберём направления связей по умолчанию (поля Navigable в закладке Element). Укажем мощности у полюсов -- концов ассоциаций (поля Multiplicity min и Multiplicity max в закладке Element). Укажем, что связь между заказом и позицией заказа -- композиция (в поле Association type со стороны OrderItem занести Composition).

      4. Добавим атрибуты (Attribute) классов: классу Order -- number, creationDate, deliveryDate, fillingDate; классу OrderItem -- quantity, number; классу ArticleOfFurniture -- description; классу Customer -- name, address, phones; классу User -- login, password. Укажем мощность атрибута Customer::phones (вкладка Element, Multiplicity Min = 1, Multiplicity Max = *).

      5.Проведём зависимость (Dependency -- находится в нижнем разделе палитры Common) от класса User к перечислимому типу TypeOfUser.

      6. Добавим всем классам-сущностям стереотип <<entity>>. Для этого выделим нужный класс в браузере, вызовем контекстное меню, Add stereotype -> <<entity>>. В итоге диаграмма должна соответствовать рисунку 4.1.2.

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

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

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

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

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

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

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

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

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

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

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

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


      Идентифицируем классы анализа. Согласно диаграмме вариантов использования имеются два действующих лица (Продавец и Бухгалтерская система), связанных с нашим вариантом использования. Создадим в пакете Analysis Model граничные классы: MainMenuForm -- форму главного меню, OrderForm -- форму заказа, AccountingSystem -- класс-посредник, реализующий протокол взаимодействия с Бухгалтерской системой. В браузере вызовем контекстное меню пакета Analysis Model, Create element -> Class. Создадим управляющий класс OrderController, отвечающий за реализацию бизнес-логики (действия аналогичны). Из описания варианта использования следует, что в потоках событий будут задействованы экземпляры классов Order, OrderItem, ArticleOfFurniture, Customer. Открываем в редакторе диаграмму классов VOPC CRUD Orders. Перетаскиваем на неё вышеупомянутые классы из браузера. Также перетаскиваем на диаграмму связи между классами-сущностями, участвующими в реализации варианта использования.

      Назначим классам стереотипы. Выделите в браузере класс OrderController. С помощью контекстного меню добавьте стереотип <<control>>. Аналогично добавьте стереотип <<boundary>> граничным классам MainMenuForm, OrderForm, AccountingSystem. Классам-сущностям Order, OrderItem, ArticleOfFurniture, Customer назначьте стереотип <<entity>>, если не сделали этого ранее.

      Вид диаграммы, которая должна получиться, изображён на рис. 4.2.1.

Рис. 4.2.1 Диаграмма VOPC CRUD Orders

      Рис. 4.2.1. Диаграмма VOPC CRUD Orders

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

      Откроем внутри взаимодействия CRUD Orders диаграмму последовательности Basic Flow (основной поток). В браузере видно, внутри взаимодействия помимо диаграммы создана кооперация (Collaboration) locals. Внутри этой кооперации добавим роли. Ими будут являться взаимодействующие объекты: s -- экземпляр действующего лица Продавец; m -- экземпляр формы MainMenuForm; f -- экземпляр формы OrderForm; c -- экземпляр класса OrderController; asys -- экземпляр граничного класса AccountingSystem и a -- экземпляр действующего лица Бухгалтерская система. В браузере выделите кооперацию CRUD Orders, вызовите её контекстное меню, Create element -> Role. На закладке Element заполните поля Name и Base. Поле Base легче заполнять, помещая в него курсор ввода и затем указывая нужный элемент модели (класс или действующее лицо) в браузере.

      Добавим на диаграмму пять линий жизни (Lifeline) -- перетащим все созданные роли (кроме f:OrderForm) из браузера на диаграмму последовательности. Левая линия жизни представляет собой экземпляр действующего лица Продавец. Правая линия жизни -- экземпляр действующего лица Бухгалтерская система. В середине линия жизни MainMenuForm, линия жизни OrderController и AccountingSystem. Заметьте, что линии жизни объектов граничных классов находятся рядом линиями жизни, представляющими тех действующих лиц, за общение с которыми они отвечают, а линия контроллера расположена в середине диаграммы.

      Добавим спецификацию выполнения (Execution Specification) на линию жизни Продавца. Затем выберем на палитре синхронное сообщение (Synchronous Message) и проведём его от спецификации выполнения к линии жизни m:MainMenuForm. Дадим имя сообщению //crudOrders. Удалим автоматически созданное ответное сообщение (пунктирную стрелку в обратном направлении следует выделить и нажать на Del). Добавим второе синхронное сообщение с тем же именем, которым форма извещает контроллер о выборе продавца (возврат также удаляем, мы не будем изображать возвраты на диаграммах последовательности). Экземпляр контроллера запрашивает соединение с бухгалтерской системой у экземпляра граничного класса. Он, в свою очередь пересылает запрос от контроллера экземпляру действующего лица. Каждое сообщение экземпляру класса должно быть связано с операцией данного класса. Сообщения, получаемые экземплярами действующих лиц, связывать с операциями не следует. Создадим в классе MainMenuForm операцию //crudOrders. Два слэша указывают, что это предварительное имя, которое в дальнейшем будет уточнено. Аналогично создадим операции //crudOrders в классе-контроллере и //startSession в AccountingSystem. Свяжем сообщения с операциями, заполнив поле Invoked на вкладке Element.

Рис. 4.2.2. Начальный вид диаграммы Basic flow

      Рис. 4.2.2. Начальный вид диаграммы Basic flow

      Далее есть два варианта развития событий. Либо удаётся связаться с бухгалтерской системой и всё идёт своим чередом, либо экземпляр формы MainMenuForm выводит сообщение об ошибке, посылая самому себе сообщение //displayError. Добавим на диаграмму комбинированный фрагмент взаимодействия (Combined Fragment). Укажем его тип -- Alt (вкладка Element, поле Operator). Добавим во фрагмент второй операнд взаимодействия (выделите на палитре Interaction Operand и добавьте к фрагменту снизу). По умолчанию операнды получают пустые сторожевые условия. Ввести нужные условия следует, выделив операнд взаимодействия на диаграмме и заполнив поле Guard на вкладке Element. Добавим на диаграмму ещё один Lifeline, воспользовавшись палитрой редактора. Пока не будем указывать, с каким объектом связана эта линия жизни. Проведем сообщение типа Creation Message от контроллера к созданной линии жизни. На вкладке Element заполним поле Represented by, указав роль f:OrderForm. Мы смоделировали, как главное меню открывает вспомогательное окно для работы с заказом. Создадим в классе OrderForm операцию //open. Свяжем сообщение к OrderForm с этой операцией. В нижней части верхнего операнда фрагмента нарисуем сообщения от объекта-контроллера к экземпляру граничного класса и далее к экземпляру действующего лица Бухгалтерская система. Поместим в нижнем операнде взаимодействия спецификацию выполнения на линию жизни m:MainMenuForm и рефлексивное сообщение (Inner Synchronous Message) для вывода предупреждения об ошибке. Диаграмма примет вид, схожий с рисунком 4.2.3. Не забудьте создать операции //closeSession() и //displayError() и связать их с сообщениями. Для disconnect создавать операцию не следует, достаточно только указать имя сообщения.

Рис. 4.2.3. Диаграмма Basic flow с добавленным фрагментом взаимодействия

      Рис. 4.2.3. Диаграмма Basic flow с добавленным фрагментом взаимодействия

      Для моделирования вариантов продолжения потока событий создадим внутри верхнего операнда взаимодействия вложенный комбинированный фрагмент. Укажем его тип (Alternative). Добавим ещё два операнда взаимодействия в созданный комбинированный фрагмент. Добавим операндам сторожевые условия.

      Внутри каждого их трёх операндов комбинированного фрагмента будет происходить одно из взаимодействий, соответствующих трём подчинённым потокам варианта использования. Чтобы не загромождать диаграмму основного потока для каждого подчинённого потока создаётся отдельная диаграмма. На основной диаграмме будут размещены лишь ссылки на используемые взаимодействия. Выделим в браузере кооперацию locals внутри взаимодействия CRUD Orders. Добавим кооперации новые элементы-взаимодействия (Interaction): Create Order subflow, Update Order subflow, Delete Order subflow. В созданный нами последним комбинированный фрагмент взаимодействия с тремя операндами добавим по одному элементу Interaction Use в каждый операнд. Во вкладке Element для каждого Interaction Use заполним поле Refers to. Диаграмма примет окончательный вид, показанный на рисунке 4.2.4.

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

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

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

      Создание заказа моделируется на диаграмме последовательности созданной внутри взаимодействия CRUD Orders. Продавец посылает дату поставки и сведения о заказчике в форму. Форма, получив эти данные, передаёт запрос о создании заказа OrderController'у. Он создаёт экземпляр класса Order и проверяет, есть ли в системе данные о заказчике. Если их нет, выполняется взаимодействие описанное комбинированным фрагментом взаимодействия (Combined Fragment), являющимся Optional блоком. Ниже блока находится сообщение от OrderController, записывающее в заказ ссылку на его заказчика. Ещё ниже расположен блок loop, который описывает, что для каждой позиции заказа Продавец вводит данные. Данные из формы попадают к контроллеру. Он проверяет, что введённая позиция есть в перечне предметов мебели. По результатам проверки есть два варианта действий. Если проверка успешна, контроллер запрашивает у Order добавление новой позиции. Логично возложить эту обязанность на сам заказ, чтобы оградить контроллер от лишних знаний о внутреннем устройстве заказа. Как заказ работает с собственными позициями -- это его личное дело. Если данные от Продавца ошибочны, данные о такой позиции заказа в системе не сохраняются.

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

      На диаграмме есть линии жизни ранее созданных ролей. Следует добавить новые роли -- o (экземпляр класса Order), cstmr (экземпляр класса Customer), art (экземпляр класса ArticleOfFurniture), и item (экземпляр класса OrderItem) в кооперацию locals внутри взаимодействия CRUD Orders. На диаграмме использованы комбинированные фрагменты с оператором opt (Optional), представляющие ветвления с единственной содержательной альтернативой, а также комбинированные фрагменты с оператором loop, описывающие циклы. Создавая циклы, следует задать в сторожевых условиях ограничения на количество итераций. Обратите внимание, что на рис. 4.2.5 есть сообщения //new, которые имеют тип Creation Message. Не забудьте добавить соответствующие операцию в классы и связать их вызовы с сообщениями (в класс OrderForm -- операции //newOrderData, //newItemData, //saveOrder; в класс OrderController -- операции //newOrder, //newOrderItem, //saveOrder; в класс Order -- операции //new, //setCustomer, //addItem, //toString; в класс Customer -- операции //new, //find, //toString; в класс OrderItem -- операции //new, //toString; в класс ArticleOfFurniture -- операцию //find; в класс AccountingSystem -- операцию //sendNewOrder; действующему лицу создавать операцию не следует). При создании линии жизни, которой посылается сообщение типа Creation Message внутри комбинированного фрагмента, следует создать линию жизни при помощи элемента палитры Lifeline, добавить сообщение, затем указать линии жизни роль, которую она представляет (item:OrderItem), связать сообщение с операцией OrderItem:://new().

Рис. 4.2.5 Create Order subflow

      Рис. 4.2.5. Диаграмма Create Order subflow

      Каждое сообщение на диаграмме последовательности назначает экземплярам классов обязанности по отправке или приёму и обработке сообщения. Для приёма сообщения в классе объекта-приёмника должна быть одноимённая операция. Для отправки сообщения между экземплярами классов должно быть соединение, т. е. между классами, экземпляры которых обмениваются сообщениями, должна быть ассоциация. На диаграмме 4.2.4. Basic flow форма отправляет сообщение //crudOrders контроллеру. Значит, в классе OrderController должна быть одноимённая операция, которая обрабатывает сообщение от формы, а между классом-формой и классом контроллером должна быть ассоциация. Нарисуем её на диаграмме VOPC CRUD Orders. Мощности полюсов этой ассоциации 1 к 1. Аналогично, форма заказа посылает сообщения объекту-контроллеру. Проведём ассоциацию от OrderForm к OrderController (мощности полюсов 1 к 1). Объект-контроллер посылает сообщения объекту граничного класса AccountingSystem (см. рис. 4.2.4, 4.2.5), экземпляру класса Order, класса Customer и экземпляру класса ArticleOfFurniture (см. рис. 4.2.5), следовательно, нужны ещё ассоциации между классами. Добавьте ассоциации, соединяющие класс OrderController c AccountingSystem (0..1 к 1), его же с Order (0..1 к 0..1), с Customer (0..1 к 0..1) и с ArticleOfFurniture (0..1 к 0..1).

      Проверьте, что для каждого сообщения, принимаемого экземпляром любого класса (не действующего лица), существует связанная операция. На диаграмме VOPC CRUD Orders отобразятся созданные операции. В результате классы должны выглядеть, как показано на рисунке 4.2.6.

Рис. 4.2.6. Диаграмма VOPC CRUD Orders по окончании анализа

      Рис. 4.2.6. Диаграмма VOPC CRUD Orders по окончании анализа

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

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

      Созданную модель анализа следует сохранить отдельно. Из-за особенностей работы текущей версии среды Modelio при проектировании нам придётся разрушить модель анализа -- использовать её элементы для построения проектной модели. Однако при сдаче выполненных упражнений у Вас должны быть два проекта: один, сохранённый на момент окончания анализа; второй, представляющий модель после выполнения всех упражнений. Для сохранения проекта закройте проект и в контекстном меню проекта выберите пункт Export the project. Укажите в появившемся окне расположение и имя архива с проектом. Впоследствии из созданного средой архива проект можно импортировать в новый workspace.

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


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

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

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


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

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

Рис. 5.1.1. Диаграмма Main

      Рис. 5.1.1. Диаграмма Main

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

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

      Чтобы не испортить модель анализа, скопируем её содержимое внутрь проектной модели. В браузере выделите всё содержимое Analysis Model от пакета Use Case Realization до диаграммы Key Abstractions включительно (но не сам пакет). Нажмите Ctrl+C (или выберите в контекстном меню Copy Element). Выделите Design Model, нажмите Ctrl+V (Paste Element). Создайте в пакете Application пакет CRUDofOrders. В созданный пакет перетащите классы MainMenuForm, OrderForm, OrderController, AccountingSystem из корня проектной модели. Заметим, что стереотипы анализа в проектной модели смысла не имеют, их можно убрать. В пакете BusinessServices создайте пакеты WarehouseArtefacts (т. е. артефакты склада, в нем разместим классы-сущности предметной области, а также перечислимый тип TypeOfUser), пакет Interfaces (где будут находиться все интерфейсы), пакет DBAccess со стереотипом <<subsystem>> (в нём создайте одноимённый класс). Классу DBAccess назначьте стереотип <<subsystem proxy>> -- это означает, что он принимает все сообщения, идущие внутрь подсистемы. Диаграмму классов Key Abstractions перенесите в пакет WarehouseArtefacts. В пакете Interfaces создайте интерфейс IDBAccess. Структура проектной модели в браузере примет вид похожий на рис. 5.1.2.

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

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

      Создайте диаграмму классов Dependencies в пакете CRUDofOrders. Разместите на ней пакеты CRUDofOrders, Interfaces и WarehouseArtefacts, укажите их зависимости (Package Import). Элементы пакета CRUDofOrders используют классы-артефакты и интерфейс подсистемы, отсюда две зависимости. Диаграмма примет вид, представленный на рис. 5.1.3.

Рис. 5.1.3. Связи пакета CRUDofOrders

      Рис. 5.1.3. Связи пакета CRUDofOrders

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

Рис. 5.1.4. Структура уровня BusinessServices

      Рис. 5.1.4. Структура уровня BusinessServices

      Моделировать структуру потоков управления системы не будем. Этот вопрос будет рассматриваться на лекции. Перечислим лишь виды процессов в нашей системе: WarehousemanApplication -- пользовательский процесс рабочего места заведующего складом; SalespersonApplication -- пользовательский процесс рабочего места продавца; StockmanApplication -- пользовательский процесс рабочего места кладовщика; OrderProcess -- общий процесс, управляющий обработкой заказов; AccountingSystemAccess -- процесс обеспечивающий связь с бухгалтерской системой; DBAccessProcess -- процесс, обеспечивающий связь с реляционной СУБД. Последние два нужны для обеспечения эффективности, т. е. поддержки кэшей данных. Перейдём к моделированию конфигурации вычислительной среды. Вычислительная среда состоит из трёх типов узлов -- сред выполнения (Execution Environment) или процессоров, на которых могут быть размещены вложенные узлы-процессы (Process), и устройств (Device). Связи между узлами -- пути коммуникации -- являются подвидами ассоциации. Создайте диаграмму размещения Deployment View внутри одноимённого архитектурного представления. Узлы-процессы следует создавать, размещая их внутри родительского узла. Окончательный вид диаграммы приведён на рис. 5.1.5. Добавьте стереотипы, настройте отображение узлов (Node) в стилях диаграмм. Отметьте отображение внутренних элементов в виде диаграммы и отображение стереотипов в виде текста или текста с пиктограммой. По диаграмме размещения можно судить, что в среде есть сервер обработки заказов, к которому подключён принтер и рабочие станции трёх типов. Также на диаграмме указан узел, относящийся к окружению системы -- сервер бухгалтерской системы, подключённый к серверу обработки заказов. СУБД развёрнута на сервере обработки заказов.

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

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

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

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


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

      Проектные реализации вариантов использования являются более полными, чем реализации, созданные в ходе анализа. В них вместо экземпляров классов анализа должны присутствовать экземпляры проектных классов и интерфейсов, т. е. должны быть учтены трансформации классов анализа в проектные элементы. Проведём уточнение реализаций вариантов использования. Откроем диаграмму последовательности Create Order subflow из взаимодействия CRUDorders в пакете Logical View::Design Model::Use Case Realizations.

      На диаграмме Create Order subflow следует учесть, что экземпляры классов Customer, ArticleOfFurniture являются устойчивыми, следовательно их надо запрашивать из базы данных. В кооперацию locals внутри взаимодействия CRUDOrders добавьте новую роль db:IDBAccess (экземпляр класса, реализующего интерфейс IDBAccess). На диаграмму Create Order subflow добавьте линию жизни, представляющую созданную роль, и направьте к нему сообщения для поиска заказчика (findCustomer(cName:String):Customer вместо сообщения find к объекту Customer), для создания записи о новом заказчике (createCustomer(addr:String, name:String, phones:String):Customer вместо new к Customer) и для проверки предмета мебели, введённого в позиции заказа (checkArticle(description:String, qty:int):boolean вместо find к ArticleOfFurniture). Тем самым мы показываем, что происходит обращение к экземпляру класса, реализующему интерфейс подсистемы, отвечающей за доступ к базе данных. Какой именно это будет класс -- это для реализации варианта использования неважно. Реализация варианта использования не определяет, как подсистема DBAccess должна обрабатывать такие вызовы. Эта часть относится к проектированию подсистемы и может варьироваться в зависимости от реализации подсистемы. Внутреннее поведение подсистемы скрыто, чтобы обеспечить возможность лёгкой модификации её реализации. Следует также добавить сообщение от экземпляра класса OrderController createOrder(o:Order) к экземпляру интерфейса после сообщения saveOrder, полученного объектом-контроллером. Поскольку на уточнённой диаграмме не осталось сообщений к экземпляру ArticleOfFurniture следует удалить его линию жизни. Диаграмма Create Order subflow примет вид, представленный на рисунке 5.2.1. Не забудьте создать операции в интерфейсе и связать с ними сообщения на диаграмме. Дополнительно создайте в интерфейсе операции init() и close(), управляющие соединением системы с СУБД.

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

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

      Подсистема пока содержит один класс со стереотипом <<subsystem proxy>>. Класс отвечает за реализацию интерфейса подсистемы. Объекты этого класса будут принимать и обрабатывать все входящие сообщения. Класс создаётся для удобства тестирования сопряжений при сборке системы. При реализации подсистемы мы воспользуемся механизмом RDBMS-JDBC из одноимённого пакета. При использовании механизма следует создать элемент модели Collaboration (кооперацию) с именем IDBAccess внутри подсистемы. Эта кооперация будет построена по шаблону проектного механизма, который является параметризованной кооперацией. Для каждого параметра шаблона RDBMS-JDBC нам понадобится указать соответствующий проектный класс. Мы собираемся подставить класс DBAccess вместо DBClass, Order -- PersistentClass, Customer -- PersistentClass.

      Создайте в подсистеме DBAccess кооперацию IDBAccess со стереотипом «interface realization». Если стереотип отсутствует в проекте, создайте его с помощью контекстного меню. Внутри кооперации IDBAccess создайте вложенный элемент -- конкретизацию шаблона RDBMS-JDBC. Укажите подставляемые параметры DBAccess вместо DBClass, Order и Customer вместо PersistentClass. В браузере внутри конкретизации шаблона удалите связывание параметра шаблона (Template Parameter Substitution) для параметра PersistentClassList. Продублируйте связывание параметра шаблона (Template Parameter Substitution) для параметра PersistentClass (скопируйте его и вставьте). На вкладке Element в поле Value укажите класс Customer из пакета WarehouseArtefacts для скопированного связывания. Создайте внутри кооперации диаграмму составной структуры (Composite Structure diagram) Main. Перетащите на неё кооперацию IDBAccess и кооперацию RDBMS-JDBC, также перетащите конкретизацию шаблона. Получившаяся диаграмма изображена на рис. 5.2.2.

Рис. 5.2.2. Диаграмма составной структуры Main

      Рис. 5.2.2. Диаграмма составной структуры Main

       Внутрь кооперации-реализации интерфейса IDBAccess скопируйте из механизма роль drMan:DriverManager, а также четыре взаимодействия Initialize, Create, Read и Disconnect. Взаимодействие Initialize (и диаграмму внутри него) переименуйте в init, Create -- в createCustomer, Read -- в findCustomer, Disconnect -- в close. Замените классы у всех ролей. Вместо DBClass укажите DBAccess, вместо PersistentClass -- Customer. Теперь создайте внутри подсистемы DBAccess диаграмму классов DBAccess. Поместите на неё интерфейс IDBAccess из пакета Interfaces. Поместите прокси-класс DBAccess. Проведите связь реализации (InterfaceRealization) от прокси-класса к интерфейсу. Перенесите на диаграмму классов DBAccess классы Customer и Order. Также поступите с классом DriverManager, интерфейсами Connection, Statement, ResultSet из пакета java.sql. Перенесите на диаграмму зависимости между DriverManager и интерфейсами из java.sql. Скопируйте все операции интерфейса в класс DBAccess. Добавьте зависимости от прокси-класса DBAccess ко всем элементам диаграммы, кроме интерфейса подсистемы. Наличие этих зависимостей следует из взаимодействий, описанных диаграммами последовательности из кооперации-механизма RDBMS-JDBC. В результате диаграмма классов и структура подсистемы должны быть похожи на рисунки 5.2.3 и 5.2.4.

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

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

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

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

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

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

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

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

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

      Схожим образом приведите диаграмму close в вид, изображённый на рисунке 5.2.6.

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

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

      На диаграмме последовательности findCustomer левая линия жизни должна представлять объект DBAccess, а вторая справа -- Customer. Самая правая линия жизни -- объект PersistentClassList должна быть удалена. Свяжите найденное сообщение, принимаемое экземпляром DBAccess, с операцией findCustomer. Добавьте классу Customer новую операцию setData(addr:String, name:String, phones:String). Свяжите с ней нижнее сообщение на диаграмме последовательности. Удалите вложенный цикл. Добавьте два сообщения getString к объекту ResultSet. Аргументы вызова задаются на вкладке Element в поле Argument. Замените оператор взаимодействия в комбинированном фрагменте с loop на opt. Исправьте сторожевое условие операнда взаимодействия. Диаграмма примет вид, изображённый на рисунке 5.2.7.

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

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

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

      Если бы мы моделировали реализацию операции createOrder, диаграмма создавалась бы аналогично createCustomer тем отличием, что не создавались бы экземпляры классов Order и OrderItem, так как они созданы в ходе потока Create Order subflow варианта использования CRUD данных о заказах, но для составления запроса или группы запросов к БД запрашивались бы сведения и у объекта Order и у его составных частей -- экземпляров OrderItem.


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

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

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

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

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

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

      Рассмотрим проектирование классов на примере системы обработки заказов. Создайте в пакете WarehouseArtefacts диаграмму классов Order. Поместите классы Order, OrderItem и ассоциацию между ними на диаграмму. Добавьте и уточните его атрибуты и операции, чтобы придать ему вид, схожий с рисунком 5.2.9. Статические (подчеркнутые) атрибуты и операции пометьте специальным флажком (вкладка Element, поле Class). Аналогично поступите с выводимыми (начинающимися со слэша) атрибутами и операциями (вкладка Element, поле Derived). Типы long, byte, boolean и String используйте из пакета java.lang, Date -- из java.util. Чтобы указать упорядоченность объектов OrderItem, связанных c одним и тем же объектом Order, отметьте флажок Ordered на вкладке Element. К сожалению среда не отображает эту отметку на диаграмме. Поэтому добавьте примечание к ассоциации. На вкладке Element введите тип примечания Constraint и его текст: {ordered}.

Рис. 5.2.9. Диаграмма классов Order

      Рис. 5.2.9. Диаграмма классов Order

      Экземпляры класса Order должны по-разному обрабатывать вызовы их операции в зависимости от состояния заказа. Например. если сборка заказа закончена, то в него нельзя добавлять новые позиции. Это признак сложного поведения и причина для создания диаграммы состояний. Добавьте классу Order диаграмму состояний LifeCycle (контекстное меню, Create diagram -> Create a State Machine Diagram). Создайте начальное состояние (Initial), финальное состояние (FinalState) и композитное состояние Active (State). Внутри состояния Active разместите подсостояния In Process, Canceled, Filled, Delivered и псевдосостояние выбора (Choice). Соедините состояния переходами, как указано на рисунке 5.2.10.

      Создайте в элементе State Machine, автоматически созданном при добавлении диаграммы состояний, события addItem, removeItem, delete, markDelivery, markFilledItem, cancel и when(numOfItems>0 && numOfItems == numOfFilledItems). Укажите типы событий (вкладка Element, поле Kind). Типы всех событий, кроме последнего -- события вызова (Call). Тип последнего события -- событие изменения (Change). Создайте в классе Order операции: addItem(art: ArticleOfFurniture, qty:byte), removeItem(num: byte), cancel(), delete(), markDelivery(), markFilledItem(num: byte). Свяжите одноимённые операции и события вызова (вкладка Element, поле Called element). У события изменения укажите выражение, при наступлении истинности которого возникает событие: numOfItems>0 && numOfItems == numOfFilledItems.

      Переходу может быть добавлено событие, указываемое до слэша, действие, указываемое после слэша, но перед "^", сторожевое условие, записываемое в прямоугольных скобках, и отправка сообщения, указываемая после "^". Для добавления переходу события-триггера во вкладке Element в поле Received event укажите подходящее событие. Событие removeItem приписано разным переходам. Не следует создавать дважды это событие. Привяжите одно и то же событие обоим переходам. Действия на переходах создаются в поле Expression of the action. Просто введите в поле нужный текст (тот, который идёт после слэша в надписи рядом с переходом). Действие по отправке сообщения -- текст после "^" -- указывается в поле Sent signal/events.

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

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

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

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

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

      Уточним связи между классами на диаграмме VOPC CRUD Orders проектной реализации варианта использования CRUD данных о заказах. Откройте диаграмму (Design Model -> Use Case Realization). Проверьте, изображены на диаграмме проектные классы или классы анализа. Присутствующие на диаграмме классы анализа следует замаскировать (Ctrl+M), а отсутствующие проектные классы и их связи переместить из браузера. Удалите из модели ассоциации между проектными классами OrderController и Customer, между OrderController и ArticleOfFurniture. В проектной модели они напрямую не связаны, их разделяет/соединяет интерфейс IDBAccess. Удалите с диаграммы (но не из модели! -- Ctrl+M) класс ArticleOfFurniture. Добавьте интерфейс IDBAccess из браузера на диаграмму (см. рис. 5.2.12). Перетащите из браузера его зависимости на диаграмму. Проведите уточнение связей. OrderController использует интерфейс, для этого в нём хранится ссылка на экземпляр класса, реализующего этот интерфейс. На диаграмме этот факт отображается агрегацией к интерфейсу. OrderController также хранит ссылку на текущий заказ (вкладка Element, поле Association type = Aggregation). Укажите направления ассоциаций (поле Navigable). Обратите внимание на двунаправленную ассоциацию (со стрелкам на обоих концах). В заказе хранится ссылка на заказчика, и каждый заказчик хранит массив ссылок на свои заказы.

Рис. 5.2.12. Уточнённая диаграмма классов VOPC CRUD Orders

      Рис. 5.2.12. Уточнённая диаграмма классов VOPC CRUD Orders

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

      Осуществим проектирование базы данных. В корне Design Model создайте пакет Database Schema со стереотипом <<schema>>. Создайте в нём диаграмму классов DataBase Schema. Создайте 3 класса со стереотипом <<table>>. См. рисунок 5.2.13. Эту схему можно использовать для хранения экземпляров класса Order, экземпляров класса ArticleOfFurniture, их составных частей и соединений. Таблица с записями о заказах состоит из 6 столбцов, один из которых является первичным ключом (<<pk>>). Столбцы для хранения выводимых атрибутов можно не заводить. Как "операция" таблицы TableOrder моделируется ограничение первичного ключа. Позиции заказа хранятся в отдельной таблице TableOrderItem. В этой таблице 5 столбцов, один из которых является частью первичного ключа (<<pk>>), а другой -- внешним ключом (<<fk>>) и частью первичного ключа. В таблицу добавлены ограничения первичного и внешнего ключа и ограничение индекса. Связь между таблицами TableOrder и TableOrderItem идентифицирующая, так как в таблице TableOrderItem внешний ключ orderID входит в составной первичный ключ <number, orderID>. Сведения о заказываемых предметах мебели хранятся в таблице TableArticleOfFurniture. В ней два столбца, один из которых является ключом. Связь этой таблицы с таблицей TableOrderItem не идентифицирующая, так как в таблице TableOrderItem внешний ключ articleID не входит в составной первичный ключ <number, orderID>.

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

Рис. 5.2.13. Диаграмма классов DataBase Schema

      Рис. 5.2.13. Диаграмма классов DataBase Schema

      Если возникают трудности с добавлением стереотипов <<identifying>> и <<non identifying>> связям между таблицами, попытайтесь применить следующие советы. Если стереотипы присутствуют в модели, но при их назначении связи возникает ошибка, удалите стереотипы. Узнать, присутствуют ли стереотипы, можно, настроив браузер. В верхней строке браузера расположены пиктограммы (стрелки, домик, ...). Найдите пиктограмму со всплывающей подсказкой View Menu (треугольник с вершиной вниз). Нажмите её, Show Options -> Show MDA Model. В дереве проекта станет виден модуль LocalModule с профилем внутри. Откройте профиль для просмотра списка стереотипов. Если стереотипы в модели отсутствуют, с помощью пункта контекстного меню проекта (корневого элемента дерева проекта) Create stereotype создайте стереотип <<identifying>> для метакласса Feature (<<non identifying>> -- аналогично). После этого может получиться добавить стереотип связи. Если не получилось, экспортируйте проект в архив и вышлите на электронную почту по адресу, указанному внизу страницы.

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

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


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

  

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

Обновлено: 17.12.2013