Wstęp

Kolejne szkolenie i kolejna walka z mitami, szkodliwymi mitami. Przypadki użycia to jedno z chyba najbardziej nadużywanych pojęć w branży IT. Do tego literatura przedmiotu jest nafaszerowana przykładami stosowania tego pojęcia w bardzo wielu kontekstach i znaczeniach, niestety nie raz z błędami. I nie chodzi o to, że tak jest a o to, że jedną z wielu metod dokumentowania systemów jest UML, który ma bardzo ścisłe sformalizowane definicje pojęć, i warto nie zapominać, że UML jest “unified” czyli ujednolicony (a nie uniwersalny!). Poza UML są inne “podejścia” do przypadków użycia, np. Alistair Cocbourn’a (podobne do ICONIX, zorientowane na przypadki użycia), a także wiele innych, nie mających z UML nic wspólnego.

Przypadek Użycia w UML

Potoczne pojmowanie “przypadku użycia czegoś” to “każdy przypadek interakcji z tym czymś” i to jest dokładnie to czym nie jest przypadek użycia w UML. Skupiam się w tym artykule na notacji UML, gdyż jest to notacja sformalizowana, zawiera ona to pojęcie w kontekście “diagramu przypadków użycia”, a liczba mitów i nieprawidłowych konstrukcji w książkach i sieci jest ogromna. Autorzy wielu z nich szermują pojęciem “przypadek użycia”, rzadko jednak podają (powołują się na) jego oryginalną definicję. Tak więc, jak już wpisujemy we wstępie tworzonej dokumentacji, że zastosowano notację UML to stosujmy ją.

Na początek semantyka diagramu przypadków użycia i to czym one nie są, a nie są kontekstem pracy aktora (specyfikacja UML 2.5.   formal-15-03-01.pdf):

Przypadek użycia reprezentuje zachowanie się systemu (przedmiot opisywany). Opisuje zachowanie się systemu będące reakcją na żądanie aktora: wygenerowanie obserwowalnego efektu dla aktora. Efektu będącego celem aktora (aktor używa systemu by ten skutek osiągnąć). Opis ten nie odnosi się do wewnętrznej budowy systemu, określony uzyskany (oczekiwany) efekt może być osiągniętym różnymi wariantami zachowania systemu (chodzi o alternatywne scenariusze). Młotek ma jeden przypadek użycia, jest nim uderzenie w gwoździa (albo nawet ogólnie uderzenie w coś). Jest wykorzystywany przez aktora w wielu kontekstach, ale to aktor je zna i rozumie.

Bardzo częsty błąd wielu tworzonych “diagramów UML” to skutek tezy, że user story modelujemy jako use case, jednak przypadek użycia nie jest tym po co (powód) aktor użył systemu. Przypadek użycia jest tym co robi ten system w odpowiedzi na żądanie aktora. Przede wszystkim Przypadki użycia opisują zachowanie i reakcje systemu a nie aktora i jego cele. Aktor z definicji jest “poza systemem” (jego cele także). User Story to co najwyżej konteksty aktora (patrz diagram powyżej). Tragedią pewnego dużego projektu jaki przyszło mi “ratować” było to, że oprogramowanie, które miało tylko przyjmować dane z pomocą jednego z 52 formularzy, zostało opisane z pomocą 421 przypadków użycia!

Kolejna ważna rzecz: przypadki użycia opisują zachowanie (reakcję) systemu ale nie opisują (nie odwołują się) do jego wewnętrznej struktury. Nie ma w UML czegoś takiego jak “systemowe przypadki użycia”, nie jest przypadkiem użycia to, że “system ma automatycznie powiadamiać użytkownika z pomocą SMS” i masa innych podobnych “rzeczy”. To cecha mechanizmu, który w nim zaimplementowano (wymagano go), są to elementy mechanizmu działania systemu (scenariusze czyli diagramy sekwencji oraz struktura czyli diagramy klas, komponentów i rozlokowania).

Trzeba też pamiętać, że akurat ten diagram UML (przypadków użycia), może służyć metodom innym, opartym na strukturalnych opisach i autorzy specyfikacji UML mają to na uwadze:

The behaviors of a UseCase can be described by a set of Behaviors (through its ownedBehavior relationship), such as Interactions, Activities, and StateMachines, as well as by pre-conditions, post-conditions and natural language text where appropriate. It may also be described indirectly through a Collaboration that uses the UseCase and its Actors as the Classifiers that type its parts. Which of these techniques to use depends on the nature of the UseCase behavior as well as on the intended reader.

Dlatego, jeżeli model ma zawierać konstrukcje nietypowe dla UML należy to zadeklarować. Standardową konstrukcją strukturalną (nie obiektową) pozostawioną przy diagramach przypadków użycia w UML są wydzielone warunkowe i wspólne elementy kodu: <<extend>> i <<include>>. Ale należy pamiętać, że to “reliktowe narzędzia” bo specyfikacja jasno mówi, że Przypadki Użycia (generalne) w UML to nazwane zachowania Systemu nie odnoszące się wewnętrznej architektury:

18.1.3.1 Use Cases and Actors […] UseCases define the offered Behaviors of the subject without reference to its internal structure.

Trzeba pamiętać, że wyłączanie fragmentów scenariuszy (związki include i extend) to wyłącznie strukturalizacja scenariuszy (kodu) przypadków użycia i opisywanie “wewnętrznej struktury kodu” a nie tworzenie “nowych niezależnych przypadków użycia”, konstrukcje mająca sens jeżeli stosujemy rozbudowane metody tekstowe (język naturalny) lub tabelaryczne dokumentowania wymagań (wtedy te opisy lub tabele są kojarzone z tymi wydzielonymi przypadkami użycia). Warto pamiętać, że organizacja OMG musi “trzymać” kompatybilność wstecz (masa dokumentacji jaka powstała i nadal istnieje) oraz nadal uznaje, że ten diagram “nadaje się” do użycia w metodykach nieobiektowych, zorientowanych także na opisy (to chyba najbardziej uniwersalny i otwarty diagram). Nie zmienia to faktu, że używając tego diagramu w kontekście metod obiektowych należy “trzymać się” paradygmatu obiektowego.

Bardzo ważne jest zrozumienie, że przypadki użycia to abstrakcja opisująca to czego oczekujemy od narzędzia (oprogramowanie) a nie to jak to będzie faktycznie realizowane, bo to opisują scenariusze i storyboardy. Aktor ma swoje cele, używa narzędzia dla określonego efektu, całość pracy jaką ma wykonać aktor ma swój kontekst np. w procesach biznesowych. Z perspektywy modeli MDA (modele CIM, PIM, PSM), diagram przypadków użycia to łącznik pomiędzy CIM a PIM (kontrakt określający wymagane usługi zamawianego oprogramowania).

Modelowanie zakresu

Autor modelu przypadków użycia powinien się więc skupić się na kontrakcie na wykonanie aplikacji oraz na tym, że opisuje na tym etapie wyłącznie usługi tej aplikacji a nie intencje aktora. Jak już wspomniano w samej specyfikacji UML, diagram przypadków użycia nie służy do ujawniania (planowania) struktury (architektury) aplikacji, od tego w UML są inne diagramy. Nie służy także do pokazywania różnych sposobów realizowania wymagań jakościowych (poza-funkcjonalnych). Logowanie nie jest powodem zakupu oprogramowania, logowanie to jedna z możliwych implementacji cechy “tylko autoryzowany użytkownik może korzystać z aplikacji”, co nie przeszkadza większości amatorów używania tych diagramów (i autorów książek) potraktowania logowania jako przypadku użycia aplikacji. Dobrym testem sensu umieszczania takich rzeczy na diagramach przypadków użycia jest zadawanie sobie pytania: “czy kupił byś tę aplikację tylko dla tego jednego przypadku użycia?”

Należy zrozumieć, że związek pomiędzy abstrakcją aplikacji a jej architekturą wygląda np. tak:

Typowe aplikacje projektowane i realizowane obecnie w duchu obiektowego paradygmatu, mają architekturę zgodną z wzorcem MVC. Komponenty Obsługa GUI (View w MVC) oraz Kontroler (Control w MVC) odpowiadają za poza-funkcjonalne cechy. To do czego (a nie jak) aplikacja zostanie faktycznie użyta realizuje Model (dziedziny systemu), tu jest 100% logiki biznesowej rozumianej jako wywoływane usługi oraz logika biznesowa ich realizacji.

Tak więc przypadkami użycia opisujemy abstrakcję jaką jest Model Dziedziny Systemu.  Są one wtedy proste, zawierają  scenariusz, który w skrócie ma postać: aktor inicjuje usługę, system prezentuje formularz do wypełnienia, aktor wypełnia go i potwierdza, system potwierdza odebranie danych i pokazuje wynik swojej pracy (lub komunikaty o błędach). Tu skupiamy się na opisie tego jakie usługi są wymagane od systemu. Kolejny etap to ?komplikowanie? każdego scenariusza w postaci projektowania, dla każdego przypadku użycia, który tego wymaga, różnego rodzaju wizardów lub wprowadzamy ograniczenia związane z uprawnieniami użytkowników.  Ten etap to praca projektantów UX i grafików, specjalistów od ergonomii itp. (Źródło: Panowanie nad złożonością czyli gdzie są Przypadki Użycia czyli MVVM-MVC | | Jarosław Żeliński IT-Consulting).

Owe bajery GUI a także “bezpieczne, szyfrowane” itp., są w pozostałych dwóch komponentach (View i Control).

Owszem specyfikacja UML nie zawiera recepty na “dobry model” bo to tylko opis języka a nie metody projektowania. Jednak niewątpliwie stosowanie tego języka jest tam opisane, a paradygmaty “narzucają” pewne konwencje, znaczenie pojęć i logikę tworzenia modeli z użyciem UML. Tworzenie takich diagramów jak ten poniżej nie ma żadnego sensu:

(źr. http://mirlew1.webd.pl/PSI/Projektowanie%20Systemów%20Informatycznych.htm)

UML, podobnie jak np. język polski, to znaczenia pojęć (słownik języka) i syntaktyka (zasady ich łączenia). Podobnie jak w języku polskim tak i w UML, można pisać zdania bezsensowne i zarazem poprawne gramatycznie. Poprawność diagramu to nie tylko poprawne użycie poszczególnych symboli, to przede wszystkim sensowność tego co wyraża cały diagram (który jest odpowiednikiem zdania w języku tradycyjnym, zdanie “myśl patrzy na kota” jest poprawnym gramatycznie zdaniem i pozbawionym sensu).

I tak, jeżeli diagram przypadków użycia jest częścią metod opartych na języku naturalnym i tabelach (np. metody proponowane przez Alistaira Cocbourn,a) można (ma sens) korzystanie ze struktury budowanej przez związek “include” czy “exclude”. W metodach obiektowych, w zasadzie wykluczających współdzielenie czegokolwiek między komponentami (hermetyzacja komponentów to kluczowa cecha obiektywności), ich stosowanie jest poważnym błędem (podobnie jak używanie tych związków do modelowanie “kolejności czynności” jako procesu, to jest gorszy błąd).

Kolejnym częstym błędem jest stosowanie (używanie/nadużywanie) na diagramach przypadków użycia związków generalizacji/specjalizacji i dziedziczenia. Są to pojęciowo różne związki oznaczane takim samym symbolem (strzałka z pustym grotem).

9.2.3.2 Generalization
Generalizations define generalization/specialization relationships between Classifiers. Each Generalization relates a specific Classifier to a more general Classifier. Given a Classifier, the transitive closure of its general Classifiers is often called its generalizations, and the transitive closure of its specific Classifiers is called its specializations. The immediate generalizations are also called the Classifier?s parents, and where the Classifier is a Class, its superClasses (see 11.4).
NOTE. The concept of parent (a generalization relationship between Classifiers) is unrelated to the concept of owner (a composition relationship between instances).

Specyfikacja UML (v.2.5) zawiera bogatszy opis (polecam) jednak istotne jest to, że symbol ten oznacza:

  • związek pojęciowy (słownikowy) pomiędzy pojęciem ogólniejszym i jego szczególnym przypadkiem (np. ssak jest uogólnieniem psa),
  • dziedziczenie to związek strukturalny pomiędzy strukturą ogólną (abstrakcyjnym szkieletem) a jej konkretną postacią np. implementacją (struktura dziedzicząca jest budowana na bazie szkieletu struktury od której dziedziczy swoją budowę), tak się korzysta np. z bibliotek w tworzeniu implementacji.

Warto też pamiętać, że element ogólny z zasady nie ma swoich implementacji bo jest abstrakcją (jeden z typowych i poważnych błędów w projektach obiektowych to tak zwane “wołanie przodka” czyli wywoływanie klas abstrakcyjnych, ten i inne antywzorce: http://kurs.aspnetmvc.pl/Wzorce/Antywzorce_w_programowaniu).

Spotykam się także z tezami jakoby związek realizacji był szczególnym przypadkiem dziedziczenia – to już kompletne niezrozumienie znaczenia tych symboli i nieczytanie specyfikacji UML. Realizacja to specyficzna (abstrakcyjna) forma związku “zależności” (dependency), pokazująca związek (zależność) pomiędzy opisem a implementacją wykonaną na jego podstawie.

7.7.3.4 Realization
Realization is a specialized Abstraction dependency between two sets of NamedElements, one representing a specification (the supplier) and the other representing an implementation of that specification (the client). Realization can be used to model stepwise refinement, optimizations, transformations, templates, model synthesis, framework composition, etc.

Jeżeli uznać, że ciasto na naszym stole jest realizacją przepisu na to ciasto z książki kucharskiej, to jest to taki właśnie związek: realizacja to związek pomiędzy opisem (specyfikacją) a przedmiotem, który powstał na podstawie tego opisu.

Jaki sens (znaczenie) mają związki uogólnienia/dziedziczenia na diagramie przypadków użycia i czy w ogóle mają? Przypadek użycia to konkretna usługa systemu. Dwa przypadki użycia połączone takim związkiem można więc interpretować tylko jako sytuację, w której mamy szkielet przypadku użycia i kilka – zgodnych z tym szkieletem – konkretnych przypadków użycia. Ten ogólny z zasady jest abstrakcyjny i nie można (nie ma sensu) łączyć go z jakimkolwiek aktorem. Można sobie wyobrazić sensowną konstrukcję zawierającą abstrakcyjnego aktora połączonego z abstrakcyjnym przypadkiem użycia, jako pewien szablon dla aktorów konkretnych i powiązanych z nimi konkretnymi przypadkami użycia, ale należy pamiętać, że będzie problem bo asocjacja także musiałaby mieć postać “szablonu”… (pamiętajmy, że dziedziczenie to przejęcie wszystkich cech, związków także).

Spotykam często diagramy nazywane diagramami aktorów, drzewiaste struktury aktorów, ich obrona  jako czegoś sensownego będzie bardzo trudna… Tym bardziej, że ludzie (role, stanowiska) nie dziedziczą po sobie niczego. Związek pomiędzy np. szefem działu a jego podwładnym (a takie czasem widuję, modelowane jako dziedziczenie/specjalizacja) nie ma absolutnie żadnego sensu: podwładny ma inne umiejętności i uprawnienia niż przełożony. Owo dziedziczenie nie działa w żadną stronę: podwładny nie raz może robić to czego nie wolno przełożonemu (menedżer bardzo rzadko może w pełni zastąpić podwładnego i odwrotnie). Uznanie, że taki diagram modeluje (opisuje) uprawnienia w “systemie” jest z podobnego powodu nie do obrony: uprawnienia są przydzielane osobom a nie “strukturom”.

Tak więc przeciętny (nietrywialny) system ma raczej kilka do kilkunastu (a nie kilkadziesiąt czy kilkaset) przypadków użycia i złożony wewnętrzny mechanizm działania. Mechanizm działania systemu jest dokładnie tym czego nie modelujemy na diagramie przypadków użycia, bo ten jest z zasady tak zwaną “czarną skrzynką”. Z tego samego powodu nie ma sensu szacowanie kosztów wytworzenia oprogramowania na podstawie jego przypadków użycia. Rysowanie diagramów przypadków użycia bez kluczowego jego elementu jakim jest “subject” (system) też nie bardzo ma sens…

Nie raz spotykam się z oczekiwaniami, że “to duży system, spodziewam się dużo use casów”… nic bardziej błędnego… To także powód, by nie stosować metod wyceny opartych na przypadkach użycia w metodach obiektowych bo tu są nieskuteczne… 

Trzy lata temu pisałem, że dokumentowanie przypadków użycia to opis logiki systemu a nie mnożenie “jajaczek”:

Analizy biznesowe wymagają oderwania się od technokracji, nie ma czegoś takiego jak dziesiątki przypadków użycia dla jednej faktury, nie ma systemowych przypadków użycia (nawet w specyfikacji UML ich nie znajdziecie), są kompletne (dające jako efekt przydatne produkty) usługi aplikacyjne i korzystający z tych usług aktorzy, w tym inne aplikacje lub komponenty. Dokumentacje zawierające setki przypadków użycia to nieporozumienie, technokratyczni zabójcy projektów. Warto się zastanowić zanim powierzycie analizę i projekt logiki systemu technokratycznemu developerowi? Zapraszam do lektury kolejnego artykułu o zarządzaniu szczegółowością analizy.. (Źródło: Wzorzec CRUD dla przypadków użycia i mikroserwisy | | Jarosław Żeliński IT-Consulting)

Po szczegóły zapraszam na moje szkolenia z “analizy obiektowej z użyciem notacji UML“.

Na zakończenie

Gorąco pole­cam pro­gra­mi­stom, by w ogó­le zaczę­li korzy­stać z UML a ana­li­ty­kom, by wyle­czy­li się z wie­lu mitów o UML roz­po­wszech­nia­nych nie­ste­ty na wie­lu, nie zawsze tanich, szko­le­niach i w wie­lu kiep­skich ??porad­ni­kach UML? (pisa­nych nie raz nawet przez uczel­nia­nych dok­to­rów i nie tyl­ko).?. Może wte­dy prze­sta­ną two­rzyć nie­przy­dat­ne deve­lo­pe­rom dokumentacje.

Source: UML for Java programmers – Jarosław Żeliński IT-Consulting

Jarosław Żeliński

Jarosław Żeliński: Od roku 1991 roku, nieprzerwanie, realizuje projekty z zakresu analiz i projektowania systemów, dla urzędów, firm i organizacji. Od 1998 roku prowadzi samodzielne studia i prace badawcze z obszaru analizy systemowej i modelowania (modele jako przedmiot badań: ORCID). Od 2005 roku, jako wykładowca akademicki wizytujący (nieetatowy), prowadzi wykłady i laboratoria (ontologie i modelowanie systemów informacyjnych, aktualnie w Wyższej Szkole Informatyki Stosowanej i Zarządzania pod auspicjami Polskiej Akademii Nauk w Warszawie.) Oświadczenia: moje badania i publikacje nie mają finansowania z zewnątrz, jako ich autor deklaruję brak konfliktu interesów. Prawa autorskie: Zgodnie z art. 25 ust. 1 pkt. 1) lit. b) ustawy o prawie autorskim i prawach pokrewnych zastrzegam, że dalsze rozpowszechnianie artykułów publikowanych w niniejszym serwisie jest zabronione bez indywidualnej zgody autora (patrz Polityki Strony). Konsultacje: wszelka pomoc i wyjaśnienia dotyczące treści artykułów autora bloga udzielana jest wyłącznie w ramach płatnych konsultacji.