Architektura mikrousługowa a analiza systemowa

mikrousługi.jpgAby jakoś zrównoważyć narzekania na korporacyjnego edżajla, drugi dzisiejszy wpis będzie bardziej inżynierski. Ostatnimi czasy mam okazję pracować nad systemami o architekturze mikrousługowej. Oczywiście jako analityk. I z tego analitycznego punktu widzenia, można powiedzieć, że architektura, jak architektura, za jednym wyjątkiem. Wydaje się bowiem, iż w przypadku tej konkretnej architektury, mniejszego znaczenia nabiera klasyk analizy, czyli analityczny model danych, rozumiany jako jednolita struktura opisująca dane, jakimi należy się posługiwać, aby można było zrealizować deklarowane funkcjonalności systemu.

Dlaczego? O tym będzie poniższy wpis.

Usługa

Mikrousługa, z analitycznego punktu widzenia, to usługa jak każda inna. Powinna mieć opisane zachowanie (jak realizuje kontrakt) oraz strukturę danych wejściowych (żądanie) i wyjściowych (odpowiedź). Koncepcyjnie (realizacja może wyglądać różnie w zależności od narzędzia do modelowania, metodyki i wynikających z niej standardów poziomu szczegółowości opisu), model usługi powinien zawierać powiązane ze sobą elementy przedstawione na rysunku poniżej.

Struktura opisu mikrousługi

Struktura opisu mikrousługi

Klient usługi

Załóżmy dla uproszczenia, że analityczną warstwą kliencką usługi będzie klasyczny przypadek użycia. Przebieg realizacji przypadku użycia, będzie zapewne opisany diagramem aktywności lub sekwencji (specyfika stosowanej metodyki). Bez względu na rodzaj diagramu, w momentach, w których zaistnieje zapotrzebowanie na dane, wymagane będzie odwołanie do usługi. Przykład takiej sytuacji prezentuje poniższy rysunek.

Wywołanie mikrousługi z przebiegu przypadku użycia

Wywołanie mikrousługi z przebiegu przypadku użycia

Moment wywołania usługi jest reprezentowany stosowną akcją, która w rożnych narzędziach do modelowania będzie troszkę inaczej wyglądała. Teoretycznie, na pinie wejściowym powinny się znaleźć dane zgodne co do typu z typem REQUEST z modelu opisu usługi. Pin wyjściowy jest zgodny, co do typu, z RESPONSE z modelu opisu usługi. Problem z pinem wejściowym zgodnym z teorią byłby taki, że należałoby albo dodać osobną akcję, która tworzy strukturę żądania na bazie dostępnych danych, albo transformację na przepływie danych, która dokonałaby przekształceń. W naszym podejściu stosujemy delikatne obejście – aby nie komplikować przejść i nie rozbudowywać diagramu o dodatkowe akcje, przypisanie danych pod cechy żądania opisujemy jako pre-condition w akcji wywołania usługi. W języku OCL przyjmuje to następującą postać.

pre:

let req: REQUEST.oclInNew() and
req.cecha1 = daneWejścioweAkcji.cechaA and 
...

Wynik wywołania usługi jest dostępny w pinie wyjściowym akcji. Tak pozyskane dane mogą być wykorzystywane w ramach przypadku użycia. Dostęp do nowych danych wymaga analogicznego wywołania kolejnej usługi.

Specyficzną cechą tego podejścia jest fakt, iż jeśli nawet w różnych usługach zwracamy logicznie te same dane, to faktycznie są one tylko takie same, gdyż znajdują się w różnych obiektach, czy strukturach danych. Specyfika ta powoduje, iż jeden logiczny model danych dla tego typu aplikacji aplikacji byłby tworem czysto abstrakcyjnym, którego zakresem zastosowań byłby jedynie model. Co więcej, odwoływanie się do niego w ramach przebiegów przypadków użycia byłoby okupione dużym wysiłkiem wynikającym z konieczności wiązania danych z mikrousług z jednolitym modelem danych.

Tego typu sytuacja nie ma zwykle miejsca w tradycyjnych, nazwijmy to, architekturach, w których aplikacja składa się z własnego frontendu i własnych danych. W takim kontekście, model danych służy zwykle jako punkt wyjścia dla konstrukcji modelu trwałego (najczęściej relacyjnej bazy danych), czy też, po konwersji do formatu XMI, jako wsad do tworzenia plików mapujących narzędzi OR-mapping. Z modelu logicznego można także generować skryptami MDA fragmenty docelowego kodu źródłowego, w szczególności deklaracje klas, konstruktory, destruktory oraz operacje trawersujące asocjacje.

Nie mając tego typu korzyści, wydaje się, że nie warto inwestować pracy w czysto abstrakcyjną warstwę opisu. Coś oczywiście tracimy, ale zyskujemy bezcenny czas.

 

 

Ilustracja: https://pl.freepik.com/darmowe-zdjecie/abstrakcyjne-geometrycznej-tła-z-futurystyczne-projektu_1104905.htm Designed by Kjpargeter


Licencja Creative Commons
Ten utwór jest dostępny na licencji Creative Commons Uznanie autorstwa – Bez utworów zależnych 4.0 Międzynarodowe.

Model informacyjny w systemach klasy frontend

Frontend XSPrzez ostatnich kilka miesięcy mam okazję uczestniczyć w analizie biznesowej oraz systemowej systemu klasy frontend. Z jednej strony, system jak system, z drugiej, to co w nim wydaje się ciekawe to model danych. Oczywiście, z punktu widzenia języka specyfikacji, w dalszym ciągu jest to stary, dobry, sprawdzony diagram klas języka UML. Natomiast, to co w nim najciekawsze, to liczności.

Ale po kolei. Systemy omawianej kategorii sporą część danych prezentowanych na ekranach czerpią z innych systemów korzystając najczęściej z dedykowanych interfejsów. Różne funkcjonalności, mogą nieść ze sobą wymagania na określone dane, także w ramach jednej klasy. Dla przykładu, załóżmy, że w momencie wprowadzania wniosku o wydanie duplikatu prawa jazdy, osoba wprowadzająca wniosek ma za zadanie podanie swojego numeru PESEL, na podstawie którego system frontend, o hipotetycznej nazwie System Obsługi Dokumentów Drogowych (SODODRO), wysyła żądanie do Systemu Ewidencji Obywateli (SEO) i pobranie podstawowych danych o osobie, na które składają się imię, nazwisko, data urodzenia i miejsce zamieszkania. Przykładowa definicja klasy mogłaby wyglądać, jak poniżej.

klasy1

Podstawowe dane Obywatela

Takie dane są prezentowane osobie składającej wniosek, która po potwierdzeniu ich poprawności otrzymuje możliwość podania powodu ubiegania się o wystawienie duplikatu. Jednocześnie, dane te zostają przepisane do wniosku, stając się jego integralną częścią. W momencie kierowania wniosku do realizacji, odnotowywany jest moment jego złożenia oraz nadawany jest unikalny identyfikator wniosku. Przykładowy diagram klas systemu SODORO dla opisywanej sytuacji przedstawia poniższy rysunek.

 

klasy2

Model klas dla funkcjonalności składania wniosku

Wniosek jest zapisywany w systemie SOW (System Obsługi Wniosków) poprzez usługę zapiszWniosek. System SODORO musi przekształcić dane do struktury danych wejściowych usługi, co jest już odzwierciedlane w przebiegu przypadku użycia (jeżeli ta technika jest stosowana do opisu funkcjonalności systemu).

Inna funkcjonalność systemu SODORO, pozwala na wyświetlenie wszystkich wniosków złożonych przez określonego obywatela. W efekcie wywołania tej funkcjonalności, system SODORO wywołuje usługę dajWnioskiObywatela systemu SOW i w efekcie otrzymuje kolekcję wniosków, opisanych cechami: moment złożenia, identyfikator wniosku. Oznacza to, iż model informacyjny systemu musi uwzględnić fakt, iż w niektórych sytuacjach dane wniosku będą zubożone w stosunku do jego pełnej zawartości informacyjnej, co musi skutkować jawnym wprowadzeniem opcjonalności w modelu klas.  Atrybutom imię składającego, nazwisko składającego, data urodzenia składającego, PESEL składającego oraz miejsce zamieszkania składającego przypisano liczności [0..1]. Podobny zabieg został zastosowany dla roli składający asocjacji składa. Co więcej, w związku z faktem, iż dane wniosku są odczytywane bez kontekstu obywatela go składającego, należy usunąć znacznik wnioskowalności atrybutów. Przykład takiej modyfikacji przedstawia poniższy rysunek.

klasy3

Osłabione liczności w modelu klas

Wraz ze wzrostem opisywanej funkcjonalności może następować dalsze osłabianie wymagalności poszczególnych cech klas oraz końców asocjacji łączących klasy. Docelowy model, może więc teoretycznie przyjąć formę diagramu, w którym zdecydowana większość właściwości klas jest opcjonalna, dzięki czemu model stanie się adekwatny do kontekstu pojedynczych funkcjonalności.

Sytuacja taka może sprowokować pytanie, jaka jest wartość takiego modelu? Czy nie lepiej byłoby tworzyć modele pod pojedyncze funkcjonalności, i uznać, iż nie ma czegoś takiego jak jednolity model informacyjny systemu klasy frontend? Przyznam, że sam miałem jakiś czas temu takie dylematy, ale na chwilę obecną stwierdzam, iż model taki ma sens. Po pierwsze, prezentuje on spójny obraz tego, czego można się spodziewać po posiadanych danych. Po drugie, pozwala on na unifikację danych wykorzystywanych przez system frontend, niezależnie od tego, skąd te dane są zaczytywane (oczywiście, pod warunkiem, że można przekształcić dane z systemów źródłowych do struktury systemu frontend). A gdyby tak przyglądnąć się modelowi z punktu widzenia narzędzi integracyjnych, czy BPMS, można byłoby dojść do wniosku, że jest to nic innego, jak model kanoniczny. A takowy przecież sens ma.

Prace analityczne trwają, więc być może mój pogląd na sprawę się zmieni. Gdyby tak się stało, postaram się podzielić swoją opinią na powyższy temat ponownie.

A przed zakończeniem…

P.S. Sposób odnotowywania zapisu wniosku

Przebiegi przypadków użycia, w ramach których m.in. następują wywołania do systemów zewnętrznych, są opisywane w metodyce AION diagramami aktywności, w których odwołanie do współdzielonej funkcjonalności (zachowania, w terminologii UML) jest reprezentowane akcją wywołania zachowania (ang. call behavior action).  Sytuacje wywoływania usług zewnętrznych systemów doczekały się w metodyce wzorca analitycznego, na który składa się przede wszystkim aktywność zawierająca dwuetapowe wywołanie. Strukturę takiej aktywności, dostosowaną do omawianego przykładu, prezentuje poniższy rysunek. Pierwsza etap, to przekształcenie informacji zapisanych w modelu informacyjnym systemu wywołującego usługę, do struktury danych wymaganej do wywołania usługi. We wzorcu etap ten reprezentuje akcja Przygotowanie danych. Precyzyjne opisanie zasad przekształcania wymaga zastosowania prostych konstrukcji języka OCL (patrz P.S. 2). Drugi etap, to wywołanie samej usługi systemu zewnętrznego, reprezentowane akcją wywołania zachowania o nazwie Wywołanie usługi. Pinem wejściowym dla tej akcji jest struktura danych będąca pinem wyjściowym wcześniejszej akcji.

activity

Opis aktywności zawierającej ciąg działań wymaganych do wywołania zewnętrznej usługi

Odwołanie do wywołania usługi zewnętrznej w przebiegach poszczególnych przypadków użycia jest reprezentowane także akcją wywołania zachowania, ale w tym przypadku wywoływana jest aktywność opisana omówionym wzorcem. Przykład wywołania prezentuje poniższy rysunek.

 

use case flow

Wywołanie wzorca wywołania usługi z przebiegu przypadku użycia

 

P.S. 2 Sposób przygotowania wyrażenia OCL transformującego dane z modelu informacyjnego aplikacji frontend na struktury parametru wywołania usługi

Język OCL może znaleźć zastosowanie między innymi do jawnego pokazania konwersji danych ze struktur modelu informacyjnego systemu frontend do struktur wywołania usługi. Poniższy rysunek prezentuje przykładowe wyrażenie OCL. Pierwsza część wyrażenia, rozpoczynająca się od słowa context stanowi deklarację kontekstu definiowania ograniczenia. Kontekstem takim, zgodnie z UML, może być klasa, albo określone zachowanie. Odwołanie się do akcji jest konwencją AION, która moim zdaniem jest naturalnym rozszerzeniem koncepcji zawartych w UML.

Druga część wyrażenia, rozpoczynająca się od słowa post opisuje warunek, który musi być spełniony po zakończeniu realizacji akcji. Pierwsza linia wyrażenia  – result.oclIsNew() – wskazuje, iż elementem wyjściowym wywołania jest nowopowstały obiekt. Dalsze składowe wyrażenia pokazują zasady transformacji.

 

ocl

Przykład zastosowania OCL do jawnego pokazania konwersji struktur danych

 

 

Ilustracją wpisu jest zdjęcie pobrane z serwisu Freepik.


Licencja Creative Commons
Ten utwór jest dostępny na licencji Creative Commons Uznanie autorstwa – Bez utworów zależnych 4.0 Międzynarodowe.