# 2. Язык моделирования UML

**UML** – унифицированный язык моделирования (Unified Modeling Language) – это система обозначений, которую можно применять для объектно-ориентированного анализа и проектирования. Его можно использовать для визуализации, спецификации, конструирования и документирования программных систем.

{% hint style="warning" %}
Ссылка на приложения для построения диаграмм UML - [http://staruml.io/download](http://staruml.io/download)
{% endhint %}

Словарь UML включает три вида строительных блоков:

* Диаграммы.
* Сущности.
* Связи.

_Сущности_ – это абстракции, которые являются основными элементами модели, _связи_ соединяют их между собой, а _диаграммы_ группируют представляющие интерес наборы сущностей.

_Диаграмма_ – это графическое представление набора элементов, чаще всего изображенного в виде связного графа вершин (сущностей) и путей (связей). Язык UML включает 13 видов диаграмм, среди которых на первом месте в списке — диаграмма классов.

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

> _Если кто-нибудь подойдет к вам в темном переулке и спросит: «Хотите посмотреть на диаграмму UML?», знайте – скорее всего, речь идет о диаграмме класса. Большинство диаграмм UML, которые я встречал, были диаграммами классов._\
> \
> &#x20;                                                                                                                                                        \- Мартин Фаулер

Графически класс изображается в виде прямоугольника, разделенного на три блока горизонтальными линиями:

* имя класса;
* атрибуты (свойства) класса;
* операции (методы) класса.

Для атрибутов и операций может быть указан один из трех типов видимости:

* `-` private;
* `~` без модификатора (default);
* `#` protected;
* `+` public.

Видимость для полей и методов указывается в виде левого символа в строке с именем соответствующего элемента.

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

**Атрибут (свойство)** – это именованное свойство класса, описывающее диапазон значений, которые может принимать экземпляр атрибута. Класс может иметь любое число атрибутов или не иметь ни одного. В последнем случае блок атрибутов оставляют пустым. Можно уточнить спецификацию атрибута, указав его тип, кратность (если атрибут представляет собой массив некоторых значений) и начальное значение по умолчанию.

Статические атрибуты класса обозначаются подчеркиванием.

**Операция (метод)** – это реализация метода класса. Класс может иметь любое число операций либо не иметь ни одной. Часто вызов операции объекта изменяет его атрибуты. Графически операции представлены в нижнем блоке описания класса. Допускается указание только имен операций. Имя операции, как и имя класса, должно представлять собой текст. Можно специфицировать операцию, устанавливая ее сигнатуру, включающую имя, тип и значение по умолчанию всех параметров, а применительно к функциям – тип возвращаемого значения.

Абстрактные методы класса обозначаются курсивным шрифтом. Статические методы класса обозначаются подчеркиванием.

Изображая класс, не обязательно показывать сразу все его атрибуты и операции. Для конкретного представления, как правило, существенна только часть атрибутов и операций класса. В силу этих причин допускается упрощенное представление класса, то есть для графического представления выбираются только некоторые из его атрибутов. Если помимо указанных существуют другие атрибуты и операции, вы даете это понять, завершая каждый список многоточием. Чтобы легче воспринимать длинные списки атрибутов и операций, желательно снабдить префиксом (именем стереотипа) каждую категорию в них. В данном случае стереотип – это слово, заключенное в угловые кавычки, которое указывает то, что за ним следует.

![](https://1377473627-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LnhxGhlv6e_zwoZYywB%2F-MGjOeRz7aLawjskZ5Fe%2F-MGjSQmsK-kQHPTmsYsf%2Fimage.png?alt=media\&token=e17ee630-9480-4c5f-aaa3-6db84353277e)

Рассмотрим пример класса - его графическое представление и код на языке Java.

![](https://1377473627-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LnhxGhlv6e_zwoZYywB%2F-MGjOeRz7aLawjskZ5Fe%2F-MGjPhr3vmnKDvrSbx1X%2Fimage.png?alt=media\&token=ef381eaa-a5d4-4492-a1ff-8e066c88ad38)

{% code title="Human.java" %}
```java
public class Human {

    private String name;        // private это "-"
    Boolean gender = true;      // default это "~"
    protected long chromosome;  // protected это "#"
    public int age;             // public это "+"

    // Статические атрибуты подчеркиваются
    public static long dna;
    
    // Константы можно отобазить как readOnly
    final int SECRET = 924;

    /* Как правило, конструкторы
     * изображаются как обычные методы */
    public Human() {}
    public Human (String name) {this.name = name;}

    /* Методы отображаются как
     * [-~#+]имя(тип_аргументов): возвращаемый тип
     * Например: public String foo (int a, double b)
     * будет +foo(int, double): String */
    public void breath() {}
    private void sleep(int hours) {}
    protected boolean sneeze() { return true; }
    int run (int speed, String direction) { return 0; }
    public static int calculateAge() { return 0; }
}
```
{% endcode %}
