Diagram UML - Wprowadzenie
Chyba każdy słyszał o zasadzie "Zmierz dwa razy, tnij raz". To szczera rada w programowaniu. Zawsze lepiej jest zaplanować implementację, zanim poświęcisz czas na jej realizację. Podczas implementacji, często trzeba tworzyć klasy i wymyślać, jak będą ze sobą współdziałać. Wizualne przedstawienie tego wszystkiego często może pomóc w znalezieniu najbardziej właściwego rozwiązania. To tutaj właśnie UML przychodzi nam z pomocą.Czym są diagramy UML?
Jeśli spojrzysz na odpowiednie obrazy w wyszukiwarkach, zauważysz, że w języku Java UML ma coś wspólnego z diagramami, strzałkami i kwadratami. Musisz wiedzieć, że UML to skrót od Unified Modeling Language. Unified (zunifikowany) jest tu ważnym słowem. Oznacza to, że nasze obrazy będą rozumiane nie tylko przez nas, ale także przez każdego, kto zna użycie UML w Java. Jest to lingua franca rysowania diagramów. Według Wikipedii,"UML jest uniwersalnym, rozwojowym, modelującym językiem w dziedzinie inżynierii oprogramowania, celem którego jest zapewnienie standardowego sposobu wizualizacji projektu systemu". |
Użycie
Sprawdźmy, czy możemy pracować z UML w środowisku IDE. Użyjemy IntelliJ IDEA jako naszego IDE. Jeśli używasz IntelliJ IDEA Ultimate, wtedy będziemy mieli zainstalowaną wtyczkę "UML Support" "po wyciągnięciu z pudełka". Pozwala to na automatyczne generowanie pięknych diagramów klas. Na przykład użyj Ctrl + N lub pozycji menu "Nawiguj" -> "Klasa", aby przejść do klasy ArrayList. Teraz w menu kontekstowym nazwy klasy wybierz "Diagram" -> "Pokaż wyskakujące okienko diagramu". W rezultacie otrzymujemy piękny diagram.

@startuml
class ArrayList {
}
class LinkedList {
}
@enduml
Aby zobaczyć wynik w IDEA, wybierz "Widok" -> "Okna narzędziowe" -> "PlantUML". Otrzymujemy tylko dwa kwadraty, które reprezentują klasy.
Wiemy, że obie te klasy implementują interfejs List. Ta relacja klas nazywana jest implementacją. Ta relacja przedstawiona jest za pomocą strzałki z przerywaną linią. Narysujmy to:
interface List
List <|.. ArrayList
List <|.. LinkedList
List jest jednym z elementów podrzędnych klasy Collection. Oznacza to, że dziedziczy Collection. Tę relację nazywa się generalizacją. Wygląda jak strzała ze zwykłą ciągłą linią. Narysujmy to:
interface Collection
Collection <|-- List
Dla następnego typu relacji dodaj do opisu klasy ArrayList wpis dot. tablicy elementów package private:
~Object[] elementData
Teraz chcemy pokazać, że ArrayList zawiera pewne obiekty. W takim przypadku wystąpi relacja agregacji.
ArrayList jest agregatem, ponieważ zawiera inne obiekty. Mówimy o agregacji, ponieważ obiekty listy mogą istnieć bez listy: nie są jej integralnymi częściami. Ich trwałość nie jest związana z okresem istnienia listy. Słowo "agregat" przychodzi do nas z łaciny i tłumaczone jest jako "skupisko", czyli całość, która składa się z grupy elementów. Na przykład w życiu codziennym mamy zespół pompowy (agregat), który składa się z pompy i silnika. Sam zespół może zostać zdemontowany, a niektóre jego elementy można wykorzystać osobno. Na przykład sprzedać lub umieścić w innym zestawie. Tak samo jest w liście. Wyraża się to pustym rombem w agregacie i linią ciągłą. Przedstawimy to w następujący sposób:
class Object {
}
ArrayList o- Object
Teraz chcemy pokazać, że w przeciwieństwie do ArrayList, klasa LinkedList zawiera instancje Node - kontenery, które odwołują się do przechowywanych danych. W tym przypadku instancje Node są częścią LinkedList i nie istnieją niezależnie. Node nie jest treścią samą w sobie. Zawiera tylko odniesienie do tej treści. Na przykład, kiedy dodajemy ciąg do LinkedList, dodajemy nowy Node, który zawiera odniesienie do ciągu, a także łącze do poprzedniego i następnego Node.
Tę relację nazywa się kompozycją. Przedstawia się ją poprzez narysowanie ciągłej linii z wypełnionym rombem na kompozycie (coś wykonanego z elementów składowych). Teraz przedstawimy relację jako tekst:
class Node {
}
LinkedList *-- Node
A teraz musisz nauczyć się przedstawiać inny ważny rodzaj relacji: zależność. Jest używana, gdy jedna klasa używa innej, ale nie zawiera ani nie dziedziczy klasy używanej. Na przykład LinkedList i ArrayList wiedzą, jak utworzyć ListIterator. Przedstawiamy to jako strzałki z przerywaną linią:
class ListIterator
ListIterator <... ArrayList : create
ListIterator <... LinkedList : create
Po wykonaniu tego wszystkiego otrzymujemy: 

Automatyzacja
Istnieją różne sposoby automatycznego generowania diagramów PlantUML. Na przykład, IDEA posiada wtyczkę SketchIT, ale nie rysuje ona diagramów całkowicie poprawnie. Powiedzmy, że implementacja interfejsów rysowana jest nieprawidłowo (jest wyświetlana jako dziedziczenie). W Internecie znaleźć można przykłady, jak to zintegrować z procesem budowania projektu. Na przykład można dowiedzieć się, jak używać uml-java-docklet razem z Maven. Aby to zademonstrować, użyjemy Archetypu Mavena, żeby szybko stworzyć projekt Maven. Uruchommvn archetype:generate
W odpowiedzi na Wybierz liczbę lub zastosuj filtr, pozostaw wartość domyślną - po prostu naciśnij Enter. Zawsze będzie to "maven-archetype-quickstart". Wybierz najnowszą wersję. Następnie odpowiemy na kilka pytań i zakończymy tworzenie projektu: 
mvn clean install
i
mvn javadoc: javadoc
Jeśli teraz otworzymy wygenerowaną dokumentację (explorer target\site\apidocs\index.html), zobaczymy diagramy UML. Nawiasem mówiąc, relacja implementacji jest teraz wyświetlana poprawnie :)
Wniosek
Jak widzisz, UML pozwala na wizualizację struktury twojej aplikacji. Ale UML potrafi znacznie więcej. Możesz użyć UML do opisania różnych procesów w twojej firmie lub do opisania procesu biznesowego obejmującego funkcję, którą piszesz. Od twojej decyzji zależy jak bardzo przydatny jest dla ciebie UML, ale bez względu na to, co postanowisz, warto znaleźć czas, aby dowiedzieć się o nim więcej.Ten artykuł przeczytasz także po angielsku. |
---|
Read the English version of this article to gain insights into UML diagrams. When you understand the conventions of UML class diagrams, you can quickly and reliable communicate important class properties, behaviors, and relationships. |
GO TO FULL VERSION