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

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

### Свойства

Свойства представляют структурную функциональность классов. В первом приближении можно можно рассматривать свойства, как поля класса. Они представленны в виде атрибутов и ассоциаций.

Атрибут описывает свойство в виде строки текста внутри прямоугольника класса. Полная форма атрибута:

**видимость имя: тип кратность=значение по умолчанию {свойства}**

например:

**count: int = 7 {readOnly}**

Для аттрибута обязательно только имя.

![](http://gameinstitute.ru/wp-content/uploads/media/2.-%D0%94%D0%B8%D0%B0%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%BE%D0%B2/image1.png)

Другая ипостась свойства – это ассоциация. Значительная часть информации, которую можно указать в аттрибуте, проявляется в ассоциации. Ассоциации – это непрерывная линия между двумя классами, направленная от исходного класса к целевому. Имя свойства вместе с кратностью располагается на целевом конце ассоциации.

![](http://gameinstitute.ru/wp-content/uploads/media/2.-%D0%94%D0%B8%D0%B0%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%BE%D0%B2/image2.png)

### Кратность.

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

* 1 – только 1. Например, только одна буква “а” в слове “пар”
* 0..1 – может быть или не быть. Например, второй двигатель у самолета
* \* — любое количество. Например, лепестков у цветка

В большинстве случаев кратности определяются своими нижней и верхней границами. Нижняя граница может быть нулем или положительным числом, верхняя граница представляет собой положительное число или \*(без ограничений). Если верхняя и нижняя границы совпадают, то можно указать одно число, например 1..1 эквивалентно 1.

### Операции

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

Полный синтаксис операции в языке UML выглядит следующим образом:

**видимость имя(параметры) : возвращаемый тип {свойства}**

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

**направление имя: тип = значение по умолчанию**

Направление обозначает, является ли данный параметр входным или выходным. Например,

**+switchOn ( on: bool ) : Result**

Cледует различать операции, изменяющие состоя ние системы, и операции, не делающие этого. Язык UML определяет запрос как некую операцию, результатом которой является некоторое значение, получаемое от класса; при этом состояние системы не изме няется, то есть данная операция не вызывает побочных эффектов. Та кую операцию можно пометить строкой свойств {query} (запрос). Опе рации, изменяющие состояние, я называю модификаторами, иначе именуемые командами.

Строго говоря, различие между запросом и модификаторами состоит в том, могут ли они изменять видимое состояние. Видимое состоя ние – это то, что можно наблюдать извне. Операция, обновляющая кэш, изменит внутреннее состояние, но это не окажет никакого влия ния на то, что видно снаружи.

Другие термины, с которыми иногда приходится сталкиваться, – это методы получения значения (getting methods) и методы установки значения (setting methods). Метод получения значения возвращает некоторое значение из поля (и не делает ничего больше). Метод установ ки значения помещает некоторое значение в поле (и не делает ничего больше). За пределами класса клиент не способен определить, являет ся ли запрос методом получения значения или модификатор – методом установки значений. Эта информация о методах является исключи тельно внутренней для каждого из классов.

### Генерализация

Один из трех ключевых признаков ООП – это наследование. Наследование позволяет увеличить используемость кода, сократить пространство для дебага и ускорить процесс разработки. Однако, наследование является не самым “чистым” сбособом использовать код многократно. Мы будем обсуждать этот вопрос в статьях, посвященных ООП.

В любом случае, вне зависимости от конкретного способа наследования функционала, UML позволяет показать, что один объект является подтипом другого. Такая связь называется генерализацией:

![](http://gameinstitute.ru/wp-content/uploads/media/2.-%D0%94%D0%B8%D0%B0%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%BE%D0%B2/image3.png)

### Реализация

Реализация – это способ показать наследование интерфейса в UML. Когда мы говорим, что класс A реализует интерфейс B, это значит, что мы можем обращаться к A методами B:

![](http://gameinstitute.ru/wp-content/uploads/media/2.-%D0%94%D0%B8%D0%B0%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%BE%D0%B2/image4.png)
