Diagram klas (UML) po raz 2

W związku z tym, że poprzedni diagram klas wywołał dyskusję na pewnym forum nt. jego zawartości, konstrukcji, zastosowanych elementów, atrybutów oraz realizacji między nimi, przygotowany został nowy diagram (poniżej). Dyskusja jak najbardziej konstruktywna (miejmy nadzieję, że dla wszystkich czytelników), została zapoczątkowana przez Analityka Biznesowgo, którego wizyta na moim blogu mnie bardzo zaskoczyła. Zamieszczam poniższy diagram z komentarzem i czekam na dalszy ciąg. Na tym blogu zawarte są treści, które są analizowane i później proponowane są nowe rozwiązania – taka jest idea tego bloga („modelowanie trochę od innej strony…”). Tym razem zostałem w swoich planach wyprzedzony z analizą przykładu.

Kilka komentarzy:

  • nie zastosowano w nim kompozycji, ponieważ jest za mocną relacją, nie oddaje rzeczywistości. W szczególności w tego typu dziedzinie Klient może istnieć samodzielnie, nie musi złożyć zamówienia, może tylko przeglądać. Podobnie produkt może istnieć samodzielnie. Diagram dotyczy dziedziny zamówień przez internet i wtedy produkt w dziedzinie istnieje przed klientem i przed zamówieniem;
  • atrybut „płeć” jest jak najbardziej przydatnym elementem w prezentowaniu Klienta, w szczególności w diagramach, które odpowiadają systemom zakładającym takie coś jak personalizacja, czy badanie zachowań klientów. Nie ma tego na diagramie, bo to nie było celem samym w sobie;
  • niektóre atrybuty rzeczywiście były zbędne lub umieszczone w nieprawidłowej klasie. W związku z tym, niektóre usunąłem, a niektóre przeniosłem;
  • zmienione zostały klasy uczestniczące w relacji dziedziczenia;
  • na diagramie warto byłoby dodać, dla jasności sytuacji, klasy użytkownika oraz interfejs koszyk, żeby lepiej zilustrować charakter;
  • można dodać klasę faktura;

Diagram klas (UML)

Na diagramach prezentujących warstwę reiżnynierii zostały zamieszczone informacje o następujących obiektach:

  • DaneKlienta – zaprezentowane jako klasa „Klient” na poniższym diagramie;
  • DaneZamowienia – zaprezentowane jako klasa „Zamowienie” na poniższym diagramie;
  • DaneDostawy – zaprezentowane jako klasa „Dostawa” na poniższym diagramie;

Były one używane do realizacji określonych czynności. Na poniższym diagramie – tzw. diagramie klas (ang. class diagram)zostały one zaprazentowane jako klasy wraz z przykładowymi atrybutami (ang. attribute) oraz operacjami (ang. operation). Dodatkowo zostały umieszczone dodatkowe klasy – np. Płatność – silnie powiązane z tą dziedziną. Między poszczególnymi klasami zostały określone związki. Przy niektórych podana liczebność. Inne natomiast są w relacji uogólnienia.

Powyższy diagram ma charakter przykładowy. Kolejna wersja diagramu z komentarzami znajduje się tutaj.

Diagram przypadków użycia (UML)

W czasie tworzenia systemu informacyjnego – w tym przypadku systemu wspierającego złożenie zamówienia przez Klienta i jego realizację przez dostawcę – istotne jest to, aby spojrzeć na:

  1. czynności wykonywane przez klientów – np. „Określenie zamówienia” czy wybranie produktu, określenie jego ilości, „Realizacja zamówienia”, czyli określenie w jaki sposób ma do nas trafić i kiedy/jak za produkt chemy zapłacić
  2. czynności wykonywane przez pracowników dostawcy – np. „Analiza zamówienia” czy „Realizacja wysyłki”.

Każdą z tych przykładowych czynności można dalej rozbijać, identyfikując jej elementy składowe. Przykładowe powiązanie aktorów (klient, pracownik) oraz wykonywanych czynności jest przedstawione na poniższym diagramie – tzw. diagram przypadków użycia (ang. use case diagram).

Proces wyborczy

Tydzień temu odbyły się w Polsce wybory Prezydenta RP. Głosy zdobyte przez kandydatów rozłożyły się i żaden kandydat nie zdobył ich liczby wymaganej do wygrania w pierwszej turze (czyli powyżej 50% głosów). Za tydzień będzie więc druga tura… Od kilku tygodni, temat nie schodził z pierwszych stron serwisów, z czołówek wiadomości. Jedni informowali o tym gdzie tym razem się pojawił dany kandydat, co powiedział, co się wydarzyło w trakcie spotkania, a inni przypominali o wcześniejszym zachowaniu, decyzjach. Jedni przekonują na spotkaniach bezpośrednich, a inny wykorzystując sieć Internet. Jedni tworzą nowe hasła wyborcze, a drudzy opierają się na dotychczasowych zdaniach. Jedni zastanawiali się na kogo zagłosować, inni wiedzieli od samego początku. Teraz z kolei pojawiają się sondaże, które raz dają wygraną jednemu kandydatowi, a innym razem temu drugiemu. Kandydaci musieli jednak zacząć od zgłoszenia swojej kandydatury oraz przedstawienia odpowiedniej liczby głosów popierających. A jeszcze wcześniej musiał zostać ogłoszony termin wyborów, aby cały proces mógł ruszyć.

Proces wyborczy o zgłoszenia komitetu/kandydata, poprzez prowadzenie kampanii aż po przeprowadzenie samych wyborów, definiuje tzw. Kodeks wyborczy. Szczegółowe wytyczne są opisane w dokumencie „Kodeks wyborczy”, dokładnie ustawie, opublikowanej na stronach rządowych dotyczących wyborów. Jest to dokument, który określa zasady dla poszczególnych wyborów. Na potrzeby tego wpisu skupiałem się na dziale V, a efekt tego spróbowałem zobrazować na poniższym diagramie.

proces_wyborczy_600px
Kilka komentarzy do tego procesu:

  • W sam proces wyboru Prezydenta (wg rozdziału 1 w dziale V) są zaangażowane minimum 3 podmioty – Marszałek Sejmu, Kandydat na Prezydenta oraz Państwowa Komisja Wyborcza – co oznaczyłem elementami znanymi z UML, łącząc te obiekty z odpowiednimi krokami procesu, przez połączenia typu asocjacja.
  • Działania w tym procesie wykonywane są w określonym rygorze czasowym w zakresie momentu ogłoszenia oraz przeprowadzenia poszczególnych etapów – co zaznaczyłem przez zdarzenia wskazujące na momenty czasu (ang. timer event) wykorzystywane w diagramach BPMN.
  • W procesie jest krok „Zgłoś kandydaturę” oznaczony jako podproces, ze względu na to, że jest to rozbudowane działanie (opisane w rozdziale 2 działu V), realizowane także w ustalonym rygorze czasowym. Kroki tego procesu zostały zasygnalizowane w ramce „Zgłoś kandydaturę”, wraz z połączeniem ich do wskazanych wcześniej uczestników procesu.
  • W procesie kluczowym elementem jest krok „Zlicz głosy” , występujący 2 razy, przy czym pierwszy z nich występuje zawsze, a drugi opcjonalnie, w zależności od wyników 1 tury głosowania, co zostało oznaczone za pomocą bramki opartej o dane (ang. Exclusive data-based gataway)

Ocena zamówienia – moment i konstrukcja

Udało się! Dotarło bez części zamówionych produktów, ale wreszcie odebrałem zamówienie, o którym pisałem w poprzednim wpisie. Przyszło w całości, nieuszkodzone, bezpiecznie zapakowane. Choć spodziewałem go się trochę wcześniej. Patrząc na zrealizowany proces mogę dla niego wskazać następujące komentarze:

  1. (+) sklep posiadał produkty, których szukałem,
  2. (+) ceny produktów były akceptowalne,
  3. (+) dostępne sposoby płatności i dostawy pozwoliły wybrać to, co mi pasuje,
  4. (+) nie odwołali/nie wstrzymali zamówienia w przypadku problemów,
  5. (+) produkty przyszły w całości,
  6. (-) zamówienie przyszło z opóźnieniem,
  7. (-) informacje o dostępności produktów nie są do końca prawdziwe, przez co nie dostałem kompletu zamówienia.

Podsumowując:  jestem zadowolony z realizacji tego zamówienia – biorąc pod uwagę liczbę (+) i (-). Co ciekawe sklep ma specyficzny sposób zachęcania do wypełnienia ankiety o zrealizowanym zamówieniu. Pierwszy raz dostałem prośbę, jeszcze przed wysyłką zamówienia – zachęcała do tego wiadomość: „Wystaw opinię o naszym sklepie w zamian za…..” – sprawdziłem, że przyszła po statusie „gotowy do wysłania”. Dzień po odebraniu przesyłki przyszła kolejna wiadomość: „Twoja opinia jest dla nas ważna”, która także odwoływała się w treści do możliwości nagrodzenia za wydanie opinii.

Na poniższym diagramie stanów w UML (ang. state diagram) umiejscowiłem tę prośbę o ocenę (stan „Brak oceny”) w całym procesie zamówienia, patrząc z perspektywy statusów, które otrzymałem w postaci wiadomości e-mail lub określiłem sobie samodzielnie (oznaczone na szaro).

nieocenione2_360px

Po otrzymaniu pierwszej wiadomości, zadałem pytanie: co tak szybko? Przecież zamówienie nawet do mnie nie zostało wysłane. Po drugiej wiadomości, zacząłem zastanawiać się czy chcę wypełniać tę ankietę i w jaki sposób ten fakt wpłynie na moją ocenę, uwzględniając również to, co opisałem w poprzednim wpisie. Ostatecznie uruchomiłem proces oceny, chcąc sprawdzić, czy będzie okazja do wypowiedzenia się w tej kwestii. Wyglądało to następująco:

  • Pytania dotyczyły zakupionego produktu – czyli pytania dotyczące komentarzy (1) i (5) powyżej.
  • Pytania dotyczyły procesu w samym sklepie – dla (2), (3) i (7) powyżej.
  • Pytania dotyczyły czasu dostawy – dla (4), (6) i (7),
  • Prośba o dodatkowe komentarze – tutaj mógłbym wskazać te elementy, o które nie było pytania bezpośrednio. Mógłbym pochwalić za pewną elastyczność związaną z brakiem produktów równocześnie wskazując, że można byłoby to poprawić. Mógłbym wskazać zastrzeżenia co do ankiety itd.

Zabrakło mi w czasie czy nawet przed wypełnieniem ankiety informacji, czy ankieta jest anonimowa, czy zostanie opublikowana na stronie czy tylko przesłana. Dopiero na ostatnim kroku, jest informacja o akceptacji regulaminu, który odpowiada na te pytania. Wydaje się, że taką informację w skrócie można byłoby zawrzeć na 1 ekranie lub w innej formie.  Można też powiedzieć, że wystarczyłaby wysyłka ankiety w tym drugim kroku, na przykład 2 dni po nadaniu przesyłki, zakładając standardowy czas realizacji dostawy dla wybranej formy dostawy.  Plusem jest to, że ankieta jest prostsza od tej, którą kiedyś opisywałem. Ma też element niestandardowy jakim jest możliwość zamieszczenia zdjęcia lub dodatkowe informacji związanej z zamówionym produktem (np. zachęcają do pokazania jak go odbiorca wykorzystuje).

Umiejscowienie prośby o ocenę dla zamówień , które ostatnio składałem, było różne. Konstrukcja ankiety również.   Przeważnie przychodziły w momencie powiadomienia o wysłaniu zamówienia. W jednym przypadku przyszła informacja z pewnym opóźnieniem. Ten czas opóźnienia dla ankiety jest dość istotny – z jednej strony wpływa na to ile pamiętamy z realizowanego procesu, a z drugiej może wpłynąć na samą chęć wypełnienia ankiety. Zależy to od tego jak sprawnie przeszło zamówienie, jakie spowodowało reakcje, a także od podejścia odbiorcy – jedni nie wystawiają ocen wcale a inni to robią zawsze i wszędzie. Reszta z odbiorców jest gdzieś pośrodku i pewnie na pytanie o to, czy wystawią ocenę, odpowiedzą krótko „to zależy”.  Podobnie jest z konstrukcją ankiety – długa i szczegółowa może zniechęcić do jej wystawienia. Prosta i krótka może zachęcić do jej częstego wypełnienia.

Współdzielenie listy zakupów – „pull” czy „push”?

W ramach poprzedniego wpisu dotyczącego elektronicznej listy zakupów wskazałem, że jedną z funkcjonalności dostępnych w aplikacjach wspierających zakupy, jest możliwość współdzielenia listy zakupów. W aplikacji, z której korzystałem, to współdzielenie oparte było o podawanie adresu e-mail, przy założeniu, że zarówno tworzący listę, jak i ją otrzymujący jest zarejestrowanym użytkownikiem aplikacji i ma założone konto na serwerze aplikacji.

Użytkownicy aplikacji w ramach udostępnionej listy mogą:

  • dodawać/edytować produkty na liście,
  • śledzić postęp zakupów realizowanych przez drugą osobę,
  • kopiować listę na przyszłość.

Założeniem dla funkcjonowania współdzielenia listy zakupów, był dostęp do sieci Internet z poziomu urządzenia, na którym jest zainstalowana aplikacja. W sytuacji utraty dostępu do sieci Internet, zmiany na liście oczekiwały na podłączenie się drugiego użytkownika listy. W przypadku dostępu do sieci Internet przez obydwa urządzenia, zmiany były przekazywane w miarę na bieżąco.

Wspólny proces dla obydwu użytkowników jest przedstawiony na poniższym diagramie.

wspoldzielenie450px_1

Dla współdzielenia listy można byłoby zastosować dwa modele „współpracy”:

  • model „push” (aplikacja inicjująca zmianę przy pomocy pośrednika przekazuje zmiany do drugiej aplikacji)
  • model „pull” (jedna aplikacja przekazuje zmiany do wspólnego miejsca, a druga odpytuje o ewentualne zmiany w liście)

Wariant: model „push
Użytkownik – właściciel listy – rejestruje listę, udostępnia ją, a następnie wprowadza na niej zmiany. Wszystkie te elementy są przesyłane na serwer obsługujący aplikację. Każda zmiana jest rejestrowana i przekazywana do aplikacji odbiorcy listy (wskazanego poprzez e-mail). Serwer wysyła informację o zmianach do aplikacji użytkownika, rejestrując wysłane zmiany. Ewentualna zmiana przez drugą aplikację jest wysyłana analogiczną ścieżką. Na diagramie przedstawiona została ta komunikacja, gdzie każda zmiana jest „pchana” (ang. push) na serwer a następnie do drugiej aplikacji.

wspoldzielenie450px_2

W tym celu został wykorzystany wykres wyglądający jak diagram sekwencji (znany z UML) z pewnymi dodatkami. W projektowaniu rozwiązań można znaleźć wzorzec fire-and-forget, w którym informacje są przesyłane bez oczekiwania na reakcję odbiorcy. Trochę jak tutaj, bo w tym modelu aplikacja nie czeka na informację zwrotną.

Wariant: model „pull
Podobnie jak w poprzednim wariancie, użytkownik – właściciel listy – rejestruje listę, udostępnia ją, a następnie wprowadza na niej zmiany. Wszystkie te elementy są przesyłane na serwer obsługujący aplikację. Trafiają na listę zmian/działań (ang. queue) wykonanych na liście zakupów w postaci zdarzeń typu: udostępnienie listy, zmiana listy, zakup produktu (a dokładnie jego odklikanie) itd. W momencie ustawienia udostępnienia listy, zmiany na utworzonej liście są dostępne do pobrania/odczytania (ang. pull) przez drugą aplikację. W sytuacji, gdy takie udostępnienie nie nastąpi, zmiany są odnotowywane na serwerze i są dostępne tylko dla właściciela listy.

wspoldzielenie450px_3

Na diagramie jest przedstawiony ten model. W projektowaniu rozwiązań można znaleźć wzorzec publish-subscribe, który zakłada, że odbiorcy pobierają interesujące ich informacje z miejsca, gdzie zostały wystawione.

Pewnie można byłoby jeszcze zidentyfikować kilka innych wariantów, gdzie ta komunikacja jest bardziej dwustronna. Jednakże biorąc pod fakt, że aplikacja jest zainstalowana na urządzeniach mobilnych i nie w każdej sytuacji aplikacje będą miały dostęp do internetu, jakiś sposób przechowywania i kolejkowania zmian jest konieczny.  Dodatkowo użytkownicy wykonują często operacje zmiany i przeglądania zmian w różnym czasie lub tworzenie listy jest rozłożone w czasie. Patrząc od strony „odbiorcy” listy, także może zmodyfikować listę w czasie jej dostępności. Takie zmiany są „przesyłane zwrotnie” do właściciela listy.

Proces oparty o stany

Wyobraźmy sobie, że parking opisany ostatnio we wpisie, wykonuje oprócz wskazanych 3 podstawowych działań (przyjęcie samochodu, przyjęcie opłaty i wypuszczenie samochodu), jeszcze jedną bardzo ważną rzecz. Mianowicie, wskazuje w momencie wjazdu na parking, gdzie jest najbliższe wolne miejsce. Niby rzecz trywialna, ale wymaga odpowiedniego przygotowania – zarówno od strony infrastruktury (kontrola zajętych miejsc, identyfikacja gdzie są samochody wcześniej wpuszczone, które jeszcze nie zaparkowały), jak i informatycznej (odpowiedni system zarządzania miejscami parkingowymi, kontrolą stanów miejsc i ich zmianą, a także prezentacją graficzną parkingu).

stany450px

Z jednej strony mamy zmianę stanu miejsca parkingowego, a z drugiej weryfikację położenia, gdzie jest wolne miejsce. Takie procesy zostały zaprezentowane na powyższym diagramie. W momencie realizacji procesu (na diagramie Określ mapę dojazdu) z prezentacją najbliższego wolnego miejsca (na diagramie Wyświetl mapę dojazdu) system musi wziąć pod uwagę stany miejsc parkingowych wynikajacych z:

  • zajęcia miejsca parkingowego (zmiana stanu na zajęty),
  • opuszczenia miejsca parkingowego (zmiana statusu na wolny),
  • przemieszczania się samochodów wpuszczonych na parking (w dowolnym momencie dane miejsce może zmienić stan),
  • lokalizacji samochodów wpuszczonych na parking (np. są na 2 poziomie, a miejsce akurat jest na 1 poziomie).

Chcąc uniknąć ryzyka, że wskazane najbliższem miejsce okaże się zajęte, można także wskazywać miejsce alternatywne. Dodatkowo już po wjeździe na parking w widocznych miejscach mogłyby być umieszczone ekrany wskazujące na najbliższe wolne miejsce parkingowe (cykliczne wykonywanie pierwszego procesu). Ułatwieniem w zarządzaniu takim parkingiem mogłoby być to, że nie da się cofnąć do innego miejsca parkingowego, nie przejeżdżając przez punkt startowy, który dodatkowo jest kontrolowany przez system.

W podanym przykładzie podane procesy opierają się na świadomym wykorzystaniu stanów poszczególnych miejsc parkingowych (oznaczone za pomocą funkcji w klasach UML na diagramie). Stany miejsc występują naprzemiennie i trudno jest określić jakie są ramy czasowe dla rozpoczęcia procesu i jego zakończenia. Dla danego miejsca stan może się nie zmienić godzinami lub zmienić się raz i pozostać taki przez wiele godzin. Takie cechy są charakterystyczne dla procesów sterowanych stanami – ang. state-driven process. Skierowanie samochodu na dane miejsce jest możliwe tylko, gdy jest ono wolne. Zmiana stanu odbywa się poprzez odnotowanie wjazdu samochodu na dane miejsce.

Co dostarczają kroki procesu?

Ostatnio spotkałem się z pojęciem diagramu procesu, który na bazie kroków procesu równocześnie wskazuje, co one dostarczają. Jest to tzw. Process-Deliverable Diagram (w skrócie PDD). Jest to diagram, który łączy w sobie elementy z dwóch obszarów:

  • kroków/czynności składających się na proces, zaprezentowanych za pomocą diagramu czynności (ang. activity diagram) z notacji UML,
  • obiektów dostarczanych przez proces, zaprezentowanych za pomocą diagramu klas (ang. class diagram) z notacji UML;

pdd2

Pierwszym procesem, który przyszedł mi na myśl, gdy przeczytałem o tym diagramie, był proces realizacji projektu, zaprezentowany na powyższym przykładowym diagramie. Począwszy od inicjalizacji projektu, przez realizację jego kolejnych działań po wdrożenie, na każdym etapie dostarczany (ang. deliver) jest określony “produkt”. Produkty w całości lub częściowo są wykorzystywane na kolejnych etapach procesu. Te produkty można potraktować jako produkty końcowe procesu. Mogą być np. podstawą kolejnych zmian, przeprowadzania szkoleń, wyjaśniania reklamacji, analizy luk procesu.

Podobne rozwiązanie zostało zastosowane przy prezentacji wejść i wyjść w ramach realizacji procesu rekrutacji.

Proces w czarnej skrzynce

Dotychczas system karty aglomeracyjnej traktowałem jak tzw. czarną skrzynkę (ang. black box). Interesowały mnie tylko te działania, które mają skutek na wyświetlane komunikaty i reakcje na działania użytkownika. Wskazywałem początek trasy, koniec trasy i otrzymywałem zwrotnie odpowiedni komunikat.

Zastanówmy się jednak jak proces przedstawiony w jednym z poprzednich wpisów, a dokładnie o komunikatach dla odbiorcy wygląda w systemie karty. Można powiedzieć, że ma na pewno operacje: przyjmij punkt trasy, wyświetl komunikat, nalicz opłatę. Można sobie wyobrazić, że ma również sprawdź czy nastąpiła przesiadka (momencie odczytu punktu trasy), sprawdź czas między punktami trasy (aby określić, czy to jest kontynuacja trasy czy niezależna podróż).

Karta450

Na powyższym diagramie górna jego część prezentuje wybrane działania i ich skutek. Dodatkowo zostały wpisane obiekty, które są tworzone. Obiekty te są odpowiednikiem klas zaprezentowanych poniżej, za pomocą UML. Przedstawiony diagram obrazuje co potencjalnie może się dziać w ramach systemu i jakie struktury są w tym celu potrzebne. Na przykład, po „przyjmij punkt trasy” następuje sprawdzenie, czy to początek, czy koniec, sprawdzenie czy nastąpiła przesiadka, następnie zapis informacji z jego parametrami, następnie naliczenie opłaty i wyświetlenie komunikatu.

Krok „Określ rodzaj punktu”, po określeniu numeru linii i numeru przystanku, sprawdza, dla obecnie zapisanej trasy, (jeżeli istnieje), jaki rodzaj może to być punktu – początek, koniec czy przesiadka – są to rodzaje Punktu trasy, stąd zastosowane dziedziczenie. Określa te parametry, które zostają zapisane jako element trasy. Następnie następuje w kroku „Nalicz opłatę” żądanie Określ opłatę(), które w zależności od parametrów trasy, nalicza opłatę do końca linii, aktualizuje opłatę dla przesiadki lub określa końcową opłatę za przejechany odcinek. Naliczona opłata lub różnica do zwrotu zostaje odnotowana w saldzie karty poprzez operację ZmienSaldo().

Atrybut Linia określa na jakiej linii a atrybut przystanek określa kiedy i na jakim przystanku nastąpiło wskazanie punktu trasy. Atrybut Linia jest potrzebny do określenia czy nastąpiła przesiadka, a Przystanek (numer, czas) wskazuje, czy może traktować kolejny punkt jako przesiadkę czy niezależne rozpoczęcie trasy. Trasa określana jest przez poszczególne Punkty trasy. „Aktualna trasa” jest zapisywana dla danej Karty raz w systemie.