Read this post in: de_DEen_USes_ESfr_FRhi_INid_IDjapl_PLpt_PTvizh_CNzh_TW

Полное руководство по диаграммам классов UML (диаграмма как код)

💡 Примечание: Все диаграммы предоставлены в форматеPlantUML формате. Вы можете немедленно отобразить их, используяVisual Paradigm Диаграмма как код.


🔹 Введение в UML

Что такое UML?

«Единый язык моделирования (UML) — это универсальный визуальный язык моделирования, используемый для спецификации, визуализации, построения и документирования элементов программной системы». — Румбау, и др., 1999

Ключевые характеристики:

  • 🎨 Визуальная нотация: Графический синтаксис для моделирования систем

  • 📐 Стандартизирован: Стандарт, принятый OMG с 1997 года

  • 🔧 Язык, а не метод: Определяет нотацию, а не процесс

  • 🌐 Широкий охват: Моделирует бизнес-процессы, функции системы, структуры кода и схемы баз данных

Что UML НЕ является

Распространённое заблуждение Реальность
Методология разработки Просто нотация моделирования
Язык программирования Абстрактный язык спецификации
Только для объектно-ориентированного программирования Применимо к базам данных, моделированию бизнеса и т.д.
Точно определено во всех аспектах В ранних версиях остаются некоторые семантические неоднозначности

🔹 История и стандартизация

Хронология эволюции

The Evolution of Unified Modeling Language (UML)

1965–1970: Simula-67 (первый объектно-ориентированный язык)
     ↓
1970-е – 1980-е: Smalltalk в Xerox PARC
     ↓
1984: C++ был представлен Бьярне Страуструпом
     ↓
1988–1992: Распространение методов объектно-ориентированного проектирования (Booch, OMT, OOSE и др.)
     ↓
1994: Румбау приходит к Бучу в Rational → начинается объединение
     ↓
1995: Опубликован черновик UML 0.8
     ↓
1996: OMG издаёт запрос на предложение (RFP) по стандартному языку моделирования
     ↓
1997: UML 1.1 принят OMG (14 ноября)
     ↓
2000: UML 1.3 официально опубликован
     ↓
2003: Опубликован UML 1.5; принят суперструктурный уровень UML 2.0

Почему UML выиграл «Войну методов»

  • Объединил более 50 конкурирующих методов объектно-ориентированного проектирования в один стандарт

  • Поддерживается крупными игроками индустрии (IBM, Microsoft, Oracle, HP)

  • Предоставил механизмы расширения для настройки

  • Стал де-факто стандартом для объектно-ориентированного моделирования

⚠️ Критический взгляд: Некоторые утверждают, что UML — «монстр языка, созданный комитетом», с неточными семантиками в ранних версиях.


🔹 Классы и атрибуты

Структура класса

Класс UML представляется прямоугольником с тремя компартментами.

@startuml
class Student {
  firstName: String
  lastName: String
  email[0..1]: String
  encryptedPW: String
  + totalPoints(): Integer
  + setPassword(pw: String)
  + checkPW(pw: String): Boolean
}
@enduml

Синтаксис объявления атрибутов

[видимость] имя[множественность]: Тип [= значение по умолчанию] {свойства}

Примеры PlantUML:

@startuml
class Student {
  + ProgramOfStudy[0..2]: String = "MIS"
  - encryptedPW: String {frozen}
  # internalID: Integer
  ~ packagePrivateData: String
}
@enduml

Область видимости атрибута

  • Область видимости экземпляра (по умолчанию): У каждого объекта своё значение

  • Область видимости класса (статический): Одно значение, общее для всех экземпляров

Ключи в UML ⚠️

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

@startuml
class Student {
  {pk} id: Integer
  {ak1} email: String
  - name: String
}
@enduml


🔹 Ассоциации и отношения

Базовая ассоциация и множественность

@startuml
class Exercise
class Chapter
Exercise "0..*" -- "1..1" Chapter : Принадлежит
@enduml

Интерпретация: Каждое упражнение принадлежит ровно одной главе; глава может содержать ноль или более упражнений.

Имена ролей

Вместо (или в дополнение к) именам ассоциаций используйте имена ролей на концах ассоциаций:

@startuml
class Person
class Company
Person "0..*" --> "0..1" Company : Сотрудник/Работодатель
@enduml

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

Навигация

Укажите направление обхода с помощью стрелок:

@startuml
class Упражнение
class Глава
Упражнение "0..*" --> "1" Глава
@enduml

  • Стрелка указывает направление эффективного обхода

  • В ООБД: реализуется как указатель только в одном направлении

  • В РБД: соединения работают в обоих направлениях независимо

Типы коллекций с {упорядоченный}

@startuml
class Глава
class Упражнение
Глава "1" -- "0..*" Упражнение : {упорядоченный}
@enduml

  • {упорядоченный}: Сохраняйте порядок (используйте список, а не множество)

  • Реализация в РБД: добавьте атрибут порядкового номера

УПРАЖНЕНИЯ (
    id PRIMARY KEY,
    chapter_id ССЫЛКА НА ГЛАВЫ,
    sort_no INTEGER,
    УНИКАЛЬНО (chapter_id, sort_no)
)

Квалификаторы

Квалификаторы делят связанные объекты с помощью механизма, похожего на ключ:

@startuml
class Chapter
class Exercise
Chapter "1" --> "0..1" Exercise : <<qualifier>> no: Integer
@enduml

Значение: Учитывая главу и номер упражнения, возвращается не более одного упражнения.

Классы ассоциаций

Когда ассоциация имеет атрибуты или операции:

@startuml
class Student
class Exercise
class Solution {
  date: Date
  points: Integer
}
Student "0..*" -- "0..*" Exercise : has solved
Solution .. Student
Solution .. Exercise
@enduml

  • Один Решение объект на пару (Студент, Упражнение)

  • Обеспечивает: один и тот же студент не может отправить два решения для одного и того же упражнения

Композиция против агрегации

Функция Композиция (*--) Агрегация (o--)
Символ Черный ромб Белый ромб
Связь Целое-части, сильная собственность Целое-части, слабая ссылка
Жизненный цикл Части удаляются вместе с целым Части независимы
Множественность 1 или 0..1 со стороны целого Любой
Сопоставление с RDBMS ПРИ УДАЛЕНИИ КАСКАДНО Стандартный внешний ключ
@startuml
class Глава
class Упражнение
Глава *-- "0..*" Упражнение : Композиция
Глава o-- "0..*" Упражнение : Агрегация
@enduml


🔹 Операции и методы

Синтаксис объявления операции

@startuml
class Калькулятор {
  + getTotal(studID: Целое, inclExtra: Логическое = true): Вещественное {isQuery=true}
  + {static} getInstance(): Калькулятор
  + {constructor} Калькулятор(initialValue: Вещественное)
  - recalculate(): void
}
@enduml

Спецификация параметра:

[направление] имя: Тип [= значение по умолчанию]
  • Направления: вход (по умолчанию), выходвход-выход

  • Значения по умолчанию позволяют использовать необязательные параметры

Специальные стереотипы операций

Стереотип Цель
{isQuery=true} Гарантирует отсутствие изменения состояния
{конструктор} Создает и инициализирует новые экземпляры
{статический} Операция на уровне класса, без неявногоself

Операции в контексте базы данных

Культурный конфликт: ОО акцентирует внимание на инкапсуляции; реляционные системы акцентируют внимание на прямом доступе к данным.

Стратегии реализации:

Тип операции Реализация RDBMS
Простой доступ к атрибуту Прямой SELECT/UPDATE
Производный атрибут (без параметров) Представление базы данных
Производный атрибут (с параметрами) Хранимая процедура или логика приложения
Сложная проверка ограничений Триггеры или прикладные процедуры

🔹 Обобщение и наследование

Базовое обобщение

@startuml
class Person
class Student
class Professor
Person <|-- Student
Person <|-- Professor
@enduml

Абстрактные классы и операции

@startuml
абстрактный класс Account {
  - balance: Float
  + deposit(amount: Float): void
  + {abstract} withdraw(amount: Float): void
}
@enduml

Ограничения обобщения

@startuml
class Person
class Student
class Professor
class OtherPerson
Person <|-- Student : <<{disjoint, complete}>>
Person <|-- Professor : <<{disjoint, complete}>>
Person <|-- OtherPerson : <<{disjoint, complete}>>
@enduml

Множественная классификация / Дискриминаторы

@startuml
class Employee
class Staff
class Faculty
class HMO
class NonHMO
Employee <|-- Staff : <<kind>>
Employee <|-- Faculty : <<kind>>
Employee <|-- HMO : <<insurance>>
Employee <|-- NonHMO : <<insurance>>
@enduml

  • Дискриминаторы группируют взаимоисключающие специализации

  • Объекты могут иметь одно значение на каждый измерение дискриминатора


🔹 Механизмы расширения

UML предоставляет три механизма расширения:

1. Стереотипы<< >>

Расширяет семантику UML путем создания новых «подтипов» элементов метамодели.

@startuml
class Customer <<entity>> {
  - id: Integer
  - name: String
}
class MathLibrary <<utility>> {
  + sin(x: Float): Float
  + cos(x: Float): Float
}
@enduml

2. Метки значений{ключ=значение}

Добавьте пользовательские свойства к элементам модели.

@startuml
class Student {
  {author=sb, version=1.0, persistence=persistent}
  - id: Integer
}
@enduml

3. Ограничения {...}

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

@startuml
class Exercise {
  - no: Integer
  - points: Integer {value >= 0}
  {points <= maxPoints}
}
@enduml


🔹 UML для проектирования баз данных: основные соображения

Преобразование UML в реляционную схему

UML-конструкция Реляционная реализация
Класс Таблица
Атрибут Столбец
Первичный ключ {pk} Ограничение PRIMARY KEY
Ассоциация (1:*) Внешний ключ на стороне «многие»
Ассоциация (:) Таблица соединения/пересечения
Композиция Внешний ключ + ПРИ УДАЛЕНИИ КАСКАДНО
Класс ассоциации Таблица с составными внешними ключами + атрибуты
Обобщение Отдельные таблицы (с внешними ключами) или одна таблица с дескриптором типа
{упорядоченный} ассоциация Добавить столбец последовательности + уникальное ограничение
Квалификатор Часть составного ключа или индексированного столбца

Критические различия: ОО vs. Реляционные

Аспект Объектно-ориентированный Реляционный
Идентичность Ссылка на объект (суррогат) Первичный ключ (бизнес-ключ или суррогат)
Операции Центрально для проектирования, инкапсулировано Внешние (SQL, процедуры)
Инкапсуляция Приватные атрибуты, публичный интерфейс Прямой доступ к таблице по умолчанию
Наследование Поддержка родного языка Сложные стратегии отображения
Связи Указатели/ссылки Внешние ключи и соединения

Практические рекомендации для проектировщиков баз данных

  1. Явно моделировать ключи: Используйте {pk}{ak1} стереотипы, поскольку UML не поддерживает встроенные ключи

  2. Отметьте постоянство: Используйте {persistent} метку значения для различия классов базы данных от временных классов приложения

  3. Упростите операции: Сопоставьте операции запроса с представлениями; сложные операции — с хранимыми процедурами

  4. Внимательно обращайтесь с наследованием: Выберите стратегию сопоставления на основе шаблонов запросов

  5. Документируйте ограничения: Используйте OCL или четкие текстовые ограничения для бизнес-правил

  6. Осторожно используйте классы ассоциаций: Только когда связь имеет значимые атрибуты


🎯 Быстрое руководство по шпаргалке

Краткое резюме нотации диаграммы классов PlantUML

@startuml
class <<stereotype>> ClassName {
  {tagged=value}
  [+/-/#/~] name[mult]: Type [= val] {props}
  [+/-/#/~] name(params): Ret {props}
}
@enduml

Нотация ассоциации

@startuml
ClassA "multA" -- "multB" ClassB : AssociationName
ClassA *-- ClassB  ' Композиция
ClassA o-- ClassB  ' Агрегация
ClassA --> ClassB  ' Навигация
@enduml

Символы видимости

  • + Публичный

  • - Приватный

  • # Защищённый

  • ~ Пакет

Общие свойства и ограничения

  • {статический} / {isQuery=true} / {абстрактный}

  • {значение >= 0} / {исключающее ИЛИ} / {упорядоченный} / {pk}


💡 Заключительные мысли: Диаграммы классов UML мощны для концептуального моделирования, но помните, что они были разработаны в первую очередь для инженерии программного обеспечения. При использовании UML для проектирования баз данных будьте готовы расширить нотацию (с помощью стереотипов, тегированных значений, ограничений), чтобы зафиксировать реляционные концепции, такие как ключи, нормализация и декларативные ограничения, которые не являются встроенными в объектно-ориентированную основу UML.

Руководство составлено на основе «Часть 6: Диаграммы классов UML» Стефана Браса, университет Галле, 2003 год. Все диаграммы оформлены в синтаксисе PlantUML для совместимости с современными инструментами.

Leave a Reply