
- •Часть 1 13
- •Глава 1 14
- •Глава 2 29
- •Часть 2 36
- •Глава 3 37
- •5.6 Заключение 86
- •Глава 6 87
- •6.4 Заключение 108
- •Глава 7 108
- •7.9 Заключение 129
- •Глава 8 130
- •8.7 Заключение 155
- •Глава 9 157
- •9.6 Заключение 176
- •Глава 10 178
- •10.10 Заключение 194
- •Глава 11 195
- •11.4 Заключение 218
- •Глава 12 220
- •14.5 Заключение 246
- •Часть 4 246
- •Глава 15 247
- •3.1 Документы 251
- •Часть 1 Обзор
- •Глава 1
- •1.1 Определение Требования и Заинтересованного Лица
- •1.2 Пирамида Требований
- •1.3 Трассировка (Связь) между Требованиями
- •1.4 Характеристики Хорошего Требования
- •1.5 Обзор Процесса Управления Требованиями
- •Глава 3 «Формирование Плана Управления Требованиями» детально описывает все эти пункты.
- •Глава 8 «Дополнительная Спецификация» детально описывает этот тип требований.
- •1.6 Заключение
- •Глава 2
- •2.1 Интерфейс
- •Окно Проводника Панель Инструментов Область Представлений Описание
- •Views (Область Представлений)
- •2.2 Рабочее Пространство Word
- •2.3 Документы
- •2.4 Требования
- •2.5 Заключение
- •Часть 2
- •Глава 3
- •3.1 Когда Создается Документ rmp
- •3.2 Решения, Которые Могут Быть Оформлены в Документе rmp
- •Глава 1 «Управление Требованиями» перечисляет решения, которые должны быть приняты при создании документа rmp. В следующих пунктах мы обсудим каждое решение и влияющие на него факторы.
- •Глава 12 «Документация» содержит более детальное описание документов, которые, возможно, будет необходимо создать.
- •3.4 Заключение
- •Глава 4
- •4.3 Заключение
- •Глава 5
- •5.6 Заключение
- •Глава 6
- •6.4 Заключение
- •Глава 7
- •7.9 Заключение
- •Глава 8
- •Время ответа
- •Время обработки
- •Число одновременных пользователей
- •Время обработки отчета
- •8.7 Заключение
- •Глава 9
- •9.6 Заключение
- •Глава 10
- •10.10 Заключение
- •Глава 11
- •11.4 Заключение
- •Глава 12
- •12.4 Заключение
- •Часть 3
- •Глава 13
- •13.6 Заключение
- •Глава 14
- •14.5 Заключение
- •Часть 4
- •Заключение
- •Глава 15
- •3.1 Документы
10.10 Заключение
Эта глава представляет восемь методов извлечения тестовых сценариев (test cases) из дополнительных требований. В большинстве случаев мы имели дело с нефункциональными требованиями. Дополнительные требования бывают довольно разными, также как и тип. Поэтому не существует универсального метода для их тестирования. Нам нужно выбирать соответствующий подход для каждого требования.
Использование автоматического тестирования - очень хорошая помощь при тестировании требований производительности и надежности. Представленный в пункте 10.9. пример – это простой случай записи сессий IBM Rational Robot и запуска их для требуемого числа виртуальных пользователей. Более углубленное использование Robot включает настройку типа записей в зависимости от архитектуры системы, характеристик генерации скриптов, использование хранилищ данных, а также изменение записанных скриптов вручную. Инструменты автоматического тестирования также полезны при выполнении функциональных тестовых сценариев, как описано в предыдущей главе. И если функциональное тестирование может быть выполнено вручную, то выполнить тестирование производительности без этих инструментов практически невозможно.
Тестовые сценарии должны быть приготовлены достаточно рано в проекте, потому что их создание может породить некоторые вопросы, которые помогут улучшить требования. Однако фактическое тестирование начинается только после того, как некоторая часть системы уже спроектирована и разработана. Следующая глава рассматривает порядок проектирования.
Ссылки
[IBM03a] Rational Robot, User’s Guide, IBM Corporation, 2003.
[IBM03b] Rational Test Manager, User’s Guide, IBM Corporation, 2003.
Глава 11
Объектно-Ориентированное
Проектирование
Данная глава описывает, каким образом собранные до настоящего момента требования могут выступать в качестве основы для объектно-ориентированного проектирования системы. Существует много подходов к проектированию, и в этой главе описан один из таких подходов. Рассмотренный в данной главе подход является общим и может применяться независимо от архитектуры системы и языка реализации. Тем не менее, такое высокоуровневое проектирование должно быть усовершенствовано с учетом взятия во внимание языка программирования и архитектуры системы.
Рисунок 11.1. представляет высокоуровневое видение данного подхода. Для каждого сценария мы создаем одну диаграмму последовательностей. Одновременно с созданием диаграмм последовательностей мы создаем классы, которые содержат в себе требуемую функциональность. Классы, их атрибуты и операции, а также отношения между классами, отображаются на диаграмме классов.
Пункты 11.2 и 11.3 показывают, каким образом для проектирования можно использовать два инструмента IBM: Rational Rose и Rational Software Architect.
Рисунок 11.1. Создание диаграмм проектирования из сценариев.
11.1 Проектирование Системы из Сценариев Использования (Use Case)
Проектирование может быть выполнено с использованием Универсального Языка Моделирования - Unified Model Language (UML) – графического языка моделирования, который использует специальную систему обозначений для создания абстрактной модели системы [BOO04] [BOO05].
Основная задача данного метода - это создание диаграммы последовательностей для каждого сценария. Одновременно с этим осуществляется формирование классов, а отношения между классами показываются на диаграмме классов.
При проектировании диаграммы взаимодействий сообщения от действующего лица (actor) должны идти в класс представления пользовательского интерфейса (boundary-class). Boundary-класс затем передает сообщения в controller-class, который впоследствии взаимодействует с определенными классами-сущностями (entity-классы).
Мы будем придерживаться следующей последовательности шагов для каждого сценария:
Получить пару шагов сценария: запрос пользователя и ответ системы.
Решить, какой boundary-класс будет обеспечивать взаимодействие с действующими лицами.
Создать название для операции, которая будет позволять действующему лицу передавать входные значения системе.
Разработать аргументы для этой операции. Обычно, на экране для каждого элемента управления пользовательского интерфейса (UI control) существует один аргумент. Например, текстовая переменная может представлять поле для ввода, а Булева переменная может представлять radio-button или checkbox.
Решить, какая controller-операция должна обеспечить эту функциональность.
Решить, какой controller-класс должен предоставить данную операцию (взять из существующих классов или создать новый).
Разработать аргументы и возвращаемое значение операции (если необходимо, создать новые entity-классы).
Если необходимо, создать в boundary-классе операцию, которая отображает на экране информацию, полученную от controller-класса.
Продолжить выполнение этих пунктов для следующих шагов сценария.
В качестве примера рассмотрим основной алгоритм (Basic Flow) сценария использования Бронирование рейса.
Мы можем пропустить первые два шага, потому что данная функциональность предоставляется не нашим приложением, а Интернетом и браузером.
В1. Турист (Traveler) вводит URL сайта.
В2. Система отображает домашнюю страницу сайта.
Следующие два шага предоставляют список рейсов согласно данным по аэропортам вылета и прибытия, а также даты и количество пассажиров.
В3. Турист вводит:
Аэропорт вылета, дату вылета.
Аэропорт прибытия, дату возвращения.
Количество путешествующих с ним взрослых и детей.
Турист выбирает «Найти рейсы».
В4. Система отображает рейсы вылета, отсортированные по цене.
Создадим класс FlightReservationForm, который будет включать функциональность пользовательского интерфейса, относящуюся к этим шагам сценария. В UML класс представляется в виде прямоугольника с тремя ячейками:
Верхняя ячейка содержит название класса.
Средняя ячейка содержит атрибуты.
Нижняя ячейка содержит операции.
Класс FlightReservationForm не имеет атрибутов. Первая операция – это getOutboundFlights, как показано на Рисунке 11.2.
Рисунок 11.2. Представление класса с помощью UML.
Довольно часто аргументы создаваемой операции состоят из предоставленных пользователем переменных. Операция getOutboundFlights имеет следующие аргументы:
Аэропорт вылета (departure airport).
Аэропорт прибытия (arrival airport).
Дата вылета (departure date).
Дата возвращения (return date).
Количество путешествующих взрослых (number of traveling adults).
Количество путешествующих детей (number of traveling children).
На данном этапе мы должны подумать о том, обладает ли система всей информацией, требуемой для выполнения операции. Например, как система будет определять, нужен ли нам билет в один конец, либо же билет до пункта назначения и обратно? Мы можем создать правило: если Турист не указал дату возвращения, то ему или ей нужен билет в один конец. В операции класса мы не можем просто пропустить аргумент, но мы можем установить соглашение, что если дата получена в формате 01/01/0001, то это означает, что Турист не ввел дату, а значит, не указал рейс обратно. Другим вариантом может быть добавление Булевого аргумента returnFlag, указывающего, существует ли рейс обратно.
Мы можем показать аргументы на UML-диаграмме, но такое отображение делает класс очень широким, как показано на Рисунке 11.3.
Рисунок 11.3. Отображение сигнатуры операции на диаграмме классов.
Как только у нас появилась операция boundary-класса, нам стало необходимо разработать операцию controller-класса, которая будет снабжать boundary-класс необходимой информацией.
Назовем эту операцию getFlights, а controller-класс, предоставляющий данную операцию, FlightSelector. Аргументы операции getFlights класса FlightSelector будут такими же, как и у операции getOutboundFlights из класса FlightReservationForm. Почему мы называем одну операцию getOutboundFlights, в то время как название другой – getFlights? Потому что функциональность controller-класса та же самая: независимо от того, являются ли запрашиваемые рейсы вылетами или рейсами возвращения, необходимо возвращать список рейсов на основании некоторых входных атрибутов. Тем не менее, функциональность boundary-класса немного отличается в отношении рейсов вылета и возвращения, т.к. пользовательский интерфейс немного различен в этих двух случаях.
Сейчас нам нужно определить entity-классы, которые будут использоваться для возвращения информации о рейсе. Поместим всю информацию относительно рейсов в класс Flight. Атрибутами этого класса будут:
|
|
|
|
|
|
Так как ни один из атрибутов однозначно не идентифицирует рейс, мы можем добавить дополнительный атрибут под названием flightId. В целях улучшения производительности системы лучше определить его как Integer, чем как String. При разработке нашего класса Flight мы имеем в виду полную связь между аэропортом вылета и пунктом назначения. Однако если это не прямой рейс, то он будет состоять из нескольких отрезков пути с остановками между ними. Рейс будет содержать один или более отрезков пути. В объектно-ориентированном проектировании это называется агрегацией. Рисунок 11.4. показывает UML-представление классов Flight и FlightLeg, а также их агрегацию. Класс FlightLeg содержит атрибуты, подобные атрибутам класса Flight, но они описывают отдельные отрезки пути. Вдобавок он содержит Airline (название авиалиний) и FlightNumber (номер рейса), используемый этими авиалиниями для идентификации рейса.
Рисунок 11.4. Агрегация классов Flight и FlightLeg.
Для этих классов нам также необходимо добавить атрибут flightLegId (идентификатор отрезка пути). FlightNumber однозначно не идентифицирует рейс, потому что в разные дни могут быть рейсы с одним и тем же номером. Другой подход заключается в использовании пары атрибутов Flight Number и Departure Date, но использование двух атрибутов для идентификации менее удобно.
У классов Flight и FlightLeg есть некоторые атрибуты, но нет операций. Ситуация, когда одна из ячеек класса пуста, является достаточно распространенной. У entity-классов есть атрибуты, но нет операций, а у controller-классов есть операции, но нет атрибутов.
Так как мы ожидаем, что в результате поиска будет найдено большое количество рейсов, объект, возвращаемый функцией getFlights, будет представлять собой список объектов Flight. Мы можем определить новый класс ListOfFlights. На UML диаграмме мы можем показать, что ListOfFlights содержит ноль или более объектов класса Flight, как показано на рисунке 11.5. Берется множество от 0 до n, т.к. список может быть пустым.
Рисунок 11.5. ListOfFlights содержит в себе несколько рейсов.
После того как мы сформировали классы Flights и ListOfFlights, а также части классов FlightReservationForm и FlightSelector, мы можем отобразить шаг сценария (относительно поиска) на диаграмме последовательностей, как показано на Рисунке 11.6. На диаграмме последовательностей мы показываем сообщения, посылаемые между объектами. Пунктирная линия, идущая вниз от каждого объекта, называется линией жизни (lifeline).
Boundary-класс FlightReservationForm на данной диаграмме представляет пользовательский интерфейс, или клиентскую часть, которая взаимодействует с действующим лицом. Controller-класс FlightSelector представляет серверную часть приложения. Реализация этих классов зависит от архитектуры системы.
Рисунок 11.6. Диаграмма последовательностей, показывающая вызов операции getOutboundFlights класса FlightReservationForm и операции getFlights класса FlightSelector.
Как только FlightReservationForm получает список рейсов от FlightSelector, он отображает его на экране. Для этого мы можем определить возвратную операцию displayOutboundFlights. Значение, возвращаемое этой операцией, может быть Булевым, показывающим, было ли успешным выполнение операции или нет.
Иногда нам необходимо более чем одна controller-операция для реализации требуемой функциональности. В нашей системе одним из требований было то, что помимо кода аэропорта, система будет распознавать пары наименований город/штат или город/страна. Чтобы смоделировать данную функциональность, мы можем ввести класс AirportController с операцией getAirportCode (town, location). Почему мы не называем этот класс AirportCodeResolver? Потому что в будущем мы можем использовать этот же класс для поиска расположенных рядом аэропортов или каких-либо других операций, связанных с аэропортами. Более общее название обеспечивает нам гибкость в применении
Если строка, описывающая аэропорт в аргументе операции getFlights – не трехзначный код аэропорта, то FlightSelector полагает, что он содержит пару наименований город/штат или город/страна. Он также передает этот аргумент классу AirportController, который возвращает код аэропорта на основании входных переменных (см. Рисунок 11.7).
Рисунок 11.7. FlightSelector вызывает операцию getAirportCode класса AirportController.
Как только мы закончили с моделированием шагов В3 и В4, мы можем перейти к следующим шагам:
В5. Турист выбирает рейс.
В6. Система отображает рейсы возвращения.
Операция boundary-класса, обеспечивающая данную функциональность, может быть названа selectOutboundFlight, а ее аргументами будут:
flightId: Идентификатор (ID) выбранного рейса вылета.
airport: Аэропорт посадки для рейса возвращения.
date: Дата рейсов возвращения.
Возвращаемое значение – набор объектов Flight.
Для получения списка рейсов возвращения мы можем использовать уже определенную операцию getFlights класса FlightSelector. Так как отображение рейсов возвращения на экране требует немного иной функциональности, чем отображение вылетов, нам необходимо определить другую операцию boundary-класса displayReturnFlights. Мы можем добавить три новых сообщения в диаграмму последовательностей, как показано на рисунке 11.8.
Рисунок 11.8. Диаграмма последовательностей после добавления сообщения getReturnFlights.
Рассмотрим два следующих шага сценария:
В7. Турист выбирает рейс возвращения.
В8. Система отображает детали рейса.
Операция boundary-класса может быть названа selectReturnFlight.
Теперь нам нужна controller-операция, которая возвращает детали рейса на основании flightId:
Название операции: getFlightDetails.
Аргумент: flightId.
Возвращаемое значение: Flight.
Класс, выполняющий данную операцию: FlightSelector.
Мы добавляем операцию getFlightDetails к классу FlightSelector, а также добавляем соответствующие сообщения в диаграмму последовательностей. Так как нам необходимы детали рейсов вылета и возвращения, у нас будут два различных вызова этой операции. Операция boundary-класса, отображающая детали рейсов обоих типов, будет называться displayFlightDetails (см. Рисунок 11.9).
Рисунок 11.9. Диаграмма последовательностей после добавления сообщений selectReturnFlight, getFlightDetails и displayFlightDetails.
Так как шаг В10 не является ответом системы на шаг В9, мы возьмем только один шаг для формирования следующей операции:
В9. Турист подтверждает рейс.
Операция boundary-класса называется confirmFlight, а ее аргументы включают идентификаторы для обоих типов рейсов.
До настоящего времени мы получали информацию о доступных рейсах. Сейчас мы хотим начать фактическое бронирование рейсов. Мы можем сгруппировать всю функциональность, относящуюся к бронированию, в отдельный controller-класс BookingSystem. Каким образом разделить функциональность между классами – будет решать дизайнер системы. В нашем случае мы бы могли рассмотреть комбинирование функциональности классов FlightSelector и BookingSystem в один большой класс FlightController. Однако этот класс был бы очень большим и обеспечивал бы довольно обширную функциональность.
Создадим класс BookingSystem и добавим операцию bookFlight, которая будет иметь в качестве аргументов идентификаторы двух типов рейсов – один для рейса вылета и один для рейса возвращения. Если мы бронируем билет в один конец, второй аргумент будет нулевым. Операция возвращает reservationNumber. Нам понадобится этот ID в будущем. Рисунок 11.10. показывает начальное представление этого класса. Позже нам будет нужно больше операций.
Рисунок 11.10. Начальное представление класса BookingSystem (была добавлена только одна операция).
Следующий шаг также берется отдельно для формирования операции:
В10. Турист предоставляет свой идентификатор и пароль для покупки билета.
Наиболее удобным будет вынести все функции идентификации пользователя в системе в отдельный объект, такой как LoginController (см. Рисунок 11.11). Он будет содержать функциональность, относящуюся к смене паролей, восстановления забытых паролей и т.д. Операция Login будет иметь идентификатор пользователя (userid) и пароль (password) в качестве аргументов. Возвращаемое значение – Булево, подтверждающее, была ли идентификация успешна. Соответствующая функция boundary-класса может называться также - login.
Рисунок 11.11. Класс LoginController.
Следующие два шага сценария:
В11. Турист предоставляет информацию пассажира.
В12. Система отображает доступные места.
Эти два шага фактически не относятся друг к другу. Даже если отображение мест на экране выступает в качестве ответа на предоставление информации пассажира, лучше разделить эти две функциональности на две отельные операции. Это обеспечивает большую гибкость в применении в случае, если мы хотим изменить ход процесса в будущем.
В первую очередь, boundary-класс вызывает данную операцию для отображения PassengerDataRequest.
Чтобы принять информацию пассажира, boundary-класс, как и controller-класс BookingSystem, должен иметь операцию setPassengerData, которая берет объект Passenger в качестве аргумента. Объект Passenger содержит следующие атрибуты:
|
|
|
|
|
|
|
|
|
|
Рисунок 11.12. показывает представление этого класса с помощью UML.
Рисунок 11.12. Класс Passenger.
Помимо объекта Passenger операция setPassengerData должна содержать второй аргумент, определяющий reservation ID, чтобы система корректно присваивала эти данные определенному заказу. Операция может быть вызвана много раз, в зависимости от того, как много пассажиров путешествует.
Для шага В12 операция boundary-класса и соответствующая операция controller-класса – это getAvailableSeats. Ее аргумент – flightId. Она возвращает список номеров доступных мест. Controller-операция предоставляется классом BookingSystem. Когда boundary-класс получает список мест от controller-класса, она вызывает операцию displayAvailableSeats.
После того как турист получает список доступных мест мы должны смоделировать способ сообщить системе, какие места Турист выбрал:
В13. Турист выбирает места.
Место, выбранное туристом, передается в boundary-класс с помощью операции selectSeat, а затем перенаправляется в BookingSystem класс с использованием той же операции. Эта операция содержит три аргумента: reservationNumber (номер заказа), passengerId (идентификатор пассажира) и seatNumber (номер места). Переменная seatNumber имеет тип String вместо Integer, потому что места в самолете обычно обозначаются комбинацией цифр и букв, например: 5А, 5В, 5С. Возвращаемое значение в данном случае неважно. Она может возвращать итоговый код, указывающий, была ли операция закончена успешно.
Операция вызывается количество раз, равное количеству пассажиров.
Внутренне информация о заказе может храниться в объекте Reservation со следующими атрибутами:
Номер заказа (reservationNumber).
Идентификатор клиента (customerId, может быть идентичным идентификатору делающего заказ пользователя).
Идентификатор рейса вылета (outboundFlightId).
Идентификатор рейса возвращения (returnFlightId).
Этот класс связан с одним или несколькими объектами FlightLegReservation, которые присваивают определенный номер места паре FlightLeg/Passenger, как показано на Рисунке 11.13.
Рисунок 11.13. Класс Reservation и связанные с ним классы.
Следующие два шага обрабатывают информацию, необходимую для осуществления платежей:
В14. Турист предоставляет информацию о его кредитной карте и расчетный адрес.
В15. Система предоставляет номер подтверждения.
Функции оплаты могут поддерживаться отдельным классом PaymentProcessor. Этот класс внутренне использует связь с системами расчета большинства кредитных карт. С точки зрения интерфейса, у класса есть метод submitPayment, который содержит объект Payment в качестве аргумента. Этот объект содержит следующие атрибуты:
Номер кредитной карты (credit card number).
Дата окончания срока действия (expiration date).
Наименования компании, обслуживающей кредитную карту (cardholder name).
Расчетный адрес (billing address) .
Класс FlightReservationForm и класс BookingSystem также содержат операцию submitPayment. Однако у этой операции есть дополнительный аргумент – reservationId (идентификатор заказа), так что BookingSystem знает, какой именно заказ был оплачен. Когда вызывается операция submitPayment класса BookingSystem, фактически вызывается операция submitPayment класса PaymentProcessor. Для разных классов вполне нормально иметь операции с одинаковыми названиями. (У нас уже есть операции с одинаковыми именами в boundary-классе и controller-классе).
После прохождения всех шагов основного алгоритма сценария Бронирование рейса наша диаграмма классов может выглядеть так, как показано на Рисунке 11.14. Вторая часть диаграммы последовательностей показана на Рисунке 11.15. (первая часть была показана на Рисунке 11.9).
Рассмотренный подход предполагает одновременное создание классов и диаграммы последовательностей. Некоторые дизайнеры предпочитают сначала создавать диаграммы сотрудничества, а затем уже формировать детали классов. В этом случае, когда мы присваиваем название сообщению, это сообщение еще не определено в классе, так что мы не можем просто выбрать его из списка. Нам нужно создать место метку для этого сообщения. Для отличия метки от фактических сообщений, мы можем добавить знак комментария «//» перед названием и написать название в простой форме (допускается использование пробелов). Например: //get outbound flights (см. Рисунок 11.16). После того, как мы определили эту операцию в классе, мы заменяем метку фактической операцией. Преимущество подхода, при котором в первую очередь создаются фактические операции для диаграммы классов, заключается в том, что нам не нужно беспокоиться о подобных заменах в будущем.
Рисунок 11.14. Диаграмма классов, показывающая классы, реализующие функциональность основного алгоритма сценария Бронирование рейса.
Рисунок 11.15. Диаграмма последовательностей, представляющая основной алгоритм сценария Бронирование рейса.
Рисунок 11.16. Диаграмма последовательностей, представляющая первые две операции основного алгоритма сценария Бронирование рейса, с комментариями вместо актуальных имен операций.
11.2 Использование IBM Rational Rose для Проектирования
IBM Rational Rose - это инструмент, обеспечивающий очень удобный подход к объектно-ориентированному проектированию, с использованием UML [IBM03c]. Данный пункт описывает, каким образом можно осуществлять проектирование, описанное в предыдущем пункте, используя Rational Rose.
Создание Новой Модели
Для создания новой модели Rational Rose выполните следующие действия:
Откройте Rational Rose (выберите Start>All Programs>Rational Software>Rational Rose (Пуск>Все программы>Rational Software>Rational Rose).
В диалоговом окне Create New Model (Создать Новую Модель) нажмите кнопку Cancel - Отмена (для загрузки настроек по умолчанию).
Определите название модели, нажав File>Save As (Файл>Сохранить как), выбирая директорию и вводя наименование.
Левая панель отображает браузер, как показано на Рисунке 11.17.
Рисунок 11.17. Окно браузера IBM Rational Rose.
Создание Диаграммы Классов
На панели диаграмм Вы можете открыть несколько окон с диаграммами. При запуске приложения должно открыться окно диаграммы классов, установленное по умолчанию. Оно называется «Class Diagram: Logical View/Main». Вы можете выбрать это окно или создать новое окно диаграммы классов. Для создания нового окна выполните следующие действия:
Нажмите правой кнопкой мышки на Logical View и выберите New>Class Diagram (Новая>Диаграмма Классов).
Дайте название диаграмме, например Booking Flight (Бронирование рейса).
Двойным щелчком мышки на диаграмме (в окне браузера) откройте окно на главной панели.
Между панелью браузера и панелью диаграмм расположена вертикальная панель инструментов, как показано на Рисунке 1.18. Чтобы поместить нужный элемент на диаграмму, Вам нужно нажать на иконку на данной панели инструментов, а затем нажать на нужное место на диаграмме, где Вы хотите поместить данный элемент.
Рисунок 11.18. Панель инструментов для диаграммы классов.
Создайте класс на диаграмме, выполняя следующие действия:
Нажмите на иконку класса на панели инструментов (пятая иконка сверху).
Нажмите на окно Class Diagram (Диаграмма Классов), чтобы поместить на него иконку.
Класс появляется с названием NewClass.
Двойным щелчком мышки на данном классе откройте диалоговое окно Class Specification (Характеристика Класса), как показано на Рисунке 11.19.
Измените название класса, например FlightSelector.
Введите описание класса в области Documentation (Документация).
Выберите закладку Operation (Операция).
Правой кнопкой мышки нажмите на главной панели диалогового окна и выберите Insert (Вставить).
Назовите операцию, например getFlights. Когда Вы нажмете Enter, операция будет добавлена в список.
Рисунок 11.19. Диалоговое окно Class Specification (Характеристика Класса).
Двойным щелчком мышки нажмите на названии операции.
Выберите закладку Detail (Детали), как показано на Рисунке 11.20.
Рисунок 11.20. Добавление аргументов операции.
Правой кнопкой мышки нажмите на текстовом поле Argument (Аргумент) и выберите Insert (Вставить).
Назовите атрибут, например departureAirport.
Нажмите Tab для помещения курсора под столбцом Type (Тип). Появляется поле со списком доступных типов.
Выберите из списка тип атрибута, например String.
Продолжите добавление всех аргументов.
Правой кнопкой мышки нажмите на классе и выберите Option>Show operations signature (Опции>Показать сигнатуру операций).
Для создания класса Flight выполните следующие действия:
Нажмите на иконку класса на панели инструментов.
Нажмите на окне Class Diagram (Диаграмма Классов).
Класс появляется с названием NewClass.
Двойным щелчком мышки на классе откройте диалоговое окно Class Specification (Характеристика Класса), как показано на Рисунке 11.21.
Рисунок 11.21. Атрибуты класса.
Измените название класса на Flight.
Введите начальное описание класса в области Documentation (Документация).
Выберите закладку Attribute (Атрибут).
Правой кнопкой мышки нажмите на главной панели диалогового окна и выберите Insert (Вставить).
Назовите атрибут, например flightId.
Двойным щелчком мышки нажмите на столбце Type (Тип).
Выберите из списка тип атрибута, например String.
Продолжите добавление всех аргументов.
Выполняйте эти действия для добавления классов FlightReservationForm, FlightLeg и других классов, сформированных в предыдущем пункте.
Формирование Взаимосвязей
Предположим, что мы создали классы Flight и FlightLeg. Теперь мы хотим создать связь, показывающую агрегацию этих классов. Для создания соответствующего типа связи нам нужно соединить их с помощью дуги связи, двойным щелчком мышки нажать на дуге между классами и установить некоторое значение в диалоговом окне Association Specification (Характеристики Связи):
Выберите иконку связи на панели инструментов.
Нажмите на класс Flight.
Перетащите конец связи на класс FlightLeg.
Двойным щелчком мышки на связи между Flight и FlightLeg откройте диалоговое окно Association Specification (Характеристики Связи), как показано на Рисунке 11.22.
Рисунок 11.22. Определение деталей роли.
Выберите закладку Role B Detail (Детали Роли В).
Выберите Multiplicity 1 (Множественность).
Выберите галочку Aggregate (Агрегация). После выбора данной галочки при последующем открытии этого диалогового окна его название будет изменено с Association Specification (Характеристики Связи) на Aggregation Specification (Характеристики Агрегации), как показано на Рисунке 11.22.
Поставьте переключатель в By Reference (По Ссылке), чтобы определить Containment (Ячейки) класса FlightLeg.
Выберите закладку Role A Detail (Детали Роли А).
Выберите 1…n из списка Multiplicity (Множественность).
Нажмите ОК.
После создания этой связи экран приложения должен выглядеть так, как показано на Рисунке 11.23.
Рисунок 11.23. Диаграмма классов, созданная в IBM Rational Rose.
Создание Диаграммы Последовательностей
Прежде чем создать диаграмму последовательностей мы должны создать пользователей, взаимодействующих со сценарием, который относится к этой диаграмме (помимо того что мы уже сделали при создании диаграммы сценариев).
Правой кнопкой мышки нажмите на Logical View и выберите New>Sequence Diagram (Новая>Диаграмма Последовательностей).
Правой кнопкой мышки нажмите на Use Case Package (Папка Сценариев Использования) и выберите New>Actor (Новое>Действующее Лицо).
Дайте название действующему лицу, например Traveler (Турист).
Для создания диаграммы последовательностей выполните следующие действия:
Выберите и перетащите мышкой действующее лицо на главное окно.
Нажмите на иконку класса на вертикальной панели инструментов.
Нажмите на главном окне, чтобы поместить туда класс.
Двойным щелчком мышки на классе откройте диалоговое окно Object Specification (Характеристики Объекта), как показано на Рисунке 11.24.
Рисунок 11.24. Выбор названия класса из списка определенных классов.
Выберите FlightReservationForm из списка Class (Классы).
Нажмите на иконке Object Message (Сообщение Объекта) на вертикальной панели инструментов.
Соедините линию жизни Туриста с линией жизни FlightReservationForm.
Двойным щелчком мышки на сообщении откройте диалоговое окно Message Specification (Характеристики Сообщения), как показано на Рисунке 11.25.
Выберите метод getOutboundFlights из списка Name (Название).
Нажмите ОК.
Рисунок 11.25. Выбор названия сообщения из списка доступных операций.
После этих действий экран приложения должен выглядеть так, как показано на Рисунке 11.26.
Рисунок 11.26. Диаграмма последовательностей, созданная в IBM Rational Rose.
11.3 Использование IBM Rational Software Architect для Проектирования
IBM Rational Software Architect – это встроенный инструмент для проектирования и разработки программных проектов. Он соединяет в себе функциональность Rational Software Modeler, инструмента для моделирования с использованием UML и Rational Application Developer (среда разработки J2EE). В этом пункте Вы научитесь, как создавать проект, сценарий использования (use case), класс и диаграмму последовательностей.
Создание Проекта
Для создания проекта выполните следующие действия:
Запустите программу, выбрав Start>Programs>IBM Rational>IBM Rational Software Architect v.6.0>Rational Software Architect (выбрав Пуск>Программы>IBM Rational>IBM Rational Software Architect v.6.0>Rational Software Architect).
В диалоговом окне Workspace Launcher (Модуль Установки Рабочего Пространства), как показано на Рисунке 11.27, нажмите кнопку ОК для подтверждения установленной по умолчанию рабочей директории.
Рисунок 11.27. Диалоговое окно Workspace Launcher (Модель Установки Рабочего Пространства).
Выберите File>New>Project (Файл>Новый>Проект).
В диалоговом окне New Project (Новый Проект), как показано на Рисунке 11.28, выделите UML Project и нажмите кнопку Next (Далее).
Рисунок 11.28. Диалоговое окно New Project (Новый Проект).
Введите название проекта, как показано на Рисунке 11.29, и нажмите на кнопку Next (Далее).
Рисунок 11.29. Выбор названия проекта в диалоговом окне UML Modeling Project (Моделирование Проекта UML).
Введите название файла модели UML, оставьте выделенным Blank Model, уберите выделение галочки «Create a default diagram in the new model» (Создать диаграмму по умолчанию в новой модели) и нажмите кнопку Finish (Закончить). (см. Рисунок 11.30).
Рисунок 11.30. Выбор деталей проекта в диалоговом окне UML Modeling Project (Моделирование Проекта UML).
Откроется рабочее пространство с пустой моделью, как показано на Рисунке 11.31.
Рисунок 11.31. Рабочее пространство с UML modeling project (проектом, смоделированным с помощью UML).
Создание Диаграммы Сценариев
Создадим диаграмму сценариев:
Нажмите правой кнопкой мышки на Online Travel Agency Model (Модель Он-лайн Агентства Путешествий) в Model Explorer (Проводник Моделей, в левой части экрана) и выберите Add Diagram>Use Case Diagram (Добавить Диаграмму>Диаграмма Сценариев).
Измените название Diagram 1, установленное по умолчанию, на имеющее смысл имя.
Нажмите Actor (Действующее Лицо) в меню Palette (Палитра, справа от окна диаграммы) и затем нажмите в любом месте окна диаграммы для создания на ней действующего лица. Замените название Actor 1, установленное по умолчанию, на Traveler (Турист).
Нажмите Use Case (Сценарий Использования) в меню Palette (Палитра) и затем нажмите в любом месте окна диаграммы для создания на ней сценария использования. Замените название UseCase 1, установленное по умолчанию, на Book a flight (Бронирование рейса).
Нажмите Associations (Связи) в меню Palette (Палитра). Нарисуйте линию связей от действующего лица к сценарию использования, как показано на Рисунке 11.32.
Рисунок 11.32. Создание диаграммы сценариев с помощью IBM Rational Software Architect.
Продолжайте добавление действующих лиц, сценариев и связей.
Нажмите Ctrl+S для сохранения диаграммы.
Создание Диаграммы Классов
Вы можете создать диаграмму классов, выполняя следующие действия:
Нажмите правой кнопкой мышки на Online Travel Agency Model (Модель Он-лайн Агентства Путешествий) в Model Explorer (Проводник Моделей) и выберите Add Diagram>Class Diagram (Добавить Диаграмму>Диаграмма Классов).
Измените название Diagram 1, установленное по умолчанию, на имеющее смысл имя.
Выберите Class (Класс) в меню Palette (Палитра) и затем нажмите в любом месте окна диаграммы для создания на ней класса.
Замените название Class 1, установленное по умолчанию, на FlightReservationForm.
Правой кнопкой мышки нажмите на созданном классе и выберите Add UML>Operation (Добавить UML>Операция) для создания операции этого класса. Назовите ее getOutboundFlights.
Продолжайте добавлять остальные операции класса.
Нажмите Class (Класс) в меню Palette (Палитра) и затем нажмите в любом месте окна диаграммы для создания на ней класса Flight.
Правой кнопкой мышки нажмите на классе Flight и выберите Add UML>Attribute (Добавить UML>Атрибут) для создания атрибута этого класса. Назовите его FlightId.
Двойным щелчком мышки на атрибуте FlightId откройте окно Properties (Свойства) в нижней части экрана.
В окне Properties (Свойства) нажмите Select Type (Выбрать Тип), выберите Integer в диалоговом окне Select Element (Выбрать Элемент), как показано на Рисунке 11.33.
Рисунок 11.33. Выбор типа атрибута.
Продолжайте добавление атрибутов.
Добавьте в диаграмму новый класс ListOfFlights.
Нажмите Assosiations (Связи) в меню Palette (Палитра).
Соедините классы ListOfFlights и Flight.
Двойным щелчком мышки на линии связи откройте окно Properties (Свойства) в нижней части экрана, как показано на Рисунке 11.34.
В списке Type (Тип) окна Properties (Свойства), выберите «1-Aggregation».
Установите Multiplicity (Множественность) роли ListOfFlights равную 1, а Multiplicity роли Flight равную *.
Рисунок 11.34. Создание диаграммы классов с помощью IBM Rational Software Architect.
Создание Диаграммы Последовательностей
Показанная на Рисунке 11.35. Диаграмма последовательностей может быть создана выполнением следующих действий:
Нажмите правой кнопкой мышки на название модели в Model Explorer (Проводник Моделей) и выберите Add Diagram>Sequence Diagram (Добавить Диаграмму>Диаграмма Последовательностей).
Измените название Diagram 1, установленное по умолчанию, на имеющее смысл имя.
Перетащите мышкой Traveler (Турист) из окна Explorer (Проводника) на диаграмму для создания действующего лица.
Перетащите мышкой класс FlightSelector из окна Explorer (Проводника) на диаграмму.
Выберите Asynchronous Message (Асинхронное Сообщение) в Palette (Палитра).
Нажмите на линию под Traveler (Туристом) и перетащите к линии под FlightReservationForm.
Выберите операцию getOutboundFlights из списка.
По аналогии создайте оставшиеся сообщения.
Выберите File>Save All (Файл>Сохранить Все), чтобы сохранить все изменения.
Рисунок 11.35. Создание диаграммы последовательностей в IBM Rational Software Architect.
Публикация Проекта
После того как все необходимые диаграммы были созданы, Вы можете осуществить публикацию всей модели на веб, выполняя следующие действия:
Выделите название модели в Model Explorer (Проводник Моделей).
Выберите Modeling>Publish>Web (Моделирование>Публикация>Web).
В диалоговом окне Publish to Web (Опубликовать на Web), как показано на Рисунке 11.36, задайте местоположение генерируемых HTML файлов и нажмите кнопку ОК.
Рисунок 11.36. Задание местоположения в диалоговом окне Publish to Web (Опубликовать на Web).
Для доступа к опубликованной модели выполните следующее:
Следуйте по пути, который был указан Вами, затем двойным щелчком мышки откройте файл index.html.
Нажмите на ссылку модели, как показано на Рисунке 11.37.
Рисунок 11.37. Первая страница, где Вы выбираете опубликованную модель.
Перемещайтесь по опубликованной модели, нажимая на ссылки элементов и диаграммы, как показано на Рисунке 11.38.
Рисунок 11.38. Диаграмма классов опубликованной модели.