Tym przewrotnym tytułem chcę dziś zwrócić uwagę na dwa ważne i bardzo pomocne wzorce analityczne (słowo analityczne ode mnie, w książkach na temat wzorców bardzo rzadko używana jest nazwa “wzorce analityczne”) opisane w książce M.Fowlera. Wzorcami analitycznymi nazywam te wzorce projektowe, które pomagają w analizie i projektowaniu modelu dziedziny systemu (biznesowy model obiektowy).

MFowlerWzorceProjektowePolecam oczywiście lekturę całej książki Martina Fowlera Architektura Systemów Zarządzania Przedsiębiorstwem Wzorce Projektowe.Transfer Object oraz Value Object.

 

Przykład użycia Value Object i Transfer Object

Na etapie analizy problemu (analizy i modelowaniu dziedziny systemu) powinno nas interesować przede wszystkim co i po co się dzieje. Wielu analityków o rodowodzie programistycznym zaczyna pracę od pytań w rodzaju “ile nazwisko ma znaków, czy mogą to być tylko litery czy coś jeszcze”, itd. Jest to moim zdaniem kompletne nieporozumienie. Zabieranie się za opracowanie modelu od tej strony (modelowanie danych) całkowicie przyćmi rozwiązywany problem. Np. starając się zrozumieć system sprzedaży biletów na samolot istotne jest na początku nie to, ile znaków może mieć nazwisko a to, że bardzo istotna jest identyfikacja pasażerów i miejsc jakie mają zająć w samolocie. To nie jest to samo, bo identyfikacja pasażerów ma za cel kontrolę, kogo wpuszczamy na pokład samolotu, a nazwisko to jedna z cech pasażera i na etapie analizy nie należy zakładać, że to jedyny i najlepszy sposób na to rozróżnienie. Brzmi jak herezja? Zapewne, bo “większość” analityków zaczyna właśnie od badania np. nazwiska.

A kiedy zając się nazwiskiem? Dopiero wtedy gdy zrozumiemy problem i opracujemy systemowe jego rozwiązanie.  Po pierwsze dlatego, że na początku nie mamy wiedzy (za wcześnie na taką decyzję) by ustalić na jakich konkretnie danych będzie opierała się identyfikacja pasażerów (a nuż pojawi się [[biometria]]), po drugie niepotrzebnie skomplikujemy dokumentację zamulając ją od samego początku dużą ilością zbędnych “atrybutów”.

 

Druga istotna rzecz, to komunikacja. Wiemy, że firma sprzedająca bilety lotnicze operuje różnymi danymi (lokalny model biznesowy tej firmy) na temat rezerwowanych biletów. Wiemy, że te dane – o sprzedanych biletach – muszą być przekazane linii lotniczej, ta zaś wcześniej musi jakoś przekazać informacje o tym, na jakie loty i jakie bilety oferuje.

 

Co ciekawe, doskonale to pasuje to opisów wykonywanych przez zamawiającego (albo jak kto woli user story). Normalny człowiek raczej powie nam, że “zapisuje dane pasażera”, ale raczej nie powie nam, że “rejestruje 25 znaków nazwiska, 20 znaków imienia i czasem 20 znaków drugiego imienia…..”.  Ten sam człowiek powie następnie, że przekazuje dane o sprzedanych biletach do odpowiednich linii lotniczych a nie, że “dokonuje transferu kolekcji danych zawierających…..”.

 

Analiza i projektowanie

Na bazie wywiadów, dokumentów itp. staramy się zrozumieć “co jest grane”, jak ten system funkcjonuje. Powstaje np. taki diagram. Tu zakładam już, że modelujemy system sprzedaży biletów, ale system oznacza “wszystko to, co bierze w tym udział” a nie “konkretne oprogramowanie”:

Transfer biletów do linii lotniczej

 

Mamy model czegoś co ma się wydarzyć. Na tym etapie kompletnie nie ma sensu zajmowanie się tym ile znaków ma nazwisko. To może się zmienić w toku analizy a nawet implementacji, ale nie powinna ulec zmianie logika tej operacji.

Jak już opanujemy logikę (zrozumiemy co i jak ma działać i zaprojektujemy jak to zrealizować) zabieramy się za szczegóły. Model dziedziny (fragment):

Model dziedziny

Jak widać, np. danePasażera jako zawartość to daneOsoby a nie “pola i typy danych”. Czym są DaneOsoby znajdziemy tu:

ValueObject

Zamiast prostych typów danych (np. znakowe) stosujemy obiekt jako typ danych. To znakomicie ułatwia późniejsze rozszerzenia i zmiany (nie musimy nic zmieniać w modelu dziedziny by np. dodać drugie imię do danych osoby, modyfikujemy w jednym miejscu jedynie deklarację klasy DaneOsoby).

Wywołanie operacji podajDaneBiletu zwraca obiekt DaneBiletuLitniczego (lub agregat zawierający wszystkie bilety):

Transfer ObjectNie jest to ten sam obiekt co wcześniej, ValueObject to typ danych, Transfer Object to serializacja, której celem jest jedynie przeniesienie w możliwie najprostszy do odczytania sposób określonych informacji (oba te obiekty nie mają jednak tożsamości). Nie należy tych wzorców mylić ani utożsamiać, gdyż Value Object to “typ danych” zaś Transfer Object to jedynie parametr wywołań, Value Object powinien mieć operacje sparwdzajace jego poprawność (walidacja), Transfer Object służy wyłącznie do przekazywania informacji jako parametr wywołań i odpowiedzi (w pewnym sensie  definiuje protokół wymiany danych).

Korzyści ze stosowania tych wzorców to między innymi:

  1. szczegóły danych odkładamy na koniec projektu co jest bezpieczne (nie musimy modyfikować projektu w miarę postępu pozyskiwania wiedzy o szczegółach),
  2. zmiana tych szczegółów nie spowoduje potrzeby zmiany szkieletu modelu dziedziny,
  3. możemy prowadzić spokojną uporządkowaną analizę “top-down” (od ogółu do szczegółu),
  4. możemy się umówić z developerem, że jako analitycy nie będziemy wnikali w szczegóły danych, nadal możemy operować klasami ValueObject i TransferObject (klasy te będą w początkowej fazie projektu bez atrybutów),
  5. mimo to możemy umieścić w klasach ValueObject warunki walidacji (operacje klas, których tu nie pokazywałem) i do tego one między innymi służą (to się nazywa określanie wymagań poprzez testy czyli TDD),
  6. już na samym początku możemy uzgodnić postać danych wymienianych na interfejsach (np. zdalna komunikacja) i korzystać z tej umowy.

Tak zaprojektowany system spełnia także jedną z kluczowych zasad projektowania obiektowego: “system jest zamknięty na zmiany i otwarty na rozszerzenia”.

 

Na zakończenie

Często słyszę, że to trudne i pracochłonne (dodatkowe klasy w modelu), niestety zbyt prosty projekt potrafi być kosztowniejszy w rozbudowie w porównaniu z pierwotnym wytworzeniem, dlatego jak klient w ramach wymagań wpisuje  (a wpisuje coraz częściej): system ma umożliwiać łatwe rozszerzenia funkcjonalności, to należy go tak projektować, w przeciwnym wypadku wymaganie to nie jest spełnione…

Druga uwaga: często sami klienci zabijają swoje projekty żądając na samym początku udokumentowania wszystkich szczegółów jakie im do głowy przyjdą nie potrafiąc jednocześnie opisać mechanizmu działania ich organizacji (lub nowego pomysłu). To niestety często spotykane zjawisko, z którym moim zdaniem należy walczyć. Paradoksalnie złożoność systemów biznesowych tkwi w mechanizmie ich funkcjonowania a nie w danych, które zbierają (których nie raz jest po prostu za dużo…).

Dane to fakty jakie chcemy znać, te fakty są konsekwencją działania a nie odwrotnie. 

Na rynku w Polsce są jeszcze między innymi książki o wzorcach:

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).

Dodaj komentarz

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