Учебник Технология программирования. Технология программирования
Скачать 7.85 Mb.
|
Диаграммы последовательностей этапа проектирования. Диаграммы последовательностей этапа проектирования отображают взаимодействие объектов, упорядоченное по времени. В отличие от диаграмм последовательности этапа анализа на ней показывают внутренние объекты, а также последовательность сообщений, которыми обмениваются объекты в процессе реализации фрагмента варианта использования, называемого сценарием. Объекты изображают в виде прямоугольников, внутри которого указана информация, идентифицирующая объект: имя, имя объекта и имя класса или только имя класса (рис. 7.6). Каждое сообщение представляют в виде линии со стрелкой, соединяющей линии жизни двух объектов. Эти линии помещают на диаграмму в порядке генерации сообщений (сверху вниз и слева направо). Сообщению присваивают имя, но можно указать и аргументы, и управляющую информацию, например, условие формирования или маркер итерации (*). Возврат при передаче синхронных сообщений подразумевают по умолчанию. Если объект создается сообщением, то его рисуют справа от стрелки сообщения так, чтобы стрелка сообщения входила в него слева. Диаграммы последовательностей также позволяют изображать параллельные процессы. Асинхронные сообщения, которые не блокируют работу вызывающего объекта, показывают половинкой стрелки (рис. 7.7, а). Такие сообщения могут: • создавать новую ветвь процесса; • создавать новый объект (рис. 7.7, б); • устанавливать связь с уже выполняющейся ветвью процесса. На линии жизни в этом случае дополнительно показывают активации, которые обозначаются прямоугольником, наложенным поверх линии жизни (рис. 7.7, в). 194 Уничтожение объекта показывают большим знаком «X» (рис. 7.7, г). При необходимости линию жизни можно прервать, чтобы не уточнять обработку, не связанную с анализируемыми объектами (рис. 7.7, д). Пример 7.3. Разработать диаграмму последовательностей для сценария Решение задачи (фрагмент варианта использования Выполнение задания от момента инициализации пользователем процесса решения до его завершения). Анализ описания варианта использования показывает, что необходимо рассмотреть три варианта последовательности действий: а) нормальный процесс; б) прерывание процесса пользователем; в) возникновение исключения при выполнении алгоритма. Нормальный процесс предполагает, что при выдаче команды Создать создается объект Решение, управляющий данным сценарием. Следующее сообщение Начать активизирует этот объект. Объект Решение запрашивает у объекта класса Задание тип объекта Алгоритм, создает объект требуемого класса и активизирует его, сохраняя способность получать и обрабатывать сообщения (параллельный процесс). Объект класса Алгоритм, реализующий метод, запрашивает у объекта класса Задание данные и начинает обработку, используя вспомогательные объекты. Нормально завершив обработку, объект класса Алгоритм, реализующий метод, передает объекту класса Задание результаты и возвращает объекту Решение признак нормального завершения. Объект Решение уничтожает объект класса Алгоритм, реализующий метод, и возвращает вызвавшему его объекту признак нормального завершения решения (рис. 7.8, а). В случае прерывания процесса объект Решение прерывает процесс решения, уничтожает объект Алгоритм и возвращает признак прерванного выполнения (рис. 7.8, 6). В этом случае при выполнении обработки возникает 195 аварийная ситуация, результатом которой является генерация исключения. Обрабатывая исключение, объект класса Решение, генерирует соответствующее сообщение пользователю, уничтожает объект класса Алгоритм, реализующий метод, и возвращает признак завершения выполнения с ошибкой (рис. 7.9). 196 Диаграмма кооперации. Диаграмма кооперации - это альтернативный способ представления взаимодействия объектов в процессе реализации сценария, который позволяет по-другому взглянуть на ту же информацию. В отличие от диаграмм последовательностей диаграммы кооперации показывают потоки данных между объектами классов, что позволяет уточнить связи между ними. Пример 7.4. Разработать диаграмму кооперации для сценария Процесс решения. Изобразим на одной диаграмме три возможных случая реализации сценария, нумеруя сообщения в порядке их возможной генерации (рис. 7.10). 197 Такое представление позволяет описать потоки данных, передаваемых между объектами классов Решение, Задание и Алгоритм, реализующий метод, для сценария Процесс решения. 7.3. Уточнение отношений классов Процесс проектирования классов начинают с уточнения отношений между ними. На этапе проектирования помимо ассоциации и обобщения различают еще два типа отношения между классами: агрегацию и композицию. К сожалению, до настоящего времени не существует единой устоявшейся терминологии объектно-ориентированного проектирования. В табл. 7.1 приведены соответствия между основными терминами, используемыми наиболее известными авторами в этой области. Агрегацией называют ассоциацию между целым и его частью или частями. Агрегацию вместо ассоциации указывают, если отношение «целое-часть» в конкретном случае существенно. Например, если колесо нас интересует только как часть автомобиля, то между соответствующими классами целесообразно указать отношение агрегации, а если колесо - товар, также как и автомобиль, то связь целое-часть не существенна. Композиция - более сильная разновидность агрегации, которая подразумевает, что объект-часть может принадлежать только единственному целому. Объект-часть при этом создается и уничтожается только вместе со своим целым. Уточненные отношения между классами фиксируют на диаграмме классов. Для этого используют специальные уловные обозначения (рис. 7.11). Поскольку отношение ассоциации и его подвиды (агрегация и композиция) означают наличие обмена сообщениями между объектами классов целе- Таблица 7.1 Нотация Термины UML Класс Ассоциация Обобщение Агрегация Буч Класс Использование Наследование Включение Коал Класс, объект Связь экземпляров Обобщение- специализация Часть-целое Якобсон Объект родства Ассоциация Наследование Состоит из Оделл Тип объекта Связь Подтип Композиция Рамбо Класс Ассоциация Обобщение Агрегация Шлеср/ Меллор Объект Связь Подтип Не определена 198 сообразно уточнить направление передачи сообщений. Навигацию (направление ассоциации) показывают стрелкой на конце линии ассоциации. Если стрелки указаны с обеих сторон, то это означает двунаправленную ассоциацию. Специальное обозначение на диаграмме классов этапа проектирования используют для указания абстрактных классов и методов: на диаграмме классов их имена выделяют курсивом, либо перед именем класса указывают стереотип «abstract». UML также включает специальную нотацию для обозначения параметризованных классов или шаблонов (рис. 7.12, а). Получение из такого класса класса с конкретными типами элементов называют связыванием. Связывание можно обозначить двумя способами: явно указав тип параметра (рис. 7.12, б) и используя условное обозначение уточнения (рис. 7.12, в). Диаграммы классов позволяют также отобразить ограничения, которые невозможно показать, используя только понятия, рассмотренные выше (ассоциации, обобщения, атрибуты, операции). Например, показать, что средний 199 балл студентов должен определяться по соответствующей формуле. Подобную информацию на диаграмме классов можно представить в виде записи на естественном языке или в виде математической формулы, поместив их в фигурные скобки. Особое место в процессе проектирования классов занимает проектирование интерфейсов. Интерфейсы. Интерфейсом в UML называют класс, содержащий только объявление операций. Отдельное описание интерфейсов улучшает технологические качества проектируемого программного обеспечения. Интерфейсы широко применяют при разработке сетевого программного обеспечения, которое должно идентично функционировать в гетерогенных средах, а также для организации взаимодействия с системами управления базами данных и т. п., так как механизм полиморфного наследования позволяет создавать различные реализации одного и того же интерфейса. С точки зрения теории объектно-ориентированного программирования интерфейс представляет собой особый вид абстрактного класса, отличающийся тем, что он не содержит методов, реализующих указанные операции, и объявлений полей. Другими словами, абстрактные классы позволяют определить реализацию некоторых методов, а интерфейсы требуют отложить определение всех методов. На диаграмме классов интерфейс можно показать двумя способами: с помощью специального условного обозначения (рис. 7.13, а) или, объявив для класса стереотип «interface» (рис. 7.13, б). Реализацию интерфейса также можно показать двумя способами: сокращенно (рис. 7.14, а) или, используя отношение реализации (рис. 7.14, б). 200 Для остальных классов, ассоциированных с интерфейсом, следует уточнить ассоциацию, пока зав отношение зависимости. Это отношение в данном случае означает, что класс использует указанный интерфейс (рис. 7.15), т. е. обращается к описанным в интерфейсе функциям. Одновременно с уточнением отношений классов в пакете следует продумать и отношения классов, включенных в различные пакеты, между собой. Пример 7.5. Уточнить отношения классов пакета Объекты задачи между собой и с классом Решение из пакета Объекты управления, используя результаты детализации отношений между объектами рассматриваемых классов. Анализ диаграммы кооперации, представленной на рис. 7.10, показывает, что: • класс Задание по сути дела представляет собой таблицу, в которой фиксируется вся информация о конкретной задаче: вид задачи, алгоритм решения, данные и результат, причем результат связан с заданием неразрывно, так как теряет смысл вне контекста задания (отношение композиции), а данные имеют смысл сами по себе (отношение агрегации); • класс Алгоритм целесообразно разрабатывать как абстрактный; этот класс будет описывать интерфейс между объектом класса Решение и конкретным алгоритмом, а также между объектом класса Задание и опять жеконкретным алгоритмом; • отношение между классами Задание и Алгоритм, Решение и Алгоритм, а также Задание и Решение - ассоциации, направленные к классу Задание (рис. 7.16). Кроме того, анализ структур исходных данных и результатов решаемых задач показывает их существенное различие, следовательно, классы Данные и Результаты также необходимо реализовать как абстрактные и наследовать от них классы, уточняющие структуры данных и результатов для каждого случая. При дальнейшем анализе следует выяснить, будут ли классы Данные и Результаты описывать какие-либо поля или они только определят интерфейсы, через которые будет осуществляться доступ к данным и результатам конкретных заданий. На диаграмме классов целесообразно также указать множественность» объектов. Поскольку каждый раз решается одна задача с единственными данными, используя конкретный алгоритм, и в результате получают единствен- 201 ное решение, все перечисленные выше ассоциации связывают объекты «один к одному». 7.4. Проектирование классов Собственно проектирование классов предполагает окончательноё определение структуры и поведения его объектов. Структура объектов определяется совокупностью атрибутов и операций класса. Каждый атрибут - это поле или совокупность полей данных, содержащихся в объекте класса. 202 Поведение объектов класса определяется реализуемыми обязанностями. Обязанности выполняются посредством операций класса. Таким образом, при проектировании класса, помимо имени и максимально полного списка атрибутов, необходимо уточнить его ответственность и операции. Причем как атрибуты, так и операции в процессе проектирования целесообразно дополнительно специфицировать. В зависимости от степени детализации диаграммы классов обозначение атрибута может, помимо имени, включать: тип, описание видимости и значение по умолчанию. Для этого используют следующий формат: <признак видимости> <имя>:<тип> = <значение по умолчанию>, где признак видимости может принимать одно из трех значений: «+» - общий; «#» - защищенный; «-» - скрытый. Как упоминалось выше, операциями называют основные действия, реализуемые классом. В отличие от методов, операции не всегда реализуются классом непосредственно. Например, операция Ввод числа может быть реализована агрегатированным интерфейсным элементом «окно ввода». Полное описание операции на диаграмме класса в UML может выглядеть следующим образом: <признак видимости> <имя>(<список параметров>): <тип возвращаемого значения>. Ответственностью класса называют краткое неформальное перечисление основных функций объектов класса. Ответственность класса обычно определяют на начальных этапах проектирования, когда атрибуты и операции класса еще не определены. Эту информацию отображают на диаграмме классов в специальных секциях условного изображения класса (рис. 7.17). Исходный список операций класса формируют, анализируя диаграммы деятельностей, диаграммы взаимодействия и диаграммы последовательностей действий, построенные для различных сценариев с участием объектов проектируемого класса. На начальных этапах проектирования в секции операций класса обычно указывают лишь имена основных операций, определяющих наиболее общее поведение объектов соответствующих классов. По мере уточнения добавляют новые операции, а информацию об уже имеющихся операциях детализируют. Большинство атрибутов выявляется при анализе предметной области, требований технического задания и описаний потоков событий. 203 Кроме того, как указывалось выше, отношение ассоциации и его подвиды - агрегация и композиция - означают наличие обмена сообщениями между объектами классов. Для организации передачи сообщений необходимо, чтобы генерирующий сообщения объект содержал информацию о вызываемом объекте, что означает наличие у этого объекта соответствующего указателя. Причем при отношении композиции объекты-части могут быть организованы как объектные поля объекта-целого. В том случае, если объекты проектируемого класса должны реализовывать сложное поведение, для них целесообразно разрабатывать диаграммы состояний. Диаграммы состояний объекта. Под состоянием объекта применительно к диаграмме состояний понимают ситуацию в жизненном цикле объекта, во время которой он: удовлетворяет некоторому условию, осуществляет определенную деятельность или ожидает некоторого события. Изменение состояния, связанное с нарушением условия или, соответственно, завершением дёятельности или наступлением события называют переходом. Диаграммы состояний показывают состояния объекта, возможные переходы, а также события или сообщения, вызывающие каждый переход. Условные обозначения состояний приведены на рис. 7.18. Действие, указанное после слова Вход, выполняется при входе в состояние, а действие, указанное после слова Выход - при выходе из него. Деятельность связывается с нахождением в состоянии. Переход обозначается линией со стрелкой и может быть помечен меткой, состоящей из трех частей, каждую из которых можно опустить; <Событие> [<Условие>]/<Действие>. Если событие не указано, то это означает, что переход выполняется по завершению деятельности, связанной с данным состоянием. Если же оно ука- зано - то при наступлении события. 204 Условие записывается в виде логического выражения. Переход проис- ходит, если результат выражения - «истина». Объект не может одновременно перейти в два разных состояния, поэтому условия перехода для любого со- бытия должны быть взаимоисключающими. В отличие от деятельностей, действия, указанные для перехода, связы- вают с последним и рассматривают как мгновенные и непрерываемые. При необходимости можно определять суперсостояния (рис. 7.18, г), которые объединяют несколько состояний в одно. Этот механизм обычно ис- пользуют, чтобы показать переход из нескольких состояний в одно и то жё состояние, например, при отмене каких-либо действий. Пример 7.6. Разработать диаграмму состояний для объекта класса Ре- шение. Диаграмму состояний объекта строим, анализируя соответствующие диаграммы последовательности действий (см. рис. 7.8 и 7.9). При этом необ- ходимо уточнить, в какой момент разрешить прерывание процесса извне. Чтобы показать, что прерывание процесса возможно еще во время его инициализации, вводим суперсостояние Процесс. При реализации следует учесть возможность прерывания процесса до активации Алгоритма (рис. 7.19). 205 Результаты уточнения структуры и поведения объектов классов отразим на диаграмме классов. Пример 7.7. Уточнить атрибуты и операции классов Решение, Задание, Алгоритм, Данные и Результаты, используя полученные в данном параграфе сведения. К л а с с З а д а н и е. Поскольку объект класса Задание должен хранить идентификатор задачи и тип алгоритма, то он должен иметь соответствующие поля и включать операции Определить задачу(), Определить алгоритм(), Сообщить тип задачи(), Сообщить тип алгоритма(). Кроме того, объект класса Задание отвечает за объекты классов Данные и Результаты, связанные с ним, следовательно, он должен хранить их адреса и выполнять операции: Определить данные(), Сообщить данные(), Фиксировать результаты(), Сообщить результаты(), К л а с с ы Д а н н ы е и Р е з у л ь т а т ы. Данные задач и их результаты должны храниться в базе данных, но они имеют различные структуры. Эту проблему можно решить, если хранить и данные, и результаты в упакованном виде, распаковывая их по мере надобности. Значит, соответствующие классы должны объявлять абстрактные операции Упаковать() и Распаковать(), которые будут реализовываться классами-подтипами в зависимости от реальной структуры данных, определяемой типом задачи. Следовательно, указанные классы должны также хранить тип задачи, с которой они связаны, и содержать операции Определить тип задачи() и Сообщить тип Задачи(). К л а с с А л г о р и т м. Объекты класса Алгоритм отвечают за реализацию метода решения задачи. Поскольку они посылают сообщение объектам класса Задания, то, естественно, должны хранить его адрес. Кроме того, класс Алгоритм должен объявлять абстрактную опёрацию Выполнить(). Эта операция должна переопределяться классами Алгоритм, реализующий метод. Примечание. Возможно более удачное решение: в классе Алгоритм определить операцию Выполнить() и внутреннюю абстрактную операцию Реализовать метод(), которая вызывается из первой. Такое решение позволит не дублировать общее поведение всех алгоритмов, например, запрос и распаковку данных, а также упаковку и запись результата. Это решение не приведено, чтобы не усложнять и так достаточно сложный пример. К л а с с Р е ш е н и е. Объект класса Решение обращается к объектам классов Задание и Алгоритм, следовательно, необходимо хранить их адреса. Операции Начать() и Прервать() получены из диаграмм последовательностей действий. Операция Обработать исключение() получена оттуда же, но она должна реализовываться особым образом, так как будет получать управление через механизм исключений. Результаты уточнения приведены на рис. 7.20. 206 |