Как рисовать UML диаграммы классов

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

Архитекторы разговаривают на языке UML. Это такая своеобразная программистская латынь. Старый язык, но который до сих пор используют в определённых кругах. Использовать его напрямую для написания программного кода очень неудобно, а вот для описания архитектуры вполне подходит. Нарисовал диаграмму и стало понятней, что к чему. Поймёт дельфист, жаваист, сишник, питоньшик, сишарпер, рубист, в общем, все, кто изучал ООП.

Центральное место в UML занимают диаграммы классов. Это букварь. В интернете можно найти огромное количество информации о диаграммах классов (структура, обозначение классов, интерфейсов, атрибутов, отношений и т. д.), но при этом относительно мало информации о том, как осуществлять само проектирование. Выучить как рисовать стрелочки и прямоугольники — несложно, сложно научиться из них собирать что-то нормально работающее. В связи с этим хотел обратить внимание читателя на два особых момента.

От общего к частному…

Главное при создании диаграммы классов — использовать принцип «от общего к частному». На самом деле это один из принципов, который великие художники прошлого открыли уже много лет назад.

Представим, что вы не умеете хорошо рисовать, но вам очень хочется нарисовать, например, чью-то голову. Вы берёте карандаш, кладёте лист бумаги и начинаете рисовать его левый глаз. Потратив на этот несчастный левый глаз больше часа, бросаете и берётесь за нос, затем за правый глаз, ухо и только потом пытаетесь дорисовать все остальное. Вполне вероятно, что итог работы вас опечалит (не советую также показывать натурщице/натурщику результат работы) — глаз, нос, рот и уши скорее всего будут не на своем месте. Конечно, бывают среди нас гении, у которых получится шедевр, но все-таки, те, кто занимается этим профессионально проповедуют другой подход — «От общего к частному, от частного к общему» Вначале делается эскиз, «топорный» рисунок. Затем дальнейшая проработка. Например, так:

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

Но начинать нужно с формирования набора базовых классов. Для этого нужно просто нарисовать прямоугольники и написать в них имена основных классов. Затем постепенно прорабатывать все остальное.

Например, так:

Шаг 1. Рисуем классы

диаграмма классов 1

Шаг 2. Связи

диаграмма классов 2

Шаг 3. Мультипликаторы

диаграмма классов 3

Шаг 4. Свойства классов

диаграмма классов 4

Кстати, если  вы владеете техникой «UML colors» от мастера Кода, то можно начать использовать её уже на первом этапе.

Теперь давайте приступим к исследованию другого фундаментального вопроса в архитектуре ПО.

Быть или иметь?

Существуют два фундаментальных отношения «быть» и «иметь». Самое грубое и примитивное объяснение: «быть»  — наследование, «иметь» — агрегация (см. справочник).  Казалось бы, какая разница? В некоторых языках это вообще одно и тоже слово.

Например:  «У меня есть телефон» (иметь, обладать) и «Телефон есть инструмент общения» (быть, являться).

На самом деле, разница огромная. Представим, что у нас есть класс User, который определяет некоторого пользователя системы. Пользователи бывают разные: анонимный пользователь или гость, редактор статей и администратор. Как определить эти сущности?

Можно сделать так:

А можно сделать так:

В первом случае у нас отношение «быть, являться». Любой из объектов класса Admin, Editor, Guest также является пользователем (is a User).

Во втором случае  отношение «иметь». Объект класса User, имеет некоторое свойство-атрибут (has a), которое определяет статус этого пользователя в системе. Проецируя на реальный мир, мы должны задуматься «кто такой наш пользователь?». Что значит для него  «быть админом»? Если это нечто неотделимое от него самого, его внутренней сути, сущностного Я, его Identity, если  наш пользователь рожден админом и уходит в другой мир админом, то тогда «Admin is a User» вполне оправдано.

Но если «админ» это всего лишь ярлык, некая роль, должность или социальный статус, обладание которым облегчает или усложняет жизнь нашему пользователю и при этом мы отлично знаем, что «высшие силы» всегда могут в любой момент лишить его админских сверхспособностей, то тогда, возможно, второй вариант будет более правильным.

В первом случае админ-пользователь гордо заявляет «Я есть админ» и этого у него не отнять, то во втором он скромно говорит:«У меня есть статус админа».

Таким образом, отвечая на вопрос «быть или иметь?», мы задаём базовые отношения в нашей системы, и нужно хорошо подумать, прежде чем просто нарисовать стрелочки между классами.

P. S.  рисунки головы взяты с сайта.

Об авторе
Более 20 лет в разработке ПО, специализируюсь на Java. Опыт в создании масштабируемых и высокопроизводительных систем, разработке мобильных приложений. Подробнее об авторе и правилах использования контента – на странице @author.

  Подписывайтесь на Telegram-канал@prgrmdr