W artykule Ile przypadków użycia opisałem przypadki użycia jako narzędzie definiowania zakresu projektu, czyli sposób dokumentowania wymagań. Takie jego zastosowanie jest zdefiniowane w specyfikacji UML .
Tym razem chcę ostrzec przed bezkrytycznym „uczeniem się” ze stron internetowych, nawet tych uznawanych powszechnie za „dobre i popularne”. Sam niektóre z nich polecam, ale coraz częściej, nie całe serwisy jako takie, a tylko określone artykuły. Modernanalyst.com też do nich należy. Dziś będzie to artykuł, którego nie polecam, a opiszę go, bo autor powiela w nim dość powszechne błędy notacyjne, błędy które stały się „kanonem” dla wielu autorów stosujących UML.
Poniżej diagram przypadków użycia ze związkami 'include’ i 'extend’.
W UML zależności 'include’ i 'extend’ są reliktem analizy strukturalnej (diagramy przypadków użycia wymyślono w latach 80-tych). Związek 'include’ służy do wyłączania części wspólnej zachowań (scenariuszy) przypadków użycia, w konsekwencji: (1) muszą być co najmniej dwa bazowe przypadki użycia by można było mówić o części wspólnej, (2) część wspólna jest jedynie fragmentem, więc sama (samodzielnie) jako taka do niczego nie służy, więc nie wolno z nią łączyć żadnego aktora . Powyższy rysunek łamie obie te zasady. Zależność 'extend’, to zawarte w przypadku użycia, warunkowe rozszerzenie określonego zachowania i obligatoryjne jest podanie warunku (zdarzenia) uruchamiającego to dodatkowe zachowanie . Tu także tę zasadę złamano.
A gdy projekt jest „obiektowy”? Specyfikacja UML jasno mówi: Use Case define the offered Behaviors of the subject without reference to its internal structure . Tak więc tych związków po prostu nie używamy w projektach, o których mówimy, że są obiektowe, bo łamią podstawową zasadę paradygmatu obiektowego jaką jest hermetyzacja.
Kolejne nadużycie to stosowanie generalizacji na diagramie przypadków użycia: nie jest przewidziana dla tego diagramu (a dziedziczenie zostało słusznie z UML usunięte w 2015 roku wraz z opublikowaniem wersji 2.5 UML). Zachowania systemu to określone odrębne (hermetyzacja) elementy, tu także obowiązuje zasada nie stosowania diagramu UML do opisu architektury systemu/kodu. Po drugie, nawet gdyby autor miał na myśli stare „dziedziczenie”, to co do zasady nie łączymy aktorów z elementami abstrakcyjnymi modelu („wołanie przodka” to dawno temu opisany antywzorzec obiektowy).
Poniżej diagram profilu UML definiujący pojęcie przypadek użycia (sprawne korzystanie z notacji UML wymaga umiejętności czytania tego diagramu). I cóż my tu mamy? Należy to interpretować tak: związki 'extend’ i 'include’ to integralne części ich przypadków użycia, są to związki skierowane, przypadek rozszerzany MUSI mieć punkt rozszerzenia (rozszerzający). Nie ma tu w ogóle możliwości użycia generalizacji między elementami na tym diagramie.
Data publikacji tego artykułu: 5 styczeń 2020, czyli jego autor pisał to pięć lat po publikacji UML v.2.5! Zaś, miejsce publikacji tego tekstu to zacny serwis Modern Analyst:
What can Modern Analyst do for YOU?
Let Modern Analyst help you gain an edge over your competition!Whether you are a training provider, an experienced practitioner, a tool vendor, or a recruiter focusing on business systems analysis, make Modern Analyst work for YOU. (źr.: What can Modern Analyst do for YOU?)
Autor sam o sobie:
Author: Mr. Monteleone holds a B.S. in physics and an M.S. in computing science from Texas A&M University. He is certified as a Project Management Professional (PMP?) by the Project Management Institute (PMI?), a Certified Business Analysis Professional (CBAP?) by the International Institute of Business Analysis (IIBA?), a Certified ScrumMaster (CSM) and Certified Scrum Product Owner (CSPO) by the Scrum Alliance. He holds an Advanced Master’s Certificate in Project Management and a Business Analyst Certification (CBA?) from George Washington University School of Business. Mark is also a member of the Association for the Advancement of Cost Engineering (AACE) and the International Association of Facilitators (IAF). |
Nie rzadko słyszę, że „ale ten diagram ma pokazać jak system działa”. Niestety ten diagram nie służy do „pokazania” (dokumentowania) tego, jak działa aplikacja. Do tego służą inne diagramy (oznaczone na poniższym schemacie blokowym, diagramy aktywności służą obecnie do modelowania kodu wiec nie są używane na etapie analizy i projektowania, lub tylko do dokumentacji algorytmów) . Jest to – diagram przypadków użycia – od 2015 roku, diagram pomocniczy, służący wyłącznie do określenia zakresu projektu, czyli wymagań. Autorzy specyfikacji piszą: „Use Case are a means to capture the requirements of systems, i.e. what systems are supposed to do” (Przypadek użycia jest sposobem na uchwycenie wymagań na systemy, tj. tego CO systemy mają zrobić [dla aktora, a nie JAK]).
Często słyszę zarzuty, że „diagramy UML i dokumenty je zawierające, nie pomagają developerom, dlatego nie używamy UML”. No cóż, ale diagramy, jak ten tu opisany, i nie raz jak te na stronach Wikipedii czy Stackoverflow, prezentują podobny poziom, i faktycznie nie są przydatne… A stosowanie diagramów przypadków użycia do opisu „procesów” (łańcuchy 'extend’ i 'include’) to wręcz epidemia.. ;). Przypominam także, że logowanie to nie przypadek użycia (use case) aplikacji, a funkcjonalność środowiska aplikacji (są też inne metody uwierzytelniania użytkownika).
Dlatego polecam źródła rzetelnej wiedzy o notacjach, a są to oryginalne specyfikacje, których umiejętność czytania jest podstawową umiejętnością dobrego analityka i projektanta. Tu nie chodzi o „głupie bycie ortodoksem”, chodzi o JEDNOZNACZNOŚĆ dokumentacji, czyli i autor dokumentu i jego adresat, powinni używać tego samego „kodu”, czyli stosować się do specyfikacji używanej notacji. Bez tego mamy wyłącznie nieporozumienia i dodatkowe koszty w projektach.
W rankingach przyczyn porażek projektów, niejednoznaczność dokumentacji zawsze jest w pierwszej trójce.
>Poniżej diagram profilu UML definiujący pojęcie przypadek użycia (sprawne korzystanie z notacji UML wymaga umiejętności czytania tego diagramu). I cóż my tu mamy? Należy to interpretować tak: związki ?extend? i ?include? to integralne części ich przypadków użycia, są to związki skierowane, przypadek rozszerzany MUSI mieć punkt rozszerzenia (rozszerzający). Nie ma tu w ogóle możliwości użycia generalizacji między elementami na tym diagramie.
Idąc tym tropem myślenia tak samo nie ma możliwości używania generalizacji w przypadku klas (ang. Class). W specyfikacji UML w rozdziale 11.4.2 znajduje się rysunek analogiczny do przedstawionego diagramu dla przypadków użycia. Na tym rysunku także nie ma opisanej możliwości używania generalizacji.
Czy w związku z tym autor artykułu nie dopuszcza używania generalizacji na diagramach klas?
Generalizacja to związek pojęciowy a nie strukturalny. Diagram klas może być użyty do pokazania struktury pojęciowej i wtedy używamy asocjacji i generalizacji (taksonomie). Diagram klas może być użyty do pokazania struktury architektury aplikacji, nie wtedy może zawierać generalizacji a jedynie związki zależności, ewentualnie kompozycje i realizacje. Pojęcie dziedziczenia zostało usunięte z UML.
Zwracam uwagę, że w UML wszystko jest klasą, a każdy diagram to diagram klas tyle, że z ewentualnym profilem (patrz specyfikacja MOF oraz profile standardowe w załącznikach do UML).
Dziękuję za rozróżnienie tych spraw.
>Pojęcie dziedziczenia zostało usunięte z UML.
Ciekaw jestem w jakim zakresie pojęcie dziedziczenia zostało usunięte? Niestety, UML poznałem dopiero od wersji 2.5.1 i nie rozumiem na czym polegało to usunięcie, bo nie znam wcześniejszych jego wersji.
W bieżącej specyfikacji UML w rozdziale 9.2.3.2 Generalization znalzałem pojęcie dziedziczenia członków (ang. member), więc może szczątkowo zostało ono zachowane?
Dziedziczenie zostało całkowicie usunięte z UML 🙂 (ale patrz koniec tej notatki), tak więc generalizacja pozostaje wyłącznie związkiem między pojęciami, innymi słowy: nie używamy związku generalizacji w innych modelach (np. architektury).
Member oznacza „przynależność” a nie dziedziczenie, i tłumaczone jest jako „przeniesienie cech” ale definicji. W języku polskim jest to pojęcie „definicji sprawozdawczej”. Przykład:
– czworonogi to zwierzęta poruszające się na czterech nogach
– pies to szczekający czworonóg
To oznacza, że pies, to „szczekające zwierze poruszające się na czterech nogach” (w treści definicji, pies ma cechę „porusza się na czterech nogach”). Tu pojęcie dziedziczenia oznacza wyłącznie przejęcie (zawieranie się) ogólniejszej definicji przez definicję szczegółową. Pojęcie „member” oznacza zaś „bycie elementem czegoś” i tak w taksonomiach (drzewa generalizacji) pojęcia są elementem drzewa generalizacji, a w modelach np. architektury, jej elementy mogą być elementem drzewa kompozycji. Innymi słowy „atrybut” to „member” swojej klasy, każdy element zawarty w pakiecie to jego „member”. Może „dziedziczyć” (przejmować a nie współdzielić) pewne cechy grupy do której należy.
W językach programowania pojęcie dziedziczenia oznacza włącznie współdzielenie (re-użycie) kodu (np. klasy bibliotecznej). Używanie tego związku jest jednak łamaniem hermetyzacji, podstawowej cechy paradygmatu obiektowego (dlatego między innymi został usunięty z UML).