Read this post in: de_DEen_USes_ESfr_FRhi_INid_IDjapt_PTru_RUvizh_CNzh_TW

Kompletny przewodnik po diagramach klas UML (Diagram jako kod)

💡 Uwaga: Wszystkie diagramy są dostępne w formaciePlantUML format. Możesz natychmiast renderować je za pomocąVisual Paradigm Diagram jako kod.


🔹 Wprowadzenie do UML

Czym jest UML?

„Język modelowania zintegrowanego (UML) to ogólnego przeznaczenia język wizualnego modelowania, używany do określania, wizualizowania, konstruowania i dokumentowania artefaktów systemu oprogramowania.” — Rumbaugh et al., 1999

Kluczowe cechy:

  • 🎨 Notacja wizualna: Graficzna składnia do modelowania systemów

  • 📐 Standardowy: Standard przyjęty przez OMG od 1997 roku

  • 🔧 Język, a nie metoda: Definiuje notację, a nie proces

  • 🌐 Szeroki zakres: Modeluje procesy biznesowe, funkcje systemu, struktury kodu i schematy baz danych

Czym UML NIE JEST

Pomyłka Rzeczywistość
Metodologia rozwoju Po prostu notacja modelowania
Język programowania Abstrakcyjny język specyfikacji
Tylko do programowania obiektowego Stosowalny do baz danych, modelowania biznesowego itp.
Dokładnie zdefiniowany we wszystkich aspektach W wersjach wczesnych pozostają pewne niejasności semantyczne

🔹 Historia i standaryzacja

Chronologia rozwoju

The Evolution of Unified Modeling Language (UML)

1965–1970: Simula-67 (pierwszy język obiektowy)
     ↓
1970–1980: Smalltalk w Xerox PARC
     ↓
1984: C++ wprowadzony przez Bjarne Stroustrupa
     ↓
1988–1992: Rozprzestrzenianie się metod obiektowych (Booch, OMT, OOSE itp.)
     ↓
1994: Rumbaugh dołącza do Boocha w Rational → zaczyna się unifikacja
     ↓
1995: UML 0.8 – projekt wydany
     ↓
1996: OMG wydaje zaproszenie do ofert na standardowy język modelowania
     ↓
1997: UML 1.1 przyjęty przez OMG (14 listopada)
     ↓
2000: UML 1.3 oficjalnie opublikowany
     ↓
2003: UML 1.5 opublikowany; struktura UML 2.0 zaakceptowana

Dlaczego UML wygrał „Wojnę metod”

  • Zintegrowało ponad 50 konkurencyjnych metod programowania obiektowego w jedną standardową

  • Wspierane przez największych graczy branżowych (IBM, Microsoft, Oracle, HP)

  • Zapewniło mechanizmy rozszerzania do dostosowania

  • Stało się standardem de facto dla modelowania obiektowego

⚠️ Krytyczna perspektywa: Niektórzy twierdzą, że UML to „potworny język zaprojektowany przez komitet” z nieprecyzyjną semantyką w wersjach wczesnych.


🔹 Klasy i atrybuty

Struktura klasy

Klasa UML jest przedstawiana jako prostokąt z maksymalnie trzema komórkami.

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

Składnia deklaracji atrybutu

[widoczność] nazwa[mnożność]: Typ [= wartość domyślna] {właściwości}

Przykłady PlantUML:

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

Zakres atrybutu

  • Zakres instancji (domyślne): Każda instancja ma własną wartość

  • Zakres klasy (statyczne): Jedna wartość współdzielona przez wszystkie instancje

@startuml
class Student {
  name: String
  {static} count: Integer
}
@enduml

Klucze w UML ⚠️

Ważyne ograniczenie: UML nie ma wbudowanego pojęcia kluczy. Użyj stereotypów lub wartości oznaczeń jako obejścia.

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


🔹 Powiązania i relacje

Podstawowe powiązanie i wielkość

@startuml
class Exercise
class Chapter
Exercise "0..*" -- "1..1" Chapter : NależyDo
@enduml

Interpretacja: Każde ćwiczenie należy do dokładnie jednego rozdziału; rozdział może zawierać zero lub więcej ćwiczeń.

Nazwy ról

Zamiast (lub dodatkowo do) nazw powiązań, użyj nazw ról na końcach powiązań:

@startuml
class Person
class Company
Person "0..*" --> "0..1" Company : Pracownik/Pracodawca
@enduml

Realizacja: The Osoba tabela miałaby klucz obcy pracodawca odsyłający do Firma.

Dostępność

Określ kierunek przemieszczania się za pomocą strzałek:

@startuml
class Exercise
class Chapter
Exercise "0..*" --> "1" Chapter
@enduml

  • Strzałka wskazuje kierunek efektywnego przemieszczania

  • W OODB: implementowane jako wskaźnik tylko w jednym kierunku

  • W RDBMS: połączenia działają w obu kierunkach niezależnie

Typy kolekcji z {uporządkowane}

@startuml
class Chapter
class Exercise
Chapter "1" -- "0..*" Exercise : {ordered}
@enduml

  • {uporządkowane}: Zachowaj kolejność (użyj listy, a nie zbioru)

  • Realizacja w RDBMS: Dodaj atrybut numeru kolejności

ĆWICZENIA (
    id PRIMARY KEY,
    chapter_id ODWOŁUJE SIĘ DO ROZDZIAŁY,
    sort_no INTEGER,
    UNIQUE (chapter_id, sort_no)
)

Wyróżniki

Wyróżniki dzielą powiązane obiekty przy użyciu mechanizmu przypominającego klucz:

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

Znaczenie: Dla danego rozdziału i numeru ćwiczenia zwracane jest co najwyżej jedno ćwiczenie.

Klasy połączeń

Gdy połączenie ma atrybuty lub operacje:

@startuml
class Student
class Exercise
class Solution {
  date: Date
  points: Integer
}
Student "0..*" -- "0..*" Exercise : ma rozwiązane
Solution .. Student
Solution .. Exercise
@enduml

  • Jeden Rozwiązanie obiekt na parę (Student, ćwiczenie)

  • Wymusza: ten sam student nie może przesłać dwóch rozwiązań dla tego samego ćwiczenia

Kompozycja vs. Agregacja

Cecha Kompozycja (*--) Agregacja (o--)
Symbol Czarny romb Biały romb
Związek Część-całość, silna własność Część-całość, słabe odwołanie
Cykl życia Części usunięte razem z całością Części niezależne
Mnożność 1 lub 0..1 po stronie całości Dowolny
Mapowanie do RDBMS ON DELETE CASCADE Standardowy klucz obcy
@startuml
class Chapter
class Exercise
Chapter *-- "0..*" Exercise : Kompozycja
Chapter o-- "0..*" Exercise : Agregacja
@enduml


🔹 Operacje i metody

Składnia deklaracji operacji

@startuml
class Calculator {
  + getTotal(studID: Integer, inclExtra: Boolean = true): Float {isQuery=true}
  + {static} getInstance(): Calculator
  + {constructor} Calculator(initialValue: Float)
  - recalculate(): void
}
@enduml

Specyfikacja parametrów:

[kierunek] nazwa: Typ [= wartośćDomyślna]
  • Kierunki: wejście (domyślne), wyjściewejście/wyjście

  • Wartości domyślne umożliwiają parametry opcjonalne

Specjalne stereotypy operacji

Stereotyp Cel
{isQuery=true} Gwarantuje brak modyfikacji stanu
{konstruktor} Tworzy i inicjuje nowe instancje
{statyczny} Operacja na poziomie klasy, brak implikowanegoself

Operacje w kontekście bazy danych

Kulturowy konflikt: OO podkreśla hermetyzację; relacyjny podkreśla bezpośredni dostęp do danych.

Strategie implementacji:

Typ operacji Implementacja RDBMS
Prosty dostęp do atrybutu Bezpośredni SELECT/UPDATE
Wyprowadzony atrybut (bez parametrów) Widok bazy danych
Wyprowadzony atrybut (z parametrami) Procedura składowana lub logika aplikacji
Złożone zapewnienie ograniczeń Wyzwalacze lub procedury aplikacji

🔹 Ogólnienie i dziedziczenie

Podstawowe ogólne

@startuml
class Osoba
class Student
class Profesor
Osoba <|-- Student
Osoba <|-- Profesor
@enduml

Klasy abstrakcyjne i operacje

@startuml
abstrakcyjna klasa Account {
  - balance: Float
  + deposit(amount: Float): void
  + {abstrakcyjna} withdraw(amount: Float): void
}
@enduml

Ograniczenia uogólnienia

@startuml
class Person
class Student
class Professor
class OtherPerson
Person <|-- Student : <<{rozłączne, pełne}>>
Person <|-- Professor : <<{rozłączne, pełne}>>
Person <|-- OtherPerson : <<{rozłączne, pełne}>>
@enduml

Wielokrotna klasifikacja / Dyskryminatory

@startuml
class Employee
class Staff
class Faculty
class HMO
class NonHMO
Employee <|-- Staff : <<rodzaj>>
Employee <|-- Faculty : <<rodzaj>>
Employee <|-- HMO : <<ubezpieczenie>>
Employee <|-- NonHMO : <<ubezpieczenie>>
@enduml

  • Dyskryminatory grupują wzajemnie wykluczające się specjalizacje

  • Obiekty mogą mieć jedną wartość na wymiar dyskryminatora


🔹 Mechanizmy rozszerzalności

UML zapewnia trzy mechanizmy rozszerzalności:

1. Stereotypy<< >>

Rozszerz semantykę UML poprzez tworzenie nowych „podtypów” elementów metamodelu.

@startuml
class Customer <<encja>> {
  - id: Integer
  - name: String
}
class MathLibrary <<użyteczność>> {
  + sin(x: Float): Float
  + cos(x: Float): Float
}
@enduml

2. Wartości oznaczeń{klucz=wartość}

Dodaj niestandardowe właściwości do elementów modelu.

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

3. Ograniczenia {...}

Dodaj ograniczenia semantyczne przy użyciu dowolnego tekstu, OCL lub zdefiniowanych skrótów.

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


🔹 UML do projektowania bazy danych: kluczowe aspekty

Przekształcanie UML w schemat relacyjny

Konstrukcja UML Realizacja relacyjna
Klasa Tabela
Atrybut Kolumna
Klucz podstawowy {pk} Ograniczenie PRIMARY KEY
Związek (1:*) Klucz obcy po stronie „wiele”
Związek (:) Tabela pośrednicząca/przecięcia
Kompozycja Klucz obcy + ON DELETE CASCADE
Klasa asocjacji Tabela z złożonymi kluczami obcymi + atrybutami
Uogólnienie Oddzielne tabele (z kluczami obcymi) lub jedna tabela z rozróżnieniem typu
{uporządkowane} asocjacja Dodaj kolumnę sekwencji + ograniczenie unikalności
Wyróżnik Część klucza złożonego lub kolumny indeksowanej

Kluczowe różnice: obiektowe vs. relacyjne

Aspekt Obiektowe Relacyjne
Tożsamość Odwołanie do obiektu (zastępcze) Klucz podstawowy (biznesowy lub zastępczy)
Operacje Jądro projektowania, hermetyzowane Zewnętrzne (SQL, procedury)
Hermetyzacja Prywatne atrybuty, publiczny interfejs Domyślne bezpośredni dostęp do tabeli
Dziedziczenie Wsparcie dla języka naturalnego Złożone strategie mapowania
Relacje Wskaźniki/odniesienia Klucze obce i połączenia

Prawdopodobne rekomendacje dla projektantów baz danych

  1. Jawnie modeluj klucze: Użyj {pk}{ak1} stereotypy, ponieważ UML nie obsługuje domyślnie kluczy

  2. Zaznacz trwałość: Użyj {persistent} wartość oznaczoną, aby odróżnić klasy bazodanowe od klas aplikacji tymczasowych

  3. Uprość operacje: Mapuj operacje zapytań na widoki; złożone operacje na procedury przechowywane

  4. Ostrożnie traktuj dziedziczenie: Wybierz strategię mapowania na podstawie wzorców zapytań

  5. Dokumentuj ograniczenia: Użyj OCL lub jasnych ograniczeń tekstowych dla reguł biznesowych

  6. Ostrożnie używaj klas asocjacji: Tylko wtedy, gdy relacja ma istotne atrybuty


🎯 Szybki arkusz referencyjny

Podsumowanie notacji diagramu klas PlantUML

@startuml
klasa <<stereotype>> NazwaKlasy {
  {tagged=value}
  [+/-/#/~] nazwa[mult]: Typ [= val] {props}
  [+/-/#/~] nazwa(parametry): Wyn {props}
}
@enduml

Notacja asocjacji

@startuml
KlasaA "multA" -- "multB" KlasaB : NazwaAsocjacji
KlasaA *-- KlasaB  ' Kompozycja
KlasaA o-- KlasaB  ' Agregacja
KlasaA --> KlasaB  ' Kierowalność
@enduml

Symbole widoczności

  • + Publiczny

  • - Prywatny

  • # Chroniony

  • ~ Pakiet

Właściwości i ograniczenia wspólne

  • {statyczny} / {isQuery=true} / {abstrakcyjny}

  • {wartość >= 0} / {xor} / {uporządkowany} / {pk}


💡 Ostateczna myśl: Diagramy klas UML są potężne w modelowaniu koncepcyjnym, ale pamiętaj, że zostały zaprojektowane przede wszystkim do inżynierii oprogramowania. Przy używaniu UML do projektowania baz danych przygotuj się na rozszerzenie notacji (przez stereotypy, wartości oznaczone, ograniczenia), aby uchwycić pojęcia relacyjne, takie jak klucze, normalizacja i deklaratywne ograniczenia, które nie są naturalne dla podstawy obiektowej UML.

Przewodnik przygotowany na podstawie „Część 6: Diagramy klas UML” przez Stefana Brassa, Universität Halle, 2003. Wszystkie diagramy sformatowane w składni PlantUML w celu zapewnienia kompatybilności z nowoczesnymi narzędziami.

Leave a Reply