Проектирование классов включает следующие действия:
· детализация проектных классов;
· уточнение операций и атрибутов;
· моделирование состояний для классов;
· уточнение связей между классами.
Детализация проектных классов. Каждый граничный класс преобразуется в некоторый набор классов, в зависимости от своего назначения. Это может быть набор элементов пользовательского интерфейса, зависящий от возможностей среды разработки, или набор классов, реализующий системный или аппаратный интерфейс.
Классы-сущности с учетом соображений производительности и защиты данных могут разбиваться на ряд классов. Основанием для разбиения является наличие в классе атрибутов с различной частотой использования или видимостью. Такие атрибуты, как правило, выделяются в отдельные классы.
Рис. 4.29. Кооперативная диаграмма «Зарегистрироваться на курсы» — основной поток событий
Классы, реализующие простую передачу информации от граничных классов к сущностям, могут быть удалены. Сохраняются классы, выполняющие существенную работу по управлению потоками событий (управление транзакциями, распределенная обработка и т.д.).
|
|
Полученные в результате уточнения классы подлежат непосредственной реализации в коде системы.
Рис. 4.30. Кооперативная диаграмма «Зарегистрироваться на курсы» -подчиненный поток «Создать график»
Уточнение операций и атрибутов. Обязанности классов, определенные в процессе анализа и документированные в виде операций «анализа», преобразуются в операции, которые будут реализованы в коде. При этом:
· каждой операции присваивается краткое имя, характеризующее ее результат;
· определяется полная сигнатура операции (в соответствии с нотацией, принятой в языке UML;
· создается краткое описание операции, включая смысл всех ее параметров;
· определяется видимость операции: public, private или protected;
· определяется область действия операции: экземпляр (операция объекта) или классификатор (операция класса);
· может быть составлено описание алгоритма выполнения операции (с использованием диаграмм деятельности в виде блок-схем, а также диаграмм взаимодействия различных объектов при выполнении операции).
· Уточнение атрибутов классов заключается в следующем:
· кроме имени атрибута, задается его тип и значение по умолчанию (необязательное);
· учитываются соглашения по именованию атрибутов, принятые в проекте и языке реализации;
· задается видимость атрибутов: public, private или protected;
· при необходимости определяются производные (вычисляемые) атрибуты.
Пример уточнения операций и атрибутов приведен на рис. 4.31.
|
|
Моделирование состояний для классов. Если некоторый объект всегда одинаково реагирует на событие, то он считается независимым от состояния по отношению к этому событию. В отличие от него зависимые от состояния объекты по-разному реагируют на одно и то же событие в зависимости от своего состояния. Обычно в экономических ИС содержится очень мало объектов, зависимых от состояния, а системы управления технологическими процессами (системы реального времени) зачастую содержат множество таких объектов.
Если в системе присутствуют зависимые от состояния объекты со сложной динамикой поведения, то для них можно построить модель, описывающую состояния объектов и переходы между ними. Эта модель представляется в виде диаграмм состояний.
В качестве примера, связанного с системой регистрации, рассмотрим поведение объекта класса CourseOffering. Диаграмма состояний строится в несколько этапов:
1. Идентификация состояний. Признаками для выявления состояний являются изменение значений атрибутов объекта или создание и уничтожение связей с другими объектами. Так, объект CourseOffering может находиться в состоянии Open (прием на курс открыт) до тех пор, пока количество зарегистрировавшихся на него студентов не превышает 10, а как только оно станет равным 10, объект переходит в состояние Closed (прием на курс закрыт). Кроме того, объект CourseOffering может находиться в состоянии Unassigned (его никто не ведет, т.е. отсутствует связь с каким-либо объектом Professor) или Assigned (такая связь существует).
Рис. 4.31. Класс Student с полностью определенными операциями
и атрибутами
2. Идентификация событий. События связаны, как правило, с выполнением некоторых операций. Так, в классе CourseOffering в результате распределения обязанностей при анализе варианта использования «Выбрать курсы для преподавания» определены две операции — addProfessor и removeProfessor, связанные с выбором курса некоторым профессором (созданием новой связи) и отказом от выбранного курса (разрывом связи). Этим операциям ставятся в соответствие два события - addProfessor и removeProfessor.
3. Идентификация переходов между состояниями. Переходы вызываются событиями. Таким образом, состояния Unassigned и Assigned соединяются двумя переходами (рис. 4.32).
Рис. 4.32. Переходы между состояниями
Дальнейшая детализация поведения объекта CourseOffering приведет к построению диаграммы состояний, показанной на рис. 4.33. На данной диаграмме использованы такие возможности моделирования состояний, как композитные состояния (composite state) и историческое состояние (history state). В данном случае композитными состояниями являются Open и Closed, а вложенными состояниями — Unassigned, Assigned, Cancelled (курс отменен), Full (курс заполнен) и Committed (курс включен в расписание). Композитные состояния позволяют упростить диаграмму уменьшая количество переходов, поскольку вложенные состояния наследуют все свойства и переходы композитного состояния.
Историческое состояние (обозначенное на диаграмме окружностью с буквой «Н») — это псевдосостояние, которое восстанавливает предыдущее активное состояние в композитном состоянии. Оно позволяет композитному состоянию Open запоминать, какое из вложенных состояний (Unassigned или Assigned) было текущим в момент выхода из Open, для того, чтобы любой из переходов в Open (add student или remove student) возвращался именно в это вложенное состояние, а не в начальное состояние.
Рис. 4.33. Диаграммы состояний с композитными состояниями
Построение диаграмм состояний может оказать следующее воздействие на описание классов:
· события могут отображаться в операции класса (например, события, связанные с изменением количества студентов, записавшихся на курс, могут быть отображены в операции addstudent и removestudent класса CourseOffering);
|
|
· особенности конкретных состояний могут повлиять на детали выполнения операций;
· описание состояний и переходов может помочь при определении атрибутов класса (например, значение количества студентов, записавшихся на курс (numStudents), может быть добавлено в класс CourseOffering в качестве производного атрибута).
Уточнение связей между классами. В процессе проектирования связи между классами (ассоциации, агрегации и обобщения) подлежат уточнению.
· Ассоциации между граничными и управляющими классами отражают связи, динамически возникающие между соответствующими объектами в потоке управления. Для таких связей достаточно обеспечить видимость классов, поэтому они преобразуются в зависимости.
· Если для некоторых ассоциаций нет необходимости в двунаправленной связи, то вводятся направления навигации.
· Агрегации, обладающие свойствами композиции (см. подразд. 2.4.2), преобразуются в связи композиции.
Рис. 4.34. Пример преобразования ассоциаций и агрегаций
Пример преобразования связей в соответствии с данными рекомендациями для классов варианта использования «Зарегистрироваться на курсы», приведен на рис. 4.34. Ассоциация между управляющим и граничным классами преобразована в зависимость. Агрегация между классами Student и Schedule обладает свойствами композиции. Направления навигации на ассоциациях между классами Schedule и CourseOffering введены по следующим соображениям: нет необходимости в получении списка графиков, в которых присутствует какой-либо курс, и количество графиков относительно мало по сравнению с количеством конкретных курсов.
Рис. 4.35. Преобразование обобщения
Связи обобщения могут преобразовываться в ситуациях с так называемой метаморфозой подтипов. Например, в случае с системой регистрации студент может переходить с очной формы обучения на вечернюю, т.е. объект Student может менять свой подтип. При таком изменении придется модифицировать описание объекта в системе. Чтобы избежать этой модификации и тем самым повысить устойчивость системы, иерархия наследования реализуется с помощью классификации, как показано на рис. 4.35.
|
|