Здравствуйте, не могу найти ссылку на скачивание курса «Визуальное моделирование: теория и практика»
Номер платежа 6400454020565 |
Введение в UML 2.0, часть II
Диаграммы классов (class diagrams)
Этот тип диаграмм является основным при разработке объектно-ориентированной системы, так как позволяет наглядно изобразить структуру классов приложения. Такие диаграммы полезны как при предварительном проектировании, так и при рефакторинге, сопровождении и исправлении ошибок, а также при изучении ПО. По этим диаграммам легко генерировать программный код, их легко восстанавливать по уже существующему программному коду. Кроме того, диаграммы классов используются при описании самих языков визуального моделирования, как это будет показано в следующих лекциях.
На рис. 4.1 представлен фрагмент диаграммы классов телефонной службы приема заявок.
На этом рисунке показаны основные классы сервера телефонной системы обработки заявок: класс CPBX_Agent отвечает за работу с PBX (с "железкой", занимающейся коммутацией абонентов); класс COperator содержит описание экземпляров операторов, работающих в call-центре, класс CSubOperator описывает особенного, "продвинутого" оператора (например, начальника над группой операторов); класс COperatorList управляет множеством операторов (добавляет их в список, удаляет и т.д.); класс CNetworkConnectionSupport отвечает за поддержку соединений сервера через локальную компьютерную сеть с компьютерами операторов; класс CDispatсher отвечает за синхронизацию всех остальных программных сущностей на сервере.
Итак, на диаграммах классов изображаются сами классы с атрибутами, типами атрибутов, методами, их параметрами и типами, а также иерархия наследования классов. И класс, и наследование в UML полностью соответствуют конструкциям объектно-ориентированных языков программирования. Но кроме них на диаграммах классов могут также присутствовать связи между классами - ассоциации. Так, на рис. 4.1 класс CDispatcher связан с классами CPBX_Agent, COperator, CServerNetworkConnectionSupport и COperatorList.
Ассоциации (association)
Если два класса связаны друг с другом ассоциацией, то это означает, что их экземпляры (объекты) определенным образом связаны друг с другом, например:
- вызывают методы друг друга,
- работают с общей памятью,
- объекты одного класса являются параметрами методов другого,
- один класс имеет атрибут с типом другого класса (или указателя на него).
Ассоциация как связь между классами обязательно переходит в связь между экземплярами этих классов. Этим она принципиально отличается от наследования. Ниже мы подробно остановимся на отличиях агрегирования и наследования.
Ассоциации в программном коде могут быть реализованы, например, через атрибуты-указатели языка C++, как показано на рис. 4.2.
Отметим, что доступ по ассоциации может быть однонаправленным и двунаправленным. На рис. 4.3, а изображена ассоциация, направленная от класса С1 к классу С2. Это может означать, что в программном коде класса С2 нет атрибута а2, и объекты класса С2 "не знают", что на них ссылаются объекты класса С1. На рис. 4.3, б и в показано два варианта изображения двунаправленной ассоциации. На рис. 4.2 приведен пример реализации именно для двунаправленной ассоциации.
У ассоциации может быть имя, хотя его не обязательно задавать. Имя у ассоциации полезно проставлять, если, например, между двумя классами существует несколько ассоциаций, - чтобы отличать их между собой. Иногда же полезно именовать ассоциации для того, чтобы диаграммы было удобно читать, хотя для этой цели лучше использовать имена их концов, так как они лучше показывают, кто кого использует, обслуживает, включает и пр.
Ассоциации соединяются с классами через специальные конструкции - концы ассоциаций (association ends). Именно у этих концов определяются различные свойства, такие как множественность, агрегирование и др. Концы ассоциаций часто целесообразно именовать на диаграммах, чтобы делать спецификации более наглядными и понятными.
Но именовать концы ассоциаций полезно далеко не всегда. В примере, показанном на рис. 4.4, концы двух ассоциаций со стороны абонента целесообразно именовать, чтобы станция могла различать абонентов, полученных по разным экземплярам ассоциаций. Противоположные же концы можно не именовать, так как экземпляр класса "Станция" в системе один, у всех других объектов на него имеются ссылки.
Концы ассоциации имеет смысл именовать всегда, когда ассоциация рефлексивна, то есть связывает класс с ним самим же. Пример такой ассоциации показан на рис. 4.5. Там представлен класс CListItem, реализующий элемент двусвязного списка. У него есть ассоциация с самим собой, которая указывает, что один объект этого класса связан этой ассоциацией с двумя другими объектами - с одним через конец Prev (то есть с предыдущим в списке), с другим - через конец Next (то есть со следующим в списке), а может быть связан только с одним (предыдущим или следующим, и тогда он является, соответственно, последним или первым в списке) или ни с одним вовсе (в этом случае этот объект является единственным в списке). Эти роли используются в качестве имен для концов ассоциаций. Количество объектов, с которыми может быть связан экземпляр класса CListItem по этой ассоциации, указывается с противоположного конца ассоциации с помощью конструкции "множественность".
У конца ассоциации есть свойство под названием множественность (multiplicity). Это свойство определяет количество представителей (конкретных объектов), которые могут быть связаны с партнером ассоциации через этот конец. Множественность является целочисленным интервалом или константой. Ниже представлены примеры.
0..1.
1.
0..*.
1..*.
* - просто много, без уточнения того, 0 или 1 фигурируют в качестве нижнего предела.
Константа (например, 2, 10, 100).
Интервал (например, 3..5, 10..20).
Варианты с первого по пятый являются наиболее распространенными на практике.
Примеры множественности концов ассоциации можно видеть на рис. 4.1 - класс CDispatcher связан с классом COperator так, что каждый экземпляр класса COperator имеет связь ровно с одним экземпляром класса CDispatcher, а каждый экземпляр класса CDispatcher имеет связь с несколькими экземплярами класса COperator или может не иметь такой связи вовсе. Последнее обеспечивается нижней границей множественности ассоциации со стороны класса COperator, равной нулю.