Transkrypcja
Wstęp do dyskusji o designie
Dobra, start. Cześć Michał.
Cześć Wojtek.
O czym dzisiaj porozmawiamy? Jaki temat możemy poruszyć?
Design. Design w systemach, design pewnie trochę w Legacy. Czym zatem pisanie jest? Jak można go łatwo zepsuć? I właściwie po co komu design?
Czyli w zasadzie „ale fo so chodzi?”. O co chodzi z tym designem? Bo to fajnie zacząłeś ilustrować zagadnienie, jak można ten design zepsuć. Ale też możemy porozmawiać o tym, jak można udawać, że się radzi z takimi zagadnieniami bez designu. Taką metodą „na żywca”, popularnie zwaną „ratatata”.
Bardzo znana metoda.
To bardzo znana metoda i bardzo szeroko stosowana w pewnych wąskich kręgach, trochę szerszych.
Czym jest i co trzeba wiedzieć o Domain Driven Design?
Dobra, to taką rozkmina o designie to może faktycznie warto jednak zacząć od tego, że ten design jest potrzebny. Co to właściwie ten design by był w naszym zawodzie, w naszej branży szeroko rozumianej?
Co nam właściwie daje?
Jak byś to tak miał scharakteryzować? Powiedzmy, że gdzieś tam mielibyśmy jakiegoś klienta i on by nagle zapytał: „A co ten design właściwie jest? Z czym to się je? Kiedy się zwróci?”.
„Kiedy to się zwróci?”.
Dokładnie, to jest podstawowe pytanie. No to słucham. Panie Wojtku.
Myślałem, że ty odpowiesz najpierw.
Nie, no to ja po to zadałem pytanie.
Nie no, to jest definicja dość szeroka. I design zwróci się w biznesowym sensie pewnie nieprędko, można powiedzieć, bo to jest raczej długofalowa koncepcja. Dla mnie zawsze to był taki troszkę koncept systemu, coś, co ten system nam kształtuje w jakieś ramy – w tym systemie – żeby to właśnie nie było wszystko podyktowane ad hocowymi decyzjami, że jednak jest za tym jakaś głębsza mądrość. I ten design, no, narzuca nam pewne ramy, w których się poruszamy, narzuca nam nawet pewne czasami ograniczenia – ale one też dają nam te ramy. Dzięki temu wiemy, czego się spodziewać, wiemy, co możemy zrobić. No i też system jest bardziej przewidywalny dla ludzi, którzy go obserwują i rozwijają.
On nawet nie tyle jest jedynie przewidywalny, co wręcz staje się takie trochę ustandaryzowane i, zwłaszcza jeżeli się zmienia skład zespołu, to wtedy, stosując jakieś praktyki z takiego, jakby to określić, takiego szeroko rozumianego designu, możemy sobie – nie chciałbym tutaj powiedzieć „wymieniać członków zespołu” – ale jeżeli już dojdzie do takiej konieczności, to później, po takiej wymianie, kiedy przychodzi ktoś nowy i styka się z taką czy inną praktyką projektowania, jest już dużo łatwiej ogarnąć cały grajdołek. Już można się po prostu porozumiewać jakimiś tam standardowymi, a przynajmniej rozumianymi w społeczności naszej pojęciami, jak na przykład domena. To pewnie o tym pojęciu też sobie dzisiaj trochę porozmawiamy.
Design a legacy code
Pewnie takich pojęć się pojawia całkiem sporo. Czy to rozmawiamy o designie, czy rozmawiamy o wszystkim wokół designu, czy poza designem, to i tak tych pojęć się pojawia mnóstwo. One dają jakiś tam obraz, jak ten projekt nasz wygląda. I też jednym z takich pojęć, o których można by było sobie porozmawiać przy tej okazji, jest znany i lubiany Legacy Code.
Oczywiście, więc tutaj tego zdecydowanie nie można uniknąć w dzisiejszych czasach, bo praktyka pokazuje, że „im więcej, im dalej w las, tym więcej drzew”. Czyli im dłużej rozwijamy całe nasze oprogramowanie, a rozwijamy już je jako nasza cywilizacja – tutaj mówią, że łacińska, chociaż nie, już tak ładny kawałek czasu – to po prostu przyrasta nam tego teraz już pewnie w postępie geometrycznym, jak jeszcze do tego dojdzie, to już nie wiem w jakim postępie to będzie przyrastać i to już będzie samo się rozwijać albo zwijać.
Albo zwijać. To zależy od kierunku, w który temat zostanie wyciągnięty.
No ale w każdym razie tego kodu Legacy, na razie bez definiowania, jak to tam się popularnie lub niszowo czasem definiuje, po prostu będzie nam tego kodu przybywać i będziemy musieli sobie umieć radzić z tym zagadnieniem – po prostu się go nie bać. I tutaj też niebagatelną rolę gra właśnie nasz design. Chociaż ja osobiście wolę to nasze rodzime sformułowanie związane z projektem, z projektowaniem. Nie jest to anglicyzm, czyli nasze praktyki projektowe. To będzie właśnie ten deseń. No i tak, mieliśmy tu sobie różne przymiarki do tej dyskusji, nie da się ukryć. I rozmawialiśmy w różnych kontekstach, o jakichś na przykład kontrastach między Greenfieldem – też popularne pojęcie ostatnio – a tym naszym legacy kodem. I w kontekście designu, co byśmy mogli na ten temat tutaj znaleźć?
Legacy niejedno ma imię i niejedną ma postać, toteż może nie będziemy się skupiać na Legacy w rozumieniu takim bardzo technicznym. Bo wiadomo, Legacy to jest też Legacy, gdzie mamy stare technologie, gdzie mamy stare frameworki, nie wspierane zupełnie, opuszczone. I to też jest jakiś problem, ale to nie jest problem do końca designu, bo to jest troszkę inny aspekt tego Legacy i na to są osobne sposoby, żeby to rozwiązać, włączając całkowite przepisanie systemu. Oczywiście tu bardziej chcę poruszyć ten aspekt, to co Michale wspomniałeś, takie bardziej trochę domenowe, czyli jak sobie zaprojektować tę naszą domenę i czy w ogóle ta nasza domena powinna być. I dlaczego powinno być, prawdopodobnie w centrum naszego systemu, żeby troszkę łatwiej wnioskować.
DDD w praktyce – czy to działa?
I dlaczego w ogóle powinno być? Bo de facto to domena jest sercem całego systemu. Nie robimy systemów po to, żeby składać te nasze serwisy, biny i całą tę resztę, to ma działać tylko dla siebie samej i dla kontenera potrzeb. Tylko robimy to dla potrzeby szeroko rozumianego biznesu. A ten biznes najczęściej ma domenę. I ta domena właśnie definiuje nam pewne rzeczy, które musimy w tej naszej aplikacji – czy greenfieldowej, czy jakiejkolwiek – zrobić. No i żeby to zrobić, musimy się na nich skupić. Wiadomo, że część techniczna też jest ważna, ale ta część domenowa warunkuje nam cały system. I teraz, co z tą domeną jest? Dlaczego ta domena czasami nam umyka i zostaje bardzo mocno przysłonięta przez aspekty techniczne, na których się skupiamy, zapominając o tych co jest istotą domenową?
Okej, bo to nie jest takie proste, a często jest to też nieciekawe czasami, bo te aspekty techniczne są ciekawsze. Bardzo często, zwłaszcza jeśli mamy do czynienia z domeną bardzo nudną, jak na przykład bankowe rzeczy, oczywiste dla każdego.
A te są ciekawe, ale…
Ale domeny bywają różne, a techniczne rzeczy są zwykle dla nas, inżynierów, ciekawsze.
Tak, tak. Czyli jeżeli projekt jest rozwijany przez inżynierów, to istnieje pokusa, żeby jednak zrobić go najfajniej, jak tylko się da? I ta pokusa często prowadzi nas w takie totalne krzaki, że więcej już się nie da iść dalej. Nie chciałbym tutaj uogólniać bynajmniej, bo są różne projekty i mogą być różnie prowadzone, ale widywaliśmy już takie projekty, które po prostu próbowały gdzieś tam w pewnych momentach doścignąć takiego najbardziej topowego rozwiązania związanego z czymś tam, najczęściej właśnie tuż obok domeny, z pominięciem samej domeny. I można spędzić długie godziny na takich fajnych rozkminach i można sobie bardzo ciekawe dyskusje. My sami prowadziliśmy takie dyskusje po cztery godziny, czasami w szerszym gronie. Kiedyś to były czasy, takie dyskusje.
Tak, więc się siedziało w czterech takich już seniorów, prawie z brodami i można było dyskutować o tym, jak daną transakcję rozproszoną można by było zamodelować tu i ówdzie i co tam z tego wynika i jak tam sobie radzić z błędami. I wszystko to było pięknie, tylko czasami się okazuje, że lepiej ten czas poświęcić po prostu na rozkminę tejże domeny, albo w ogóle zastanowić się, czy my w ogóle o domenie myślimy, co my chcemy osiągnąć.
Osiągnąć, dokładnie tak, jak powiedzieliśmy – kiedy to się zwróci. Bo przyjdzie w końcu do nas ten klient albo jakiś jego przedstawiciel, popularnie zwany P.O., i zapyta: „Co to w ogóle robicie, szanowni deweloperzy?”, a my powiemy: „To właśnie mamy taki fajny framework, który nam rozwiązuje miliard problemów i popatrz, jak to fajnie się teraz dzieje”. A on nam mówi: „Ale tutaj miał być dodany nowy przycisk na tym formularzu”.
Jeszcze go nie ma, ale my już mamy w zanadrzu rozwiązanie na milion przyszłych problemów, do których nawet jeszcze nie pomyślałeś, o których nie śniło się fizjologom, które prawdopodobnie nawet nie wystąpią, ale my już mamy na nie rozwiązanie. Gdyby wystąpiły, to my już po prostu, tylko nie muszą występować, bo już mamy je rozpracowane.
Nie, tylko jednak to nie za te rozwiązania nam ten klient płaci, tylko za nasze zrozumienie domeny, a tak naprawdę za przełożenie tej domeny, jego domeny, jego biznesu na język maszynowy, który później musi nam dać te artefakty, które wykonają to, co ten klient chciał. No bo jak tak popatrzymy właśnie na to od strony domeny, to nie chcemy tutaj się kusić na jakąś tam definicję, bo już dawno czytałem jakąś książkę na ten temat – można by się tak przyznać nawet – ale taka domena to jest po prostu coś takiego, z czym ten klient na co dzień sobie żyje. I ponieważ on sobie z tym żyje i przyszedł do nas z jakimś tam problemem wynikającym z tej domeny, to można by powiedzieć, że naszym obowiązkiem jest najpierw posłuchać go, co on tam właściwie mówi, spróbować zrozumieć, czy to, co on mówi, ma sens. Jeżeli to nie ma totalnie sensu, to może coś w tym też jest, że on mówi o czymś, co nie ma sensu i dlatego mu to nie działa. Więc naszym zadaniem jest tak naprawdę szukanie zrozumienia, tak bym powiedział, tak na pierwszy rzut oka. W ogóle przy analizie domenowej powinniśmy starać się zrozumieć, o czym my tu w ogóle rozmawiamy. Jak już nam się to udało, jak już zrozumieliśmy, o czym rozmawiamy, to może warto by było zacząć wyłaniać jakieś tam pojęcia z tego, co wiem, ogromny wspólny język.
Tak, tak zwany wspólny język. I ten wspólny język jest o tyle ważny i o tyle fajny, że tak naprawdę do niedawna właściwie o takim projektowaniu domenowo zorientowanym to odważnie i głośno mówi się stosunkowo od niedawna. Wcześniej to tam były jakieś mniej lub bardziej wyszukane frameworki do tego. No i można było projektować aplikacje, na przykład siadało się do modelu bazy danych i robiło się diagram encji i koniec, i mieliśmy projekt gotowy. No i później, korzystając z pewnych udogodnień typu „yet another service”, można było wyprodukować całe to spaghetti, które tam później obchodzono.
Złożoność systemów a podejście do designu
Też przez to, że może to jest trochę – to jest subiektywne wrażenie, a może – że kiedyś wszystko było prostsze, ale też domeny były prostsze. Może nawet nie tyle domeny, co systemy, które tę domenę obsługiwały. Bo teraz zobacz, że jeśli mówimy o systemach współczesnych, to naprawdę często one muszą ogarniać bardzo wiele rzeczy, bo coraz więcej procesów jest przenoszonych, jest automatyzowanych. Więc siłą rzeczy te nasze domeny właściwie są coraz bardziej, coraz lepiej odwzorowane przez system, co sprawia, że są bardziej skomplikowane. Więc już takie proste narzędzia w stylu „zróbmy sobie schemat bazy danych, a później wygenerujemy encje bądź zwyczajnie napiszemy i system będzie jakoś działał”, teraz może to już nie przejść, bo jednak te nasze systemy mają już taki poziom komplikacji, że te narzędzia, taka prosta analiza, już nie jest wystarczająca. Musimy mieć lepsze narzędzia, jakiś lepszy aparat, żeby te domeny analizować, żeby je łączyć albo czasami rozdzielać, jeśli domeny są jednak tylko pobieżnie może połączone, ale tak naprawdę to są jednak troszkę inne kawałki tego biznesu. Więc może to jest ten problem, że ten biznes ogólnie jest coraz bardziej skomplikowany.
Tak, to jest słuszna uwaga moim zdaniem, bo faktycznie jak się popatrzy – żeby daleko nie szukać – to można sobie rynek gier, znany i lubiany też tak w niektórych kręgach, prześledzić. I kiedyś to były gry, ale też te gry były prostsze. Dzisiaj jak jakieś nawet mniejsze studio, tak zwane indie, biorą się za jakąś grę, to często jest to proces – ten proces wytwórczy jest rozpisany na długie miesiące, jeśli nie lata. Kiedyś, zgodnie z legendami, jakie jeszcze pamiętamy, wystarczyło siąść w tym mitycznym garażu i wyklepać jakąś tam grę na Amigę i zgarniać kasiorę. Zresztą polecam tę biografię Sida Meiera. Ostatnio pokazała się fajna książka opisująca jego przygody od początku jego kariery i tam jest taka fajna opowieść o tym, jak on tworzył Cywilizację. To tak naprawdę, jeśli tak faktycznie było – nie mam powodu wątpić w to po przeczytaniu tej książki – to ta Cywilizacja numer jeden powstała w kilka miesięcy siłami właśnie jednego człowieka. I to się dało zrobić. Pomijam tutaj aspekt oczywiście, że ten czy ów jest bardziej genialny od drugiego, ale akurat Sid Meier to chyba należy do takich projektantów, którzy potrafią sobie poradzić z tym tematem.
To jest pewnie potrzebne, jakiś tam analityczny umysł i tego typu rzeczy, no i masę pasji, więc pewnie on akurat był w stanie to osiągnąć, jak ktoś inny by w tym samym jego garażu mógł tego nie osiągnąć.
Tak, ale też na pewno taki nawet Sid Meier nie byłby w stanie zrobić Cywilizacji 7, najnowszej, cenionej, gdzieś tam jest w toku prac. Sam nie byłby w stanie tego zrobić. Tutaj też widać, że te systemy są coraz bardziej skomplikowane. To już nie jest czas, gdzie możemy sobie sami w garażu zbudować tę rakietę, ten system. To już jednak potrzebne są zastępy ludzi, zastępy programistów, analityków, żeby to wszystko jakoś ze sobą spiąć.
Tak jest. Tym bardziej, że coś, co kiedyś byśmy nazwali jakimś pojedynczym systemem albo całością, dzisiaj prawdopodobnie jest jakimś pojedynczym mikroserwisem, porównując rozmiar tego, może albo nam dać po prostu funkcjonalność, zakres – tak, zakres działania. I teraz mamy uniwersum złożone z tych takich mikroserwisów albo po prostu usług, które gdzieś tam występują, które piszemy my, które piszą inni i my chcemy się w którymś momencie wpiąć w ten cały ekosystem i skorzystać to z tego, to z tamtego. Doskonałym przykładem jest jakaś bramka płatności, z której wszyscy korzystają teraz i tych bramek płatności jest teraz N, systemów jest K i mamy wszystkiego P silnia tych wszystkich możliwości połączenia. Więc pewnie stąd to wynika, cały ten poziom skomplikowania i, jak to się mawia, życie nam napisało taki scenariusz, że musimy się wpisać w to i, no i teraz jak to można wpisać? Jak to my próbujemy, my, dzielni programiści, próbujemy sobie siąść do tej klawiatury? To nam przyszedł klient i opowiada nam, jakie tam ma fajne dyrdymały w tym swoim biznesie. My już składaliśmy, zapisaliśmy sobie te jego wszystkie koncepty. No i wypada co? Narysować ten schemat bazy danych, do klawiszy i szybko wyklepać mu tamten, ja tam o DSL basis, niech mu tam, że zrobi to, co trzeba.
Kiedy DDD naprawdę się opłaca
No właśnie. I teraz jasno, moim zdaniem, zdajemy sobie sprawę ze złożoności zadania, zdajemy sobie sprawę ze skali problemu. Tylko właśnie co, co możemy z tym zrobić tak naprawdę? I chyba właśnie troszkę to myślenie, troszkę poza też kontekstem tego, co chcemy zrobić, jest bardzo przydatne. W sensie, czy nasz system to – to jest oczywiście pytanie z odpowiedzią „nie” – w sensie, czy nasz system żyje gdzieś na bezludnej wyspie? No nie, zawsze to jest część jakiejś większej całości. Też warto zastanowić się, jak się ten nasz kawałek wpisuje w to, ten kawałek. Mamy go częściej niż rzadziej. Ten kawałek jest bardzo wielkim monolitem i tam tak naprawdę tych czynności jest całkiem dużo. I teraz pytanie, co zrobić, jeśli przyjdzie nam coś w nim zmienić? Jak możemy to łatwo zrobić i czy po prostu powinniśmy robić to jakimś work, tak jak robili to nasi pradziadowie i pradziadowie, nasi poprzednicy na tym miejscu, których już nie ma, więc nawet nie możemy ich zapytać. Więc co robić?
No i tutaj dochodzimy zgrabnie do takiej koncepcji właśnie, którą zasygnalizowałem na początku rozmowy, mianowicie, że ten nasz system, jakkolwiek on by był rozwijany od 3 miesięcy czy 5 lat, czy 15, a może 35, bo i takie istnieją, a może i starsze jeszcze można by kilka znaleźć – jak ten system teraz nazwać, zdefiniować? On aż się prosi, żeby go nazwać, ale w tym kontekście, że po prostu jest spuścizną po tych wcześniejszych pokoleniach. To jest taka jedna z używanych definicji, dość dobrze się moim zdaniem wpisująca w to, co dostajemy, bo my dostajemy po prostu taki zbiór artefaktów po wcześniejszych pokoleniach deweloperów, których tam nie było wcale mało. Samych deweloperów, czasem pokoleń było też kilka i było bardzo dużo różnych wzorców. Wszystko jest wymieszane i po prostu było tworzone pod wpływem tych czasów, które wymagały danej zmiany. Skumulowany taki miszmasz wszystkich zmian, które ten system przeżył od początku swojej świetności.
I jeszcze, to o czym też często rozmawiamy w naszych rozmowach, oczywiście offline’owych, to to, że ten system, skoro on dożył już tych czasów, to on jednak ma wartość i ta wartość musi teraz być rozwijana. Nie – ona nie dość, że musi być utrzymana, to jeszcze musi być rozwijana, bo jeżeli my nie będziemy rozwijać tej jego wartości, on po prostu nie podąży z duchem czasu, mimo że on jest już Legacy dzisiaj. On jednak musi nadążać za zmianami w biznesie, więc my musimy od strony technicznej umożliwić mu to nadążanie za tym.
To nie jest Legacy w takim znaczeniu negatywnym, tylko Legacy w znaczeniu dojrzałego systemu, który spełnił i pewnie wciąż spełnia swoją funkcję biznesową, tylko wymaga drobnych ulepszeń.
Drobnych ulepszeń i drobne ulepszenia oczywiście mogą być ulepszeniami technicznymi, bo jednak jeśli system zużyje ileś tam lat, to siłą rzeczy będzie się starzał. Ale ulepszeniu ulegają też procesy biznesowe, bo wiadomo, że system się zmienia, biznes ewoluuje i musimy te zmiany gdzieś tam wprowadzać.
Czasem ewoluuje jeszcze – przepraszam, że wejdę w słowo – środowisko wokół systemu po prostu. Musimy też systemowi umożliwić funkcjonowanie w tym środowisku i dobrym przykładem jest system na przykład w bankowości albo w podatkach, albo w jakiejś takiej domenie, która jest silnie związana z prawem. Kiedy następują zmiany w prawie, one są oczywiście ogłaszane z jakimś wyprzedzeniem – czasami kilkudniowym, jak to ostatnio bywało – ale przeważnie to jest w takim bardziej rozsądnym, że na przykład zmiany w podatkach następują na początku roku. No i fajnie jak jesteśmy na początku roku i wiemy, że mamy prawie cały rok do uwzględnienia tej zmiany. Gorzej jak się dowiadujemy o tym w październiku, a tu trzeba do stycznia wypuścić nową wersję. No i się okazuje, że to wcale nie jest takie proste.
Nasz cykl zajmuje 3–4 miesiące, tak?
No właśnie, a wspominaliśmy tam takie słowo monolit i to nie było przypadkiem. Chociaż niekoniecznie te monolity też muszą być takie złe. Wprawdzie monolitom z Wiedźmina się solidnie oberwało wśród krytyków, ale jednak czasami elity się sprawdzają tu i ówdzie, a też może się oberwać jakiemuś wrogowi mikrousług. Bo w nowym sezonie oczywiście nadal poczekamy. Więc mamy sobie ten nasz monolit, który nie wiem co on tam robi, ale coś tam robi. Jest jakaś domena tam, jest osadzona w jakimś tam środowisku. No i przychodzi Product Owner i mówi tak: „Słuchajcie, miłościwie nam panujący właśnie wymyślili taki przepis, że Jezus Maria!”. No i co my teraz zrobimy? No i my siadamy, planning, te sprawy i patrzymy w kod i Jezus Maria, faktycznie, to się, to jest koniec. Jest, nie. Dobra, to ten scenariusz to oczywiście horror, zostawimy, ale tak na co dzień to jednak się musi coś tam dać. Więc tutaj, tak jak Wojtek wspomniałeś, mamy system, który jednak się sprawdził w boju. On nam tam klientowi naszemu przynosił już wartość przez X lat i jesteśmy świadomi tego, że dobrze by było, żeby on przynosił tę wartość wciąż. Więc teraz sięgamy po nasze na poły techniczne, a na poły takie trochę miękko-ogólne jakieś zdolności, które pozwolą wprowadzić tę akurat zmianę do tego akurat systemu i tu mamy cały wachlarz możliwości. Możemy na przykład zdecydować się na wywalenie tego, co było, czyli wyrwiemy z korzeniami ten kawałek monolitu i wyspawamy tutaj zaraz takie nowe cacko, że będzie się podobało. Tylko czy my mamy na to czas?
Bezpieczeństwo i modularność zmian
No właśnie, czy mamy czas? I czy mamy też biznesowe otoczenie, które nam na to pozwala? Tak naprawdę, żeby wprowadzić jakąkolwiek zmianę do jakiegokolwiek systemu, czy to Legacy, czy Greenfield, musimy mieć jakąś pewność, mniejszą czy większą, że ta zmiana jest bezpieczna. Czyli siatka bezpieczeństwa. Musimy mieć jakieś minimalne testy, jakąś minimalną weryfikację, że cokolwiek robimy, przechodzi, powiedzmy, jakiś tam kawałek, jakiś proces weryfikacji, jakiś proces weryfikacyjny. Więc to jest w ogóle początek wszystkiego i to też musimy zapewnić. Więc nawet jeśli tego nie mamy, warto jednak ten kawałek sobie gdzieś tam dodać, dopisać i zweryfikować, że to działa tak, jak faktycznie powinno działać. No bo jednak wiadomo, nowe rzeczy i nowe, nowe ficzery nam coś zmieniają i nie chcemy, żeby stare rzeczy nam przestały działać. Więc to jest część taka oczywista. No i zrozumienie domeny to jest podstawa, bo wiadomo, gdzie ten nowy ficzer ma wejść? No to jest pytanie, czy to jest faktycznie nowy ficzer, czy to tylko modyfikacja czegoś, co już w systemie istnieje i już jest zaimplementowane w postaci jakiegoś kawałka subdomeny, powiedzmy, czy to gdzieś już jest zaprezentowane. I od tego zależy, gdzie mamy tak naprawdę ten nasz punkt wejścia. Jeśli to jest zupełnie nowa rzecz, teoretycznie mamy prościej, bo możemy sobie zrobić z tego naprawdę fajny jakiś kawałek modułu, jakąś odseparowaną część. I żebyście nawet mogli się – tak, monolit nie oznacza, to jest taka zewnętrzna, można powiedzieć, powłoka – to co w środku jest tego monolitu, bo to tak naprawdę może być troszkę lepiej, posiadać lepszą strukturę.
Tutaj to nawet jeszcze – przepraszam – dopowiem, to może być tak perfekcyjnie zmodularyzowane wewnętrznie.
Tak, tak, mamy do dyspozycji, mamy do dyspozycji z Javą dziewiątką pakiety. Akurat wspominamy Javę, mamy w innych językach różnego rodzaju narzędzia. Java nie jest tu najlepszym, że tak powiem, technicznym środkiem, żeby te nasze granice fajnie gdzieś tam wyrazić, więc pewnie trzeba też w inne sposoby radzić, no ale na pewno da się to zrobić.
To dlaczego mikroserwisy są tak jakby na topie, można powiedzieć? Jest jedną z przyczyn jest to, że dają nam te fizyczne granice, więc bardzo ciężko jest złamać i naruszyć te nasze granice domeny, bo jednak nie tak łatwo zawołać jakiś tam serwis z innego mikroserwisu, no bo to trzeba mieć jakieś API, trzeba to zawołać jakoś ramienia, jakieś uprawnienia. Bo tutaj ta fizyczna bariera, którą nam dają mikroserwisy, sprawia, że trudniej tę granicę naruszyć. Ale pytanie, czy jeśli takie granice trudne do złamania będą również w konflikcie, to czy to nam nie załatwi sporej części roboty bez jednoczesnego narzucania wielu ograniczeń, które dają nam mikroserwisy, jeśli chodzi o wdrożenie, monitoring, zarządzanie tego typu rzeczami?
To jest to, to jest sedno całego problemu, żeby te nasze rozwiązania, te nasze kawałki gdzieś tam implementacji tej czy innej funkcjonalności, naprawdę fajnie się izolowały od siebie, czyli klasyczne: spójność systemu kontra coupling systemu. Czyli chcemy mieć spójny system, czyli kawałki, które często się ze sobą wiążą i łączą w danym ficzerze, mają być blisko siebie, a te, które są przypadkowo gdzieś koło siebie, czyli tworzą nam ten coupling, żeby były jak najmniej od siebie zależne.
Granice domeny i kontekst
Tak jest i mamy na to też szereg intrygujących narzędzi na zapewnienie czegoś takiego. Tutaj się pojawiło fajne sformułowanie „granica”. I ważne jest, żeby tych granic sobie szukać stale, żeby ich nie przekraczać czasami, a czasami żeby je właśnie przekraczać. Ale w kontekście takiego dobrego, nowego projektu to właśnie te granice domeny i granice poddomen, które tam występują. Bo czasem domena może być rozumiana jako jakiś ogólny zestaw procesów, zachowań systemu, ale w obrębie tych zachowań systemu mamy jakieś tam dodatkowe zagadnienia, po prostu składowe, z których się cały ten zestaw składa. I te zagadnienia są na tyle specyficzne, że udaje nam się wydzielić poddomenę, więc nie ma się co obawiać takiego nawet zwiększania granulacji, bo może to prowadzić właśnie do lepszej modularyzacji i możemy w obrębie tych granic działać dosyć bezpiecznie i wprowadzać zmiany. Natomiast jeżeli pojawia się zmiana, już po tej naszej głębszej analizie, taka, która by chciała nam gdzieś tam po tych granicach bardzo mocno, ochoczo latać w tę i z powrotem, to już jest sygnał do zastanowienia się, czy aby to jest dobre podejście. I tutaj te granice, zanim je zaczniemy szukać w kodzie, czy tam między modułami, czy jakkolwiek inaczej technicznie, dobrze jest postawić sobie takie pytanie, czy my ich nie przekraczamy w samej koncepcji tego feature’a? Czyli czy mówimy o poprawnie zorganizowanym modelu, czyli – to też tutaj nawiążę do takiego zaprzyjaźnionego kursu, który ostatnio przeglądaliśmy, „Legacy Fighter” – szczerze to polecam, zresztą polecamy zdaje się wszystkim odbiorcom. Tam jest fajnie to zagadnienie opisane jako coś, co można nazwać Legacy modelem. Jeżeli mamy, jeżeli nasz model domenowy, powiedzmy, że nawet mamy ten model domenowy, ale ten model domenowy jest nieprzemyślany wystarczająco dobrze i na poziomie samego modelu – przepraszam – na poziomie samego modelu mamy jakieś zachowania, które nie powinny występować, no to później przy przekładaniu tego na język techniczny, jakiś tam coś blisko metalu, siłą rzeczy nie unikniemy też takich samych błędów, tylko że te błędy bardziej nam dadzą znać o sobie, jak już będą w tych artefaktach, które wytwarzamy, niż na kartce z modelem, kiedy projektujemy. Więc tutaj dobrze jest jednak, rozpoznając pojęcia domenowe, od razu identyfikować te procesy, które nam wyznaczą jakieś tam granice domeny i starać się tego trzymać. I teraz może się zdarzyć tak, że przyjdzie do nas ten klient i powie nam: „Słuchajcie, mam tu genialny pomysł, bo nam wyszło z rozkminy w internetach, że ten ficzer będzie po prostu świetny”. Ale my powiemy: „Ten ficzer nie ma sensu, dlatego, że…”. Taki klient może być, czy też nie? Ja tutaj zbiorczo używam określenia „klient” dla P.O. czy kogokolwiek, po prostu jest to ktoś z wizją biznesową. Ta wizja biznesowa może wybiegać daleko w przód.
Ale jeśli przychodzi z workiem pieniędzy, z pomysłem, kim jesteśmy, żeby myśleć, żeby negować takie pomysły?
Nie, broń Boże, to wtedy się nie neguje, tylko po prostu się robi.
A powinniśmy.
No niestety, niestety rynek zweryfikował. Jak byśmy jednak chcieli wyprodukować porządny legacy system, który się obroni po 20 latach, to może jednak dobrze byłoby to już nieco zweryfikować. Takie przypadki w naszych karierach się zdarzały. Czasami jest po prostu okazja, żeby sprostować pomysł ten czy ów. Może nie tyle odrzucając go, bo naprawdę, jeżeli Product Owner przychodzi z ciekawym pomysłem, to nawet jeżeli system, nawet jeżeli model systemu w tym momencie nie wspiera go, to warto się zastanowić, bo to po prostu wygeneruje jakąś tam wartość w przyszłości. Tam też siedzą bystrzy ludzie i ich zadaniem jest rozkminiać biznes od strony biznesowej. Więc jeżeli oni widzą, że jest jakiś trop w tym biznesie, którym trzeba koniecznie podążyć i na razie zrobić jakąś małą zmianę, na przykład burzącą porządek świata, a później ją rozbudowywać, to my powinniśmy – my, już w odniesieniu do projektantów oprogramowania mówię – my powinniśmy podążyć za tym tokiem rozumowania i znowuż starać się zrozumieć, co autor miał na myśli i spróbować dopasować jego tok rozumowania do naszego toku rozumowania. A nasz tok rozumowania jest z kolei bardzo silnie wspomagany tym, co mamy pod maską. Więc jeżeli my widzimy, że pod maską nam się nie zgrywa i nam zaraz się silnik zatrze, to powinniśmy zacząć przebudowę tego silnika. Tylko że nie od dokręcania wszystkich śrubek, jakie mamy pod ręką, ani walenia młotkiem, tylko od zadawania sensownych pytań tam na samej górze, na etapie tego projektu.
Nadmierne uogólnianie a różne modele domenowe
Chyba czasami się nie zgrywa – to jest ten problem. Dlaczego nam czasami się to nie zgrywa? Bo jako deweloperzy, jako programiści, czasami mamy nadmierną tendencję do nadmiernego uogólniania i chcemy dopasować od razu nadmierną pastę, by dopasować najlepiej jeden fajny, generyczny model do wszystkich przypadków. I oczywiście mamy jakąś tam klasę, mamy różne statusy, podstatusy i chcemy wszystko takim jednym sprytnym narzędziem rozwiązać tak, żeby to było generyczne, tak, żeby to było czysto i żeby się nie rozdrabniać. Tak naprawdę, żeby przyspieszyć iteracje, żeby modelować różne pomysły, to nie możemy też obawiać się różnych modeli. Nawet jeśli te modele miałyby, wydawać mogłoby się na pierwszy rzut oka, jakieś elementy wspólne, które już chcemy gdzieś tam połączyć, bo tu widzimy, że tu są dane użytkownika i tu są dane użytkownika, a to jest jeden użytkownik. Tylko że tak naprawdę to w różnych kontekstach może znaczyć zupełnie co innego. Nie ma też, nie możemy się obawiać pewnych powtórzeń, pewnej duplikacji danych. No bo to rozdzielenie czasami nam umożliwia dodanie jakiegoś nowego ficzera, niezależnie od tych poprzednich podchodów, które również opierają się teoretycznie na wspólnym modelu, ale jednak wtedy nam się to zwiążą i stworzą nam właśnie ten coupling, jeśli będziemy mieli wszystkie ficzery oparte na jednym wspólnym modelu, który tylko łączy się jednym wspólnym polem, ale tak przypadkowo się złożyło. No to niestety będziemy mieli bardzo mocny krupnik i to będzie bardzo ciężkie, żeby taki system dalej rozwijać i jakoś go rozszerzać. Więc jeśli gdzieś mamy 15 statusów, no to warto sprawdzić, czy to na pewno jest ten sam proces, czy to jest na pewno ten sam biznesowy case. To jednak są zupełnie inne modele i tak naprawdę trzeba by to było zaprezentować w inny sposób.
Dokładnie, bo tutaj możemy o modelu mówić w kontekście procesów, ale też i w kontekście danych, jakie te procesy analizują czy też przetwarzają. I nawet przytoczę taką anegdotę, gdzie kiedyś, dawno temu, byliśmy w pewnym projekcie – tak się składa, że we dwóch w tym samym – i tam mieliśmy taką tabelę, która miała wszystkie dane obiektu, na którym pracowała domena. Ale ponieważ ona chciała mieć wszystkie dane, tylko Oracle nie pozwalał mieć tam więcej kolumn niż 200 – nie pamiętam dokładnie już takiego – więc powstała tabela o takiej samej nazwie z cyferką 2, która miała resztę. Więc można tak, ale czy to jest akurat korzystne? Nie tutaj. Tu się pojawiły, przemycił tak sprytnie pojęcie, które zawierało i granicę, i kontekst w jednym. I to jest właśnie to, czego powinniśmy szukać, bo to nam pomoże podzielić domenę na konteksty, które mają swoje granice. To ma swoją nazwę „bounded context” i możemy faktycznie mieć jakąś jedną tożsamość, na przykład użytkownika, który właśnie teraz operuje, tego operatora naszej domeny. To będzie jakiś użytkownik, który się zalogował, więc on gdzieś tam w domenie autentykacji czy domenie security, zależnie jak ją tam nazwiemy, w domenie użytkownika, on ma swoją tożsamość użytkownika, ale on tutaj przychodzi do naszej domeny, przychodzi w jakiejś roli. On tę rolę może mieć różną w zależności od tego, jaką mu tam nadamy, zgodnie z systemem uprawnień, który jakoś tam przylega do domeny użytkownika, ale domena użytkownika opowiada nam o tożsamości, a domena prawnik opowiada nam o uprawnieniach tychże tożsamości. A już nasza docelowa domena, łącząc te dwa koncerty, nadaje po prostu użytkownikowi jakiś profil, który on w tym momencie wykorzystuje i to, co my właśnie…
Całkowicie odrębne byty. I nie ma się co obawiać tej odrębności, bo tak.
Czym jest Domain-Driven Design?
No bo właśnie z tej odrębności wynika moc tego rozwiązania, bo my tak naprawdę powinniśmy być jak najbliżej pojęć domenowych, jakie występują w tym biznesie, nie unikając też pojęć domenowych, które, powiedziałbym, wynikają z takiego troszkę patrzenia na domeny jak na byty techniczne, czyli na przykład taka domena zarządzanie użytkownikami. Ona w większości przypadków w różnych projektach wygląda bardzo podobnie. Możemy ją oczywiście skomplikować. My możemy dokładać do tego użytkowników różne dziwne rzeczy, ale możemy też popatrzeć na to zagadnienie jako na takie bardziej standardowe i zastosować jakieś tam zdobyte lub zasłyszane tu i ówdzie najlepsze praktyki do modelowania tej domeny użytkownika i okaże się, że domena użytkownika jest kompletna, malutka, ale kompletna i wystarcza do tego, żeby użytkownik miał dostęp do naszego systemu. Zazwyczaj na tym nam zależy w tej domenie. Natomiast w domenie sąsiedniej, do której chcemy go przekierować, jak on już się zalogował, to on już musi mieć jakiś tam swój profil, jakieś tam procesy związane z obsługą tego profilu, czy też ten profil musi mieć dostęp właśnie do tych procesów, które on będzie wykonywał? Więc bounded contexty. Jest to na pewno narzędzie na poziomie modelowania, które nam zapewnia takie rozróżnienie.
Chaos w projekcie? DDD może pomóc
Możliwość takiego rozróżnienia, dokładnie. Co jednocześnie ułatwia nam też rozumowanie, bo jednak ograniczamy się w analizie – czy analizie problemu, czy nawet implementacji – tylko do tego kawałka, który rzeczywiście teraz oglądamy. Nie musimy zastanawiać się, czy to jest jedna nasza wspólna klasa, występuje w piętnastu innych poddomenach i jednocześnie jest już pojemnikiem na różne przypadki użycia. I co się stanie, co zepsujemy, jeśli dodamy do tego jakieś tam jedno pole czy jedną rzecz? Więc jakby ograniczamy, minimalizujemy zakres naszej zmiany i pole rażenia potencjalnych błędów, więc to na pewno ułatwia nam wprowadzanie jakichkolwiek zmian i to jest w zupełności do zrobienia w starym, zwykłym monolicie. Nie ma się czego obawiać. Możemy spokojnie to zrobić i w ten czy inny techniczny sposób jakoś to odgrodzić od innych części systemu i nie ma problemu, żeby nikt do naszego podwórka nie zaglądał i żeby te ficzery żyły własnym życiem, nie zapominając o innych, ponieważ nie ma się co tych monolitów obawiać. Z uwagi na to, że równie dobrze w świeżutkich mikroserwisach też możemy się doczekać Legacy bardzo szybko, to jest to, jak szybko wyprodukujemy w danym kawałku kodu zdolność do bycia legacy, to już zależy od naszej inwencji popartej brakiem pewnie tych dobrych praktyk, albo przynajmniej takiego trzeźwego myślenia, bo z tymi praktykami to jest różnie. Z tego co zaobserwowałem, jest ich bardzo dużo i dla jednych są lepsze, dla innych gorsze. Te lub tamte, nie? Więc każdy jakieś tam swoje preferencje w końcu zdobędzie.
Nie tylko dla enterprise’ów: DDD w małych zespołach
I pewnie dobrze jest też patrzeć na te dobre praktyki w kontekście problemu, które one rozwiązują. Jeżeli jakaś dobra praktyka pracuje świetnie w danej domenie X, to niekoniecznie w domenie Y ona będzie się tam, powiedzmy, najlepiej sprawdzać. Może trzeba ją lekko zmodyfikować. To będzie pewnie podobnie jak z kursami projektowymi, które trzeba dopasowywać do zagadnienia i nie da się ich tak zaimplementować „na pałę”. Do tego nie ma bibliotek wzorców projektowych gotowych do użycia w Javie, tylko po prostu jest opis, co dany wzorzec, jakie właściwości posiada, w jakim kontekście należy go stosować, jak to zrobić dobrze, czego unikać, żeby nie zrobić tego źle i żeby nie wprowadzić antywzorca. Więc z dobrymi praktykami, rzekłbym, jest bardzo podobnie, bo dobra praktyka też musi być inteligentnie dopasowana do rozwiązania i tutaj nie ma się absolutnie czego bać w monolicie ani też w mikroserwisach. Każda architektura ma jakieś tam swoje mniejsze lub większe niedomagania.
DDD w praktyce – czy to działa? Monolity kontra mikroserwisy: Spojrzenie na architekturę
Nie wspomnieliśmy o monolicie, to jest takie dość popularne pewnie myślenie, że monolit jest duży, ciężki, ciężko się go wdraża.
Zwykle pewnie jest.
Zwykle pewnie jest, nie, ale jak sobie weźmiemy takie mikroserwisy w ilości kilkudziesięciu, to pewnie cała ich ta kombinacja jest duża, ciężka i pewnie ciężko się ją wdraża i ciężko się utrzymuje i ciężko się rozmawia między nimi. I pewnie trzeba jakieś sprytne triki stosować do tej komunikacji, bo o ile w monolicie poszczególne fragmenty jakieś tam, załóżmy, że mamy jakąś modularyzację, że poszczególne moduły ze sobą rozmawiają, one pewnie robią to przez jakieś interfejsy – dobrze by było gdyby tak robiły, bo jak robią to każdy z każdym i jest robota, to dupa i spaghetti i w ogóle wszystko wymieszane, no to sorry, to tutaj najlepszą książką jaką można polecić to jest „Working Effectively with Legacy Code” Michaela Feathersa do rozwiązywania tego. Ale jak mamy takie stado mikroserwisów, to one też mają z racji tego, że już są mikroserwisami, to już muszą mieć jakieś interfejsy komunikacyjne wystawione i też jest pytanie, czy tam rozmawia każdy z każdym, czy są jakieś kanały komunikacyjne wydzielone? Bo już miałem tutaj pewne słowo na końcu języka, ale zaczekamy z nim do odcinka trzeciego. Więc jeżeli komunikacja jest zorganizowana w sposób jakoś ogarnialny i przewidywalny, no to jest troszkę łatwiej, niż kiedy nagle się okazuje, że żeby zrobić ten czy tamten kawałek procesu biznesowego, my nagle musimy z jednego mikroserwisu zawołać dziesięć innych i rozpatrzeć wszystkie przypadki fail w tej komunikacji.
Co trzeba wiedzieć, zanim wdrożysz DDD?
To po kolei. Czyli mamy tutaj zaawansowane zagadnienie transakcji rozproszonej i radzenia sobie z problemami w tej sytuacji. Jeżeli oczywiście mówimy o transakcji, bo możemy nie mówić o transakcjach i wtedy mamy całkiem inne problemy do rozpoznania i załatwienia, a mianowicie jeżeli wszystko leciało po babce i mamy transakcję, no to siup, nagle wszystko nam się zginęło i też nie mamy wcale łatwo, bo mamy ileś tam kroków do skompletowania, prawdopodobnie w ten czy inny sposób, ale przynajmniej wywalamy ten błąd na ekran i załatwione i użytkownik się zastanawia, co znowu się stało, że istniejemy? Dziesiąty raz zapisać tego raportu, czy co on tam robił? Nie.
Czy DDD jest dla Ciebie? Autonomia zespołów i prawo Conwaya
Nie da się ukryć, że podejście mikroserwisowe jest – przede wszystkim stoi za nim autonomia, autonomia zespołów, autonomia technologii, autonomia wdrożenia, ale również autonomia tak naprawdę fail, fail poszczególnych mikroserwisów – wszystko to może odbywać się niezależnie. Część z tych rzeczy tak naprawdę możemy sobie gdzieś tam stosować w podejściu monolitowym. Nie ma problemu, żeby pożenić i Javę i Kotlina. Możemy mieć te dwa języki w jednym monolicie i sobie używać ich jednocześnie? Jakby nie patrzeć, wspomniałeś bazę danych i wspomniałeś monolit, to już jest system rozproszony de facto. My mówimy monolit jako monolit, jako system nierozproszony, ale jeśli mamy bazę danych i mamy nasz backend, to już mamy system rozproszony. Oczywiście mamy go, wygląda jak jeden tylko, wygląda. Oczywiście połączenie z bazą danych jest znacznie lepiej rozwiązane już obecnie programowo, to nie wygląda jak system rozproszony, nie musimy się tam bawić w takie rzeczy, ale de facto to już jest poniekąd bardzo prosty system rozproszony. Więc tak naprawdę jedyną rzeczą, którą tak łatwo nie przeszczepimy, to jest ta autonomia zespołu. To jest troszkę ciężej do wykonania, bo faktycznie wszyscy spotkamy się na jednym artefakcie do wdrożenia, na jednym repozytorium kodu. I stąd właśnie chyba jest jeszcze bardziej widoczna i ważna kwestia tego designu, czyli ten design, czyli to oddzielenie tych naszych funkcjonalności i pogrupowanie logiczne. Silna spójność tego kodu i mały coupling sprawi, że możemy częściowo chociaż tę autonomię zespołów uzyskać, bo wtedy każdy jednak może swoim kawałkiem zająć się w miarę bez przeszkadzania innym zespołom. To oczywiście nigdy nie będzie pewnie aż tak zrobione bez szwów jak to w mikroserwisach, ale jest to jakoś do zrobienia do pewnego momentu. Oczywiście skalowanie będzie znacznie, znacznie słabsze i przykłady czy Ubera czy Netflixa pokazują, że tam tylko podejście mikroserwisowe się sprawdziło. No ale nie oszukujmy się, bo tutaj mówimy o skali setki, a nawet tysięcy mikroserwisów. Więc to nie jest nasza skala.
Tak, to zawsze musi być nasza skala i to, jak wiele firm próbuje tę skalę nawiązywać i próbować sobie robić podobne podejście. No ale też nie oszukujmy się, nie ma aż tak dużo firm, które na takiej skali działają, które działają tak globalnie i na wszystkich rynkach jednocześnie, żeby takie podejście też śmiało miało uzasadnienie. Więc trzeba też o tym pamiętać. No i oczywiście warto też pamiętać o takiej może troszkę socjologicznej regule, ale jest coś takiego jak prawo Conwaya, które mówi nam, że systemy, które organizacja tworzy, poniekąd odwzorowują strukturę tej organizacji. Więc trzeba pamiętać, że jeśli mamy dość sztywną strukturę, jeśli mamy mocno scentralizowaną jednostkę organizacyjną, będzie bardzo ciężko, żeby tam pojawiło się podejście mikroserwisowe, gdyż ono zwyczajnie po prostu nie odda struktury i codziennego działania takiej organizacji. Więc to też jest coś, co warto mieć na uwadze i wtedy jednak trzeba troszkę to rozwiązać na niższym poziomie, może na poziomie lepszego modelowania niż sprowadzania tego wszystkiego do podejścia mikroserwisowego.
Kiedy DDD naprawdę się opłaca
A to, co powiedziałeś przed chwilą, jest ciekawy trop, bo to daje nam taką sugestię zabetonowania pewnych fragmentów i możemy mieć to zabetonowanie na różnych poziomach. Możemy mieć zabetonowanie techniczne, czyli że po prostu „Working Effectively with Legacy Code” i jedziesz, bo bez tego nic się nie da zrobić, czyli totalne spaghetti w kodzie i powodzenia ze sprowadzaniem jakiejkolwiek najprostszej zmiany. Ale może być też zabetonowanie na wyższych poziomach, na przykład na poziomie koncepcyjnym albo na poziomie zarządczym, czy nawet w organizacji. Takie zabetonowanie może skutkować tym, że niestety ta zmiana, którą by chciał biznes, a która pociągnie za sobą betonowanie tej części technicznej, jest niemożliwa, bo część biznesu, bo płacący rachunki jest zabetonowana i nie chce za to zapłacić. Nie? Więc tutaj bardzo mocno trzeba czasami forsować takie zagadnienia i właśnie taka zmiana sposobu myślenia na to, że im bardziej mamy lekko zorganizowany nasz model domenowy, tym mniej kasy wydamy finalnie na wprowadzenie tej czy tamtej zmiany i tak naprawdę odblokujemy sobie na przyszłość możliwości rozwoju domeny praktycznie, nie? Bo do tego się to sprowadza. My mamy, wróćmy do tego przykładu z Legacy systemem. Mamy ten system, który ma nasze 20 lat czy 25 i on już swoje zarobił i dalej zarabia, a jego właściciele chcą, żeby on dalej zarabiał, tylko żeby on dalej zarabiał i nie wyparła go konkurencja, która przecież nie śpi i cały czas robi coś czy coś takiego, bo oni też widzą nasz system.
Błędy i mity wokół Domain-Driven Design
Tak, nasz system przyniósł konkretne rezultaty, jest znany od 25 lat, więc oni chcą zrobić taki sam system, tylko lepszy, nie?
I teraz konkurencja też widzi nasz system i widzi własne konkurencji.
Otóż to. I nie daj Boże, konkurencja jeszcze ma nawet lepsze systemy niż nasz system, więc my musimy zdążyć z tą zmianą. Nie dość, że musimy ją zrobić, to jeszcze musimy zdążyć z nią na czas i nie dać się wyprzeć z rynku. Więc żeby zdążyć z nią na czas i żeby to wszystko nie umarło w butach, to po prostu musimy mieć tutaj – ja bym to określił tak, jak już to zasygnalizowałem – taki lekki model, po prostu model podatny na zmiany, jeżeli mamy model podatny na zmianę i mamy zrozumienie, że ta zmiana musi następować, bo wszystko jest zmianą. Jedyną stałą we wszechświecie jest zmiana. Więc wszystko się zmienia, więc my musimy też się zmieniać, my musimy adaptować się do tych wszystkich zmian. Więc jeżeli w organizacji, która ten system posiada, która go chce rozwijać, mamy zgodę na wprowadzanie tej zmiany, inaczej, mamy w ogóle zrozumienie konieczności wprowadzania tych zmian, to to już jest bardzo dobrze, bo nawet jeżeli mamy Legacy na samym spodzie, to my wcześniej czy później z tego Legacy wyjdziemy tą czy inną metodą. Albo sobie wymienimy ten fragment, który jest najbardziej ciężki na jakiś totalnie nowy, świeżutki greenfield, który za 3 lata znowu będziemy wymieniać – nieważne, już w drodze wymieniliśmy – albo po prostu wejdziemy tam i zaczniemy sobie tak przeorganizowywać ten model techniczny, nasz technologiczny, albo sobie będziemy właśnie popularną zieleninę w kodzie stosować, żeby się uwolnić od tego czy innego ograniczenia, albo sobie po prostu zmienimy technologię leciutko, albo wprowadzimy jakąś nowinkę, która nam coupling zmniejszy. I tutaj musimy poczekać do trzeciego odcinka na tę nazwę, chociaż nie wiem, czy wytrzymam, bo może w drugim się pojawi i zrobimy sobie jakąś fajniejszą komunikację pomiędzy naszymi modułami. W ogóle dzielimy te moduły tak, żeby miały bardzo dobrze określone granice, żeby te granice były przekraczane tylko w tych miejscach, w których my chcemy, czyli naszych przejściach granicznych, żeby tam nie było jakiegoś tranzytu nielegalnego, a już odpukać sięgania do tabelki obok, bo czemu by nie? Mam tę samą bazę, bo jestem w monolicie, to życie szybciej, będzie szybciej. No co? Co ja będę jakieś API robił? Na co to komu? A później jeszcze po testach, co? A właśnie. A jak do testów jeszcze dochodzi? Nie? No to to już w ogóle jak te granice sobie znajdziemy, opiszemy, to się nagle okaże, że można przetestować te nasze bounded contexty, całe nasze domeny można przetestować, w ogóle nasz ficzer daje się testować jednostkowo. O dziwo, siedzi w monolicie, nic, nie musimy całego nawet do tych testów stawiać. Bierzemy sobie kawałeczek, siup i mamy już testy i później robimy testy integracyjne, kilka bounded contextów ze sobą rozmawia, później co, całe moduły ze sobą rozmawiają, później cały monolit ze sobą rozmawia i ze światem. Jak się okazuje, że to się jednak da zrobić, nie? Tylko na początku musimy zacząć myśleć.
Podsumowanie i dalsze plany
Czyli chcesz powiedzieć, że monolit nie jest taki zły?
Tak, chcę powiedzieć, że monolit nie jest taki zły i że w dodatku to my jesteśmy cwaniaki. My się nie boimy Legacy monolitu nawet, bo Legacy monolit, oczywiście jeżeli będzie traktowany bez odpowiedniego uczucia, to umrze, sorry, ale jak podejdziemy do niego jak do człowieka, no to on odda z nawiązką.
Dokładnie. I tym pozytywnym akcentem chyba koniec.
Jak zakończyć pierwszą część? Na pewno jeszcze będziemy do tego wracać, bo to jest temat rzeka i po prostu wątków, jakie on produkuje, jest niezliczona ilość, więc na pewno jeszcze poopowiadamy o granicach, o kontekstach, o monolitach, o serwisach, o ich komunikacji, o zmianach.
Jak wprowadzać zmiany, w jaki sposób, jak ją wydawać.
To może też o zmianach w bardziej szerokim kontekście, jak taką zmianę próbować wdrażać w organizacji o szerszym aspekcie, nie tylko techniczną zmianę.
Czasami też podstawa w ogóle jakiegokolwiek pójścia do przodu. Więc to też jest ważny aspekt rozumienia konieczności zmian na poziomie technicznym, na poziomie zespołu, ale też na poziomie wyższego managementu, jakiegoś średniego szczebla. Więc to wszystko jest, wszystko się ze sobą łączy.
Jak to w…
Dokładnie.
I w mikro, i w mikroserwisach.
Ale to już przez API.
Dokładnie, albo przez…
Tylko nie powiem przez…
No to co? To na dzisiaj chyba byłoby tyle.
Dzięki.
Chyba tak. Dzięki Michał.
Do następnego razu.
Do następnego.
Cześć!