Wstęp

Tym razem krótki artykuł na temat pewnej ciekawej konstrukcji. Została ona opisana przez Rebekę Wirfs-Brock w 1999 roku . Pomysł nie zdobył sobie wtedy raczej zbyt dużej popularności, jednak obecnie, w dobie wzorców opartych o mikroserwisy i mikro aplikacje, ma szansę wrócić do łask. Ja stosuję go już od dłuższego czasu (patrz: projektowanie zorientowane na interfejsy). Skróty HLD i LLD to odpowiednio: High-Level Design (projekt wysokiego poziomu) i Low-Level Design (projekt niskiego poziomu). Są to poziomy abstrakcji w modelu PIM. Jest to także opis stylu projektowania architektury systemu zorientowanego na interfejsy (architektura zorientowana na interfejsy).

Pakiet w UML

W notacji UML pakiety są elementem grupującym, zapewniają możliwość strukturyzacji i organizacji elementów modeli UML. Specjalnym typem pakietu jest właśnie model :

Diagram profilu dla elementu Pakiet (Package) w notacji UML. Stereotyp ‘Model’ to typ Pakietu (generalizacja u dołu diagramu)

Pakiet, jako element grupujący elementy, może więc nie tylko reprezentować (oznaczać) abstrakcję komponentu, ale także grupować jego elementy w repozytorium projektu UML i opisywać ich strukturę: wraz zawartością może stanowić model.

Pakiet jako podsystem

Skorzystała z tego Rebeka Wirfs-Brock, proponując bardzo użyteczną konstrukcję:

A UML package is an appropriate container for the objects, relationships and other model elements that are the parts of a subsystem. The package will also hold other
model elements that help specify the way these parts work together, for example, collaborations
and interactions.

Skoro więc pakiet może grupować “cokolwiek”, może więc w szczególności grupować elementy modelujące np. usługę aplikacji na poziomie specyfikacji i realizacji.

Standardowo w UML można, dla usystematyzowania modelu i struktury repozytorium, tworzyć konstrukcje jak poniżej:

Przypadek użycia i jego realizacja.

Tu warto zwrócić uwagę na to, że zgodnie ze stylem projektowania zorientowanego na interfejsy, klasy na powyższym modelu także reprezentują interfejsy, realizacje ich operacji to mogą być metody tych klas, albo wywołania interfejsów złożonych komponentów.

Wirfs-Brock proponuje umieszczenie abstrakcyjnego interfejsu wewnątrz pakietu, który graficznie jest dedykowanym symbolem dla stereotypu ‘subsystem’, ta abstrakcją może być także ww. przypadek użycia:

Przypadek użycia oraz jego realizacja wewnątrz pakietu oznaczającego Podsystem

Standardowy kształt reprezentujący pakiet na diagramach, został podzielony na obszary: operacje (abstrakcyjny interfejs), specyfikacja, realizacja. Główną zaletą tej konstrukcji, w porównaniu z “tradycyjną”, jest możliwość uporządkowania treści diagramu i struktury repozytorium, poprzez umieszczenie abstrakcji specyfikacji usługi wewnątrz pakietu, który reprezentuje także jej realizację (architekturę).

W przypadku gdy użyjemy tej konstrukcji do organizowania modeli usług aplikacji (przypadków użycia), wygląda to jak na diagramie powyżej. Konstrukcji tej można użyć z powodzeniem do innych wewnętrznych komponentów, dlatego mamy do dyspozycji dodatkową przestrzeń na pokazanie nazw operacji komponentu (pakiet, zgodnie z MOF, to także klasyfikator).

W projektach realizowanych od ogółu do szczegółu, korzystanie z tej konstrukcji jest to bardzo przydatną metodą, bo pozwala zadeklarować element modelujący komponent, a później wypełnić go treścią, zachowując od początku spójną, hierarchiczną strukturę projektu i repozytorium.

Przykład

Przykładowa struktura dla dwóch przypadków użycia wygląda jak poniżej:

Struktura modeli (diagramów) projektu architektury systemu mającego dwa przypadki użycia: górna część to HLD, dolna to LLD, czyli wewnętrzne detale (architektura) komponentów architektury HLD.

Powyższy schemat obrazuje strukturę diagramów:

  • diagram przypadków użycia to najwyższy poziom abstrakcji: specyfikuje umową jako listę wymaganych usług systemu,
  • kolejny u góry po prawej jeden diagram, to model architektury wysokiego poziomu (HLD) tego systemu, gdzie każdy przypadek użycia to osobny komponent (np. mikroserwis) mający swoją implementację, taki model pokazuje także wewnętrzną integrację tych komponentów oraz ewentualną integrację z otoczeniem (inne systemy),
  • każdy komponent, realizujący określony przypadek użycia, ma swoją odrębną wewnętrzną architekturę (LLD).

Powyższe stanowi prostą i skuteczną metodę porządkowania elementów modeli, zgodną z UML więc nie powinno być problemu z wykonaniem takiego diagramu, a jak widać niektóre narzędzia (tu Visual Paradigm) są do tego przygotowane. Jeżeli Wasze narzędzie nie oferuje dedykowanego pakietu w wersji proponowanej przez Wirfs-Brock, porządkowanie architektury z pomocą pakietów ułatwia modelowanie oraz zrozumiałość modeli i strukturę repozytorium projektu.

Podsumowanie

Czy ma sens takie modelowanie? Dlaczego nie zacząć od razu kodować? W małym projekcie zapewne byłoby to przerostem formy nad treścią (ale nie zawsze!). Jednak większe projekty realizowane “od razu w kodzie”, mają ogromne problemy ze spójnością, separacją domen (dziedzina systemu i model pojęciowy ) oraz z podejmowaniem decyzji w jakiej kolejności i co ma powstawać, bo z zasady nie powstanie od razu cały system (patrz także recenzja książki: Marsz ku klęsce).

Do tego należy dodać typowe obecnie wymaganie biznesowe: nie chcemy i nie możemy czekać na ukończenie i oddanie całego systemu, chcemy mieć możliwość jak najszybszego usprawnienia pracy i rozpoczęcia korzystania z wybranych usług systemu. Pozostałe mogą być wdrażane w umówionej kolejności, wraz z upływem czasu. Więc na pewno nie może to być monolit.

Jest to możliwe pod jednym warunkiem: całość musi zostać podzielona na odrębne i samodzielne komponenty “pierwszego dnia projektu”. Innymi słowy: projekt zaczynamy zawsze od opracowania architektury całości systemu (HLD), a potem kolejno (iteracyjnie) dopracowujemy detale każdego komponentu (LLD) i dostarczamy je klientowi.

Kolejny powód do modelowania, szczególnie HLD, to integracja. Otóż, jeżeli uznać, że żadna aplikacja biznesowa nie działa samodzielnie, a zawsze jako element większej całości, to znaczy, że: żaden system “nie jest mały”, że jest zawsze częścią nadrzędnego systemu, systemu wspierającego całą organizację, jej dostawców i odbiorców, to znaczy, że

realnie zawsze modelujemy “duży system” lub jego integralną część.

To zaś oznacza, że zawsze należy wykonać (mieć) model HLD systemu całej organizacji. Bez tego nie jest możliwa analiza wpływu: na co w firmie ma wpływ ten “mały” system, który właśnie wdrażamy lub modyfikujemy.

Na koniec ciekawe zestawienie jak ewoluowało podejście do projektowania w latach 1990 – 2005. Manifest Agile (Manifesto for Agile Software Development) opublikowano w 2001 roku. Po tym czasie sygnatariusze manifestu, w swoich późniejszych publikacjach, zaczęli zwracać jednak uwagę na projektowanie architektury by unikać bałaganu w większych projektach.

Od 2005 roku te metody są doskonalone. Pojawiły się mikroserwisy, fala fascynacji pokazała, że nadmierne rozdrabnianie usług wprowadza chaos, lekarstwem mało być Use Case 2.0 . Pojawiają próby porządkowania mikrosewisów . Jednak chyba największy wkład w metody projektowania oparte na architekturze ma właśnie idea projektowania zorientowanego na role i odpowiedzialność klas .

Dodatek: koniec wodospadów

Nadal bardzo często wielu autorów przypomina i krytykuje “wodospadowe” (waterfall) metody wytwarzania oprogramowania, słusznie wytykając im nieefektywność i nieadekwatność do aktualnej zmiennej sytuacji i potrzeb rynku. Podstawą tej krytyki jest teza, że analiza i projektowanie to żmudne, szczegółowe i długie projektowanie całego systemu. Była by to prawda, gdyby ten system miał być monolitem (zresztą decyzja o projektowaniu jednej relacyjnej bazy SQL dla całej aplikacji to właśnie decyzja o budowie monolitu).

Ryzyko projektu planowanego w detalach tylko na najbliższy rok budżetowy oraz planowanego od razu w całości.

Ale analiza i projektowanie to faktycznie nie musi być waterfall i monolit. Szybkie (można nawet powiedzieć, że zwinne) tworzenie oprogramowania, to analiza warstwy operacyjnej działania firmy i szybkie modelowanie komponentowej architektury całości aplikacji na poziomie HLD. Następnie iteracyjnie projektujemy szczegóły czyli architekturę (wnętrze) kolejnych komponentów (LLD) i zlecamy ich implementację. Całość jest przewidywalna, bo ma mamy obraz całości (HLD to także interfejsy między komponentami) i możliwa jest wycena fixed-price, kolejne kroki to, w ustalonej kolejności zależnej od potrzeb biznesowych Zamawiającego, implementacja i oddawanie do użytku kolejnych usługi aplikacji (komponentów):

Iteracyjne wytwarzanie oprogramowania: pierwszy etap to projekt HLD, kolejne to: projektowanie LLD komponentu i jego realizacja (implementacja). W trakcie implementacji zaprojektowanego komponentu, projektowane są detale kolejnego. Ryzyko wprowadzenia zmian do całości projektu jest minimalne, detale LLD są ustalane dopiero “na ostatni moment” spójność całości zapewnia model HLD.

Więc duży projekt i projektowanie poprzedzające wdrożenie to nie jest żaden monolit. Nie ma tu projektu żadnej centralnej bazy danych, nie ma projektowania detali całości na samym początku. Każdy komponent “żyje własnym życiem” czyli mamy mikroserwisy: Aplikacje webowe i mikroserwisy czyli architektura systemów webowych.

Ostatniego dnia projektu mamy działający system oraz jego pełną i aktualną dokumentację.

Dodatek

Diagrams as Code 2.0 • Simon Brown • GOTO 2021

Źródła

Jarosław Żeliński

Jarosław Żeliński: autor, badacz i praktyk analizy systemowej organizacji: 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 nieetatowy wykładowca akademicki, 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).

Ten post ma jeden komentarz

Dodaj komentarz

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.