Języki

Erudis - your road to knowledge
Dokumentowanie statycznej struktury projektu

Skoro mówimy o dokumentowaniu kodu w UML to zacząć musimy od diagramu klas. Z tego prostego powodu, że będzie to fundament na którym będzie się cała nasza dokumentacja opierała. W Enterprise Architect musimy stworzyć nowy projekt i utworzyć w nim widok (prawy przycisk na głównym elemencie Model i New View...), w którym znajdą się nasze klasy. Ja nazwałem ten widok „Model projektowy” i zaimportowałem do niego katalog rozwiązania Visual Studio 2008. Aby zaimportować kod musimy kliknąć prawym przyciskiem na widoku i wybrać Code Engineering --> Import Source Directory następnie w oknie które się pojawi wybieramy katalog i zaznaczamy opcję Recursively Process Subdirectories oraz Create Package Per Namespace. Po imporcie dostajemy strukturę projektu taką jak na rysunku 3.

Struktura projektu przykładowego po imporcie

Rysunek 3. Pierwsze kroki – struktura zaimportowanego kodu w Enterprise Architect.

Specyficzne słowa kluczowe i UML
Klasy częściowe nie istniały w czasie gdy definiowano UML i ze względu na ograniczone wsparcie w językach nie trafiły do standardu jako jedna z właściwości klasy, ale dzięki wyjątkowej elastyczności UML nie było problemu żeby je dodać do modelu. Jeżeli zaznaczycie na diagramie klasę formatki np.: FrmProblemNew to po otwarciu okna z metkami (View --> Tagged values) zobaczycie nową metkę która się nazywa partial i ma wartość true. Innym przykładem jest słówko override użyte dla metody ToString(), ta metoda będzie miała metkę override=true.
Innym rodzajem rozszerzenia będzie stereotyp «property» zastosowany dla operacji by zaznaczyć właściwość, w niektórych przypadkach do stereotypu będzie również przyczepiona metka, np.: readonly=true dla operacji Person.FullName().

Niestety Enterprise Architect zbyt dokładnie zrobił to co mu kazaliśmy i w tej strukturze znajdują się pliki, które możemy bądź chcemy pominąć. Szczególnie będzie to dotyczyło tych elementów które są generowane przez Visual Studio automatycznie. Na liście prawie na pewno nie powinna się znaleźć klasa Program, oraz pakiet Properties. Usuwamy je z listy i rozwijamy pakiet Forms a w nim znajdujemy podwojone nazwy klas reprezentujących formatki. Oczywiście wynika to ze struktury projektu i użycia klas oznaczonych słowem kluczowym partial.

Klasę wygenerowaną łatwo rozpoznać po dużej ilości atrybutów, które będą odpowiadały kontrolkom np.: label1, label2, etc. Takie klasy najlepiej jest usunąć z modelu po to by uniknąć wygenerowania tam dodatkowych elementów i zwykłej ludzkiej pomyłki.

Diagram, który automatycznie powstanie w trakcie importu dla każdego pakietu/przestrzeni nazw będzie zazwyczaj mało czytelny ponieważ znajdą się na nim wszystkie wykryte relacje pomiędzy wszystkimi elementami przestrzeni nazw. Niestety nie zawsze wszystkie relacje są wykrywane. Enterprise Architect ma problem z narysowaniem relacji opisywanych przez typy generyczne np.: List<Person>. Nie wpływa to na generowany kod ale niestety wpływa na czytelność diagramu. Jeżeli widać zbyt mało relacji to niestety możemy je jedynie dodać ręcznie. Jeżeli jest ich za dużo to mamy dwie drogi, pierwsza to pochowanie relacji, które nas nie interesują, a druga to podzielenie diagramu na mniejsze diagramy pogrupowane tematycznie. W prezentowanym projekcie część podziału została zrobiona automatycznie w związku z podziałem na przestrzenie nazw w kodzie.

Wykrywanie elementów architektury
Narzędzie samo niestety nie potrafi zgadnąć, że zastosowaliśmy w kodzie pewne wzorce projektowe. W przykładzie jest klasa Workflow, która jest implementacją wzorca singleton. Warto konstrukcje architektoniczne, które widzimy zaznaczyć jeżeli model ma się stać dokumentacją. W przypadku singletona wystarczy nadanie klasie Workflow stereotypu singleton, dla innych wzorców konieczne może być stworzenie diagramu złożonych struktur i zdefiniowanie obiektu collaboration dla znalezionego wzorca.
Diagram modelu klas

Rysunek 4. Diagram modelu klas

Diagram formatek aplikacji

Rysunek 5. Diagram formatek aplikacji z dodatkową klasą ProblemData z innego pakietu.