All we do is looking for some way to fulfill our needs.

czwartek, 17 października 2013

Tagged under: , , , , , , , ,

Mantra Architektoniczna


Ci którzy byli na JDD 2013 mogli zobaczyć na żywo. Dla tych, którzy nie byli lub nie widzieli poniżej znajdziecie prezentację dotyczącą Mantry architektonicznej i obszerny artykuł. Zatem zarezerwuj sobie dłuższą chwilę.
Ciągle powtarzamy, że nie mamy czasu. Nie ma czasu na testowanie jednostkowe, bo nasze szacowania są obcinane o połowę. Nie ma czasu na refaktoryzację, bo nasz kierownik projektu się na to nie zgadza. Nie ma czasu na przeglądy kodu, bo … nie ma czasu. Tak po prostu.

Co się dzieje z naszym czasem?

To co się dzieje z naszym czasem? Gdzie on się podziewa? Oto co się często dzieje w naszych projektach – kilka historii.

Przychodzi nowa osoba do zespołu. Często na wstępie dostaje do podpisania stos dokumentów – regulaminów, które obowiązuje w firmie. Dostaje namiary na różne zasoby w organizacji – konto w systemie HRowym, login do repozytorium, dostęp do serwerów, wewnętrznego intranetu. Tu wszystko wygląda świetnie. Gorzej kiedy przychodzi do informacji o systemie, który mam rozwijać. Delikwent dostaje wydrukowaną i złożoną z różnych źródeł dokumentację pięćsetstronicową. Nie do końca aktualną, niespójną i niezrozumiałą. I musi sobie radzić. Zamiast zorientować się w ciągu tygodnia jak działa system, poświęca na to trzy lub cztery miesiące przedzierając się samodzielnie przez „big ball of mud”. Inne osoby w zespole najczęściej nie mają czasu, żeby dokładniej wprowadzić w system. Tu traci się czas.

Inna historia – robisz przegląd kodu. Znajdujesz kilka niedociągnięć – tutaj jakaś nazwa do poprawy, tutaj warto wydzielić fabrykę i nagle napotykasz na coś dziwnego. Przetwarza JSONa w serwisie. Dziwne po przecież tego nie powinno się robić w serwisie. Autor tego wspaniałego dzieła w ciągu krótkiej chwili pokazuje ci przynajmniej kilka miejsc, gdzie było zrobione to samo i stamtąd skopiował pomysł. I teraz trzeba to odkręcać. Tu traci się czas.

Jeszcze inna historia – właśnie masz naprawić błąd. Po chwili czytania kodu, w głowie masz następujący dialog wewnętrzny: „O fu*k… Ja pie…. Co to ku…. jest? Dżizas… Ja pie… Tutaj? XML? Jaki ku… Manager?”. I tak pół godziny… albo więcej zanim zaczniesz pracować z kodem. Jeśli to można nazwać pracą. Tu traci się czas.

To tylko przykłady. Takich sytuacji zdarzają się setki, każdego dnia. Uciekają sekundy, minuty, godziny.

Pozornie proste pytanie

Zrób w swoim zespole prosty test. Zadaj pytanie: z jakich klocków składa się system, który piszemy i jakie są jego odpowiedzialności (tzn. co w danym klocku można, a czego nie można robić)? I sprawdź czy wszyscy udzielą tej samej odpowiedzi. My robiliśmy to wielokrotnie i od różnych osób dostawaliśmy odpowiedzi, które zawsze się nieco różniły. Czasami różniły się bardzo. Czasami o kilka procent. Jeśli te kilka procent przeskalujemy przez ilość osób i wielkość systemu, różnice stają się znaczące. W ten sposób architektura zaczyna erodować, powstają drobne odstępstwa od reguł i nawet doskonale zaprojektowana architektura musi polec w takich okolicznościach. Im więcej czasu upływa, tym konsekwencje są większe.

Zrób sobie test – odpowiedz na kilka pytań, które pozwolą ci ocenić, jak dobrze jest rozpropagowana wiedza o architekturze:
•    Ile potrzeba czasu do wdrożenia nowej osoby w projekt?
•    Jakie narzędzia ma do dyspozycji? Jak to robi i kto za to płaci?
•    Jak się upewniasz, że ludzie w Twoim zespole mówiąc o rozwiązaniach, mówią o tym samym?
•    Na podstawie czego możesz stwierdzić, że każdy pisząc kod wie dokładnie, co powinno znaleźć się w danym klocku?


Skąd się to bierze? Obraz architektury kształtują liderzy (np. lider techniczny, projektant, architekt, niektórzy członkowie zespołu – w zależności od przyjętej struktury). To oni wiedzą jak to powinno być zrobione. Z drugiej strony będąc liderem często jesteś osobą, która w jakiś sposób wyróżnia się wśród tłumu – tobie szczególnie zależy, cały czas dokształcasz się, jeździsz na konferencje, czytasz kolejne książki. Nie wszyscy tak mają. Nie wszyscy w lot łapią to, na czym polega architektura danego systemu. Tak było, jest i będzie. I trzeba się z tym pogodzić. To co można zrobić, to zwiększać prawdopodobieństwo, że mimo tych przeciwności, wszyscy architekturę będą rozumieć tak samo.

Co to jest Mantra Architektoniczna?

Wyobraź sobie taki cel: O trzeciej nad ranem każda osoba w zespole jest w stanie bez zająknięcia powiedzieć, jakich klocków składa się system i jakie są ich odpowiedzialności. I wszyscy odpowiedzą to samo. Ambitne? Bardzo. I właśnie o to chodzi. To trzeba wypracować. Być może nie zadzieje się to od razu, jednak wkładając nieco wysiłku i dając sobie czas, można zbliżyć się do tego ideału.
W osiągnięciu tego celu ma nam pomóc Mantra Architektoniczna, która składa się z trzech składowych:
  1. Wizualizacji bloków budujących
  2. Zdefiniowania odpowiedzialności
  3. Napędzania procesu


Zwizualizuj

Narysuj klocki, z których składa się system. Może to być UML, odręczny rysunek, coś co będzie zrozumiałe dla zespołu. Następnie umieść to w takim miejscu, żeby było widoczne np. na ścianie, tak, żeby w każdym momencie można było podejść do rysunku i dyskutować w oparciu o niego. Zadbaj o jego łatwą dostępność.
Czasami może ci się wydawać, że przecież używamy Domain-Driven Design (DDD), w związku z tym wszystko jest oczywiste. Nic bardziej mylnego. Szczególnie wtedy jest to ważne, żeby zdefiniować Mantrę, ponieważ praktycznie nigdy dane podejście architektoniczne nie jest zastosowane książkowo, jest ono w jakiś sposób zmodyfikowane i te różnice należy wyartykułować. Poniżej znajdziesz przykładowe rysunki – jeden oparty o DDD, a drugi oparty o klasyczną architekturę warstwową. To tylko przykłady. Kluczem jest to, żeby ten rysunek był unikalny dla waszego systemu.


Przykład rysunku dla architektury opartej o DDD 



Przykład rysunku dla architektury warstwowej


A jak to wygląda u ciebie?

Jeśli wasza architektura wykorzystuje wzorzec Domain Model – warto zwizualizować klasy dziedziny. Jeśli wasz system komunikuje się z wieloma innymi systemami – warto zwizualizować powiązania z innymi systemami, tak aby łatwo można było prześledzić konsekwencje interakcji w systemie. Te rysunki mają być podstawą komunikacji – miejscem, przy którym toczą się dyskusje o rozwiązaniach.


Dodatkowe rysunki – model dziedziny oraz diagram kontekstowy 

Zdefiniuj

Kiedy już elementy architektury zostaną narysowane, następnym krokiem jest określenie ich odpowiedzialności:
•    jaką rolę pełnią w systemie,
•    jakie operacje powinny być wykonywane,
•    jakie operacje nie powinny być wykonywane.

Oto kilka przykładów odpowiedzialności
Value Object

•    Grupuje dane należące do pewnej całości
•    Nie jest trwale przechowywany
•    Pozwala nazwać konkretny byt z domeny
•    Nie jest unikatowy
•    NumerTelefonu, KodPocztowy,
•    Implementowany w oparciu o wzorzec Immutable
•    . . .

Entity

•    Obiekt, który musi być unikatowy
•    Posiada dane oraz zachowanie biznesowe
•    Jest trwale przechowywany
•    Unikatowość obiektu zależy od konkretnego kontekstu i domeny
•    . . .

Repository

•    Wyznacza warstwę do trwałego przechowywania danych
•    Abstrahuje od konkretnego sposobu persystencji
•    Zachowuje interfejs kolekcji
•    . . .

Application Service

•    Mieści się w warstwie aplikacji
•    Wykonuje przetwarzanie wyznaczone przez przypadki użycia (kroki)
•    . . .

Co się powinno dziać – przykład:
Controller

•    Przyjmuje request.
•    Dokonuje złożonej walidacji.
•    Składa dane do wywołania serwisu.
•    Wywołuje serwis.
•    Wynik pakuje w JSONa.
•    Określa kolejny widok.

Czego nie powinno być – przykład:

Controller

•    Prostej walidacji (gdyż do tego celu wykorzystujemy framework webowy).
•    Złożonego przetwarzania JSONa  (z serwisu nie powinien przychodzić JSON).
•    Logiki dziedzinowej np. decydowanie na podstawie danych czy zlecenie ma być wykonane.

Powyższe definicje powinny być jak najmniej książkowe, a jak najbardziej zaczerpnięte z tego co się dzieje w projekcie. Szczególnie ważne jest to, czego nie powinno się robić w danym bloku budującym. To jest bardzo cenna informacja o często popełnianych błędach. To jest ta część mantry, która jest najbardziej żywa.

Napędzaj

Jest to ta część Mantry, która o której najczęściej się zapomina. To tej części zawdzięczamy nazwę „Mantra”. Żeby architektura żyła w głowach członków zespołu, żeby się rozwijała, musi się ciągle o niej mówić, musi się wokół niej cały czas coś dziać. O tym najczęściej zapominamy – uważamy, że wystarczy wymyśleć, a reszta zadzieje się sama. Tak niestety się nie dzieje. Trzeba dokładać węgla do pieca, trzeba działać. Musi się dziać i to przynajmniej na kilku frontach.

1.    Zdefiniuj jak jest i jak powinno byćZaangażuj cały zespół lub kluczowe osoby, aby zdefiniować główne elementy Mantry zgodnie z pierwszymi dwoma punktami. Odróżnij dwa stany rzeczy: jak jest i jak powinno być. Zdarza się tak, że spora część osób doskonale wie, jak powinno być, a mimo to, założenia architektoniczne nie są realizowane.

2.    RozpowszechnijZwołaj spotkanie i przedyskutuj Mantrę. Ustal od kiedy obowiązuje. Zorganizuj uwidocznienie Mantry w formie fizycznej (rysunki na flipchartach) lub w formie elektronicznej w przypadku dużych zespołów. Jeśli trzeba roześlij maile informacyjne. Niech to będzie wydarzenie.

3.    Monitoruj – przeglądy kodu, Definition of doneJeśli używacie Definition of Done, dodajcie jako jeden z punktów weryfikację, czy rozwiązanie jest zgodne z Mantrą. Analogicznie dla przeglądów kodu – niech to będzie jeden ze sprawdzanych elementów.

4.    Rób retrospekcjeRób regularne spotkania, w czasie których w zespole dyskutujecie, w jakim zakresie Mantra jest realizowana i czy jest to stan satysfakcjonujący. A jeśli nie to, co należy zmienić. Niech te retrospekcje będą poświęcone tylko i wyłącznie architekturze (designowi).

5.    ModyfikujMantra to żywy byt. Musi się rozwijać. Szczególnie sekcja „Czego się nie powinno robić”. Ona powstaje na bazie doświadczeń. Wcześniej wymieniona retrospekcja, to również miejsca na zadanie sobie pytania: czy obecna postać architektury jest wystarczająca? Może należy wprowadzić istotną zmianę? Może dla wybranej części systemu należy wprowadzić inne rozwiązanie (np. maszynę stanową albo osobny model).
To wszystko musi się dziać. Kto tego pilnuje? Lider architektury lub System Owner – osoba odpowiedzialna za spójność stosowanych rozwiązań.

Legacy

A jak powinna wyglądać Mantra w kodzie, który ma już za sobą długą historię rozwoju? Nierzadko zdarza się tak, że pierwsze wiersze systemu były pisane w C, później w C++, następnie w Javie, a potem dokładano do tego szynę ESB. Każde z tych podejść powodowało, że stosowano inne techniki do rozwiązywania podobnych problemów. Wtedy w systemie będzie istniało wiele różnych rozwiązań. Często brak ustalenia w projekcie, jak to powinno wyglądać ostatecznie, co robimy w przypadku modułu X, gdzie dominują praktyki z C++, a co robimy w module Y, gdzie masa kodu przypomina język C. W takim przypadku mamy do czynienia z kilkoma Mantrami, innymi dla różnych części systemu. Ich zdefiniowanie wyeliminuje pytanie – to jak to powinno być zrobione w tym miejscu, czy tak samo jak to robiliśmy ostatnio?



Podsumowanie

Skoro to takie nieskomplikowane, to dlaczego się to nie dzieje? Jest przynajmniej kilka powodów. Po pierwsze często wydaje się, o czym już wspominaliśmy, że jeśli stosujemy pewne podejście (np. Domain-Driven Design), to już jest wszystko jasne. Nic bardziej mylnego, wtedy tym bardziej trzeba się upewnić, że wszyscy w zespole rozumieją architekturę tak samo. Po drugie często po cichu liczy się, że osoby w zespole wchłoną wiedzę o systemie z kodu. Może tak się stanie, tylko na to potrzeba wielu miesięcy, jeśli nie lat. Kto ma na to czas? Kto za to zapłaci? Po trzecie liderzy często zapominają o tym, że wizję architektury trzeba rozpowszechnić. Wydaje im się, że jeśli oni to mają w głowie, to reszta zespołu też jakoś tę wizję przyswoi, niejako samoistnie. Trochę naiwne oczekiwanie.
Zatem nie pozostaje nic innego jak brać się do roboty:

  1. zwizualizować elementy architektury,
  2. zdefiniować odpowiedzialności,
  3. napędzać proces.