objects09 16

Диаграммы UML

До сих пор при обсуждении средств объектно-ориентированного программирования в PHP я позволял коду говорить самому за себя и использовал краткие примеры для иллюстрации таких понятий, как наследование и полиморфизм. Это полезно, потому что речь идет о PHP, который находится в центре нашего внимания. Но по мере увеличения размеров и сложности примеров использование только одного кода для иллюстрации больших изменений в проекте станет несколько абсурдным. Согласитесь, трудно увидеть общую картину в нескольких строках кода.

UML расшифровывается как Unified Modeling Language (унифицированный язык моделирования). История его создания довольно интересна. По словам Мартина Фаулера (Martin Fowler), UML возник как стандарт после многолетних интеллектуальных и бюрократических споров в сообществе приверженцев объектно-ориентированного проектирования. Результатом этой борьбы стал мощный графический синтаксис для описания объектно-ориентированных систем. В данной статье мы рассмотрим его только в общих чертах, но вы вскоре поймете, что "малыш" UML прошел долгий путь.

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

Диаграммы классов

Диаграммы классов — это только один аспект UML, но, вероятно, они чаще всего используются. И поскольку они чрезвычайно полезны для описания объектно-ориентированных связей, я тоже буду использовать их.

Представление классов

Как и можно было ожидать, классы — это главные составные элементы диаграмм классов. Класс представляется в виде прямоугольника с именем, как показано на рисунке ниже (для проработки последующих примеров вам понадобиться структура класса ShopProduct, которую мы определили к данному моменту и вспомогательные классы - исходный код):

Представление класса в UML

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

Абстрактные классы представляют, либо выделяя имя класса курсивом, либо добавляя к имени класса уточнение {abstract}, как показано на рисунке ниже. Первый способ более распространенный, а второй более удобный, если вы делаете заметки в своем блокноте:

Пример представления абстрактного класса в UML

Надпись {abstract} — это пример уточнения. Уточнения в диаграммах классов служат для описания того, каким способом должны использоваться конкретные элементы. Для текста в фигурных скобках не существует специальных правил, он должен просто дать понятное объяснение каких-либо условий, которые применяются к элементу.

Интерфейсы определяются таким же образом, как классы, за исключением того, что они должны включать стереотип {т.е. расширение словаря UML):

Представление интерфейса

Атрибуты UML

Если говорить в общем, то атрибуты описывают свойства класса. Атрибуты перечисляются в разделе, который расположен непосредственно под именем класса:

Представление атрибута

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

Символы видимости UML
Символ Видимость Описание
+ Общедоступный Доступный для всего кода
- Закрытый Доступный только для текущего класса
# Защищенный Доступный только для текущего класса и его подклассов

За символом видимости следует имя атрибута. В данном случае мы описываем свойство ShopProduct::$price. Двоеточие используется для отделения имени атрибута от его типа (и, возможно, от его стандартного значения). И снова повторяю, что вы можете включать ровно столько деталей, сколько это необходимо для ясности.

Операции UML

Операции описывают методы или, точнее, вызовы, которые могут быть сделаны к экземпляру класса. На рисунке ниже показаны две операции класса ShopProduct:

Представление операций UML

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

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

Описание наследования и реализации

В UML отношения наследования описываются в виде обобщений. Это отношение обозначается линией, ведущей от подкласса к родительскому классу. Эта линия заканчивается незакрашенной замкнутой стрелкой. Ниже показана связь между классом ShopProduct и его дочерними классами:

Описание наследования и реализации интерфейса

Как показано на диаграмме с помощью UML описывается также связь между интерфейсом и классами, которые его реализуют.

Ассоциации

Наследование — это только одно из отношений в объектно-ориентированной системе. Ассоциация происходит, когда объявляется, что свойство класса содержит ссылку на экземпляр (или экземпляры) другого класса. Допустим мы моделируем два класса и создаем ассоциацию между ними. На данном этапе нам неизвестна природа этих отношений. Мы только указали, что у объекта Teacher будет ссылка на один или более объектов Pupil или наоборот. Это отношение может быть или не быть взаимным:

Описание ассоциаций в UML

Стрелки используются для описания направления ассоциации. Если в классе Teacher существует ссылка на экземпляр класса Pupil, но не наоборот, то мы должны определить ассоциацию с помощью стрелки, направленной от класса Teacher к классу Pupil. Эта ассоциация называется однонаправленной.

Если в каждом классе существует ссылка на другой класс, то для описания двунаправленного отношения используется двунаправленная стрелка. Можно указать также количество экземпляров класса, на которые ссылается другой класс в ассоциации. Для этого нужно поместить число или интервал чисел рядом с каждым классом. Можно также использовать звездочку (*), обозначающую любое число. На рисунке выше показано, что может существовать только один объект Teacher и ноль или больше объектов Pupil.

Агрегирование и композиция

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

В случае агрегирования, содержащиеся объекты составляют основную часть объекта-контейнера (который их содержит), но они могут также одновременно содержаться и в других объектах. Отношение агрегирования обозначается линией, которая начинается с незакрашенного ромба:

SchoolClass агрегирует класс Pupil

Класс состоит из учеников, но на один и тот же объект Pupil могут одновременно ссылаться различные экземпляры класса SchoolClass. Если бы нам понадобилось распустить школьный класс, для этого необязательно удалять ученика, который может посещать другие классы.

Композиция представляет собой еще более сильное отношение. В композиции на содержащийся объект может ссылаться только его объект-контейнер. И он должен быть удален при удалении объекта-контейнера. Отношения композиции изображаются так же, как и отношения агрегирования, только с закрашенным ромбом. Отношение композиции проиллюстрировано на рисунке:

Композиция

В классе Person существует постоянная ссылка на объект SocialSecurityData. Экземпляр этого объекта может принадлежать только содержащему его объекту Person.

Описание отношений использования

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

Класс Report на рисунке ниже использует объект ShopProductWriter. Отношение использования изображается с помощью пунктирной линии со стрелкой с незамкнутым контуром на конце; эта линия соединяет рассматриваемые класс и объект. Тем не менее при этом отношении ссылка на объект не хранится в виде свойства, как, например, в объекте ShopProductWriter, где хранится массив ссылок на объекты типа ShopProduct:

Отношение использования

Итак, мы рассмотрели UML как основу, очень важную для работы с объектами и шаблонами.

Методы проектирования
Шаблоны проектирования

Комментарии (0)

Результаты поиска по запросу

Система Orphus