Najpro艣ciej rzecz ujmuj膮c - Core Code - jest to kod niezale偶ny od infrastruktury i kontekstu wywo艂ania. Wzorce s艂u偶膮ce do jego implementacji to: Command, Serwis, Repozytorium, Fabryka, Read Model, Write Model (Encja) czy Value Object. Z drugiej strony mamy tytu艂ow膮 Infrastruktur臋 do kt贸rej nale偶膮 np. implementacje interfejs贸w repozytori贸w czy kontrolery HTTP/CLI. Stosuj膮c podzia艂 na Core Code i Infrastruktur臋 realizujemy wa偶ny cel: odseparowanie kodu realizuj膮cego funkcjonalno艣膰 od szczeg贸艂贸w technicznych. Istotnym elementem w poznaniu ka偶dego z tych wzorc贸w jest zrozumienie w jaki spos贸b dzia艂aj膮 ze sob膮 nawzajem, oraz na jakim etapie cyklu 偶ycia aplikacji wyst臋puj膮. W tym wpisie nie skupie si臋 na wspomnianych wzorcach, ale na istocie tytu艂owego podzia艂u na Core Code i Infrstruktur臋 - czyli dlaczego jest on istotny i jakie korzy艣ci przyniesie.
Odseparowanie od Infrastruktury. Why even bother...?
Odseparowanie od infrastruktury mo偶emy zrealizowa膰 poprzez stosowania wy偶ej wymienionych wzorc贸w. Jakby si臋 na tym zastanowi膰 to pilnuj膮c by kod dzieli艂 si臋 na Core Code i Infrastruktur臋, realizujemy g艂贸wne za艂o偶enia OOP - wprowadzanie warstw abstrakcji. Bior膮c za przyk艂膮d Serwis Aplikacyjny - czytaj膮c jego kod, nie musimy zaprz膮ta膰 sobie g艂owy szczeg贸艂ami technicznymi zapisu danych do bazu poniewa偶 Serwis posiada zale偶no艣膰 w postaci Interfejs Repozytorium, kt贸ra skutecznie ukrywa z艂o偶ono艣膰 tego zagadnienia. Je偶eli b臋dziemy potrzebowali tej wiedzy, po prostu wyszukamy Implementacje Repozytorium ukrywaj膮c膮 techniczne aspekty zapisy. Dzi臋ki temu nie jeste艣my zbyt wcze艣nie obci膮偶eni wi臋dz膮, kt贸rej na danym etapie w og贸le nie potrzebujemy.
Cz臋sto wymienian膮 zalet膮 odseparowania Core Code od Infrastruktury jest wymienialno艣膰 szczeg贸艂贸w implementacyjnych jak np. baza danych. Prawde m贸wi膮c wymiana bazy na inn膮 jest do艣膰 rzadko wyst臋puj膮ca czynno艣膰 w czasie 偶ycia projektu, ale je偶eli byliby艣my do niej zmuszeni np. z przyczyn wydajno艣ciowych to przy wydzielonej Warstwie Infrastruktury jeste艣my do tego zdolni por贸wnywalnie mniejszym nak艂adem pracy. Poj臋cie szczeg贸艂u implementacyjnego nie ogranicza si臋 jedynie do bazy danych, ale jesto to o wiele szersze spektrum, gdzie do Infrastruktury zaliczamy ca艂e frameworki, biblioteki, po艂膮czenia z zewn臋trznymu systemami. Od wszystkich tych zale偶no艣ci mo偶emy si臋 odgrodzi膰 warstw膮 abstrakcji co w nieznanej przysz艂o艣ci mo偶e si臋 okaza膰 nieocenion膮 zalet膮. Jak to powiedzia艂 Michael Feathers:
"Avoid littering direct calls to library classes in your code. You might think that you’ll never change them, but that can become a self-fulfilling prophecy"
Mo偶na wywnioskowa膰, 偶e to co robimy to izolowanie si臋 od technologii s艂u偶膮cej do realizowania funkcjonalno艣ci, kt贸ra nie definiuje funkcjonalno艣ci samej w sobie. Przez to, 偶e mamy fizycznie rozdzielone miejsca obs艂ugi zapisu do bazy danych konkretnej Encji i definicji samej Encji - utrzymanie projektu staje si臋 prostrze. Na przyk艂ad chc膮c podnie艣膰 wersje biblioteki obs艂uguj膮cej po艂膮czenie z baz膮 danych b臋dziemy operowali jedynie na Warstwie Infrastruktury nie ruszaj膮c przy tym kwestii biznesowych, w wyniku czego ryzyko nieumy艣lnego wprowadzenia zmiany funkcjonalno艣ci biznesowej znacz膮co maleje.
Fizyczne rozdzielenie - czyli tworzenie oddzielnych klas domeny problemu oraz infrastrukturowych w osobnych Warstwach. Warstwy wed艂ug standardowego modelu dziel膮 si臋 na Aplikacj臋, Domen臋 oraz Infrastruktur臋 - realizowane s膮 przez namespace'y. Jest jasno okre艣lone, jak膮 wiedz臋 mog膮 posiada膰 klasy w danej warstwie o bytach (klasy, interfejsy, enum) z innej warstwy. Jako, 偶e PHP natywnie nie ma zaimplementowanego mechanizumu enkapsulacji przestrzeni nazw, nic nie stoi na przeszkodzie by zaimplementowa膰 z艂y kierunek komunikacji np. Wastwa Aplikacji posiada odwo艂ania do klas z Warstwy Infrastruktury. Jedynie dyscyplina developer贸w w przestrzeganiu zasad mo偶e pilnowa膰 tej poprawno艣ci (by膰 mo偶e przy pomocy analizy statycznej).
Z wyizolowan膮 Warstw膮 Infrastruktury sprawiamy, 偶e mo偶emy stosowa膰 TDD bo klasy z Core Code s膮 艂atwe w testowaniu jednostkowym. Dodatkowy nak艂ad pracy mo偶e prowadzi膰 do powstania modelu domenowego wedle DDD. Stosowanie tych technik niew膮tpliwie przyczyni si臋 do jako艣ci wytwarzanego oprogramowania. Dodatkowo, tworzenie klas z my艣l膮 o odseparowanej infrastrukturze, naturalnie prowadzi do implementacji popularnego wzorca architektonicznego Porty i Adaptery.
Wewn臋trzna jako艣膰 oprogramowania
Przez Jako艣膰 Wewn臋trzn膮 rozumie si臋 szerokopoj臋t膮 czytelno艣膰 kodu, 艂atwo艣膰 w utrzymaniu i rozwijaniu aplikacji. Wydaje si臋, 偶e na jako艣ci kodu zale偶y g艂贸wnie programistom, gdy偶 dla ludzi biznesu jej istotno艣膰 na pierwszy rzut oka nie jest taka oczywista. Jako 偶e oprogramowanie tworzone jest w spos贸b iteracyjny, pisane klasy musz膮 realizowa膰 sp贸jne funkcjonalno艣ci, tworzy膰 lu藕no powi膮zane wi臋ksze struktury i by膰 pokryte nale偶yt膮 ilo艣ci膮 test贸w jednostkowych. Nigdy nie wiadomo jakie zmiany najdejd膮 w kolejnych iteracjach, wi臋c musimy stara膰 si臋 tworzy膰 solidne elementy budulcowe (klasy/grupy klas/modu艂y) w ca艂ym projekcie. Utrzymuj膮c 艣cis艂膮 dyscypline przy tworzeniu wysokiej jako艣ci oprogramowania sprawiamy, 偶e b臋dziemy mogli modyfikowa膰 zachowanie oprogramowania w spos贸b przewidywalny i bezpieczny, minimalizuj膮c ryzyko, 偶e zmiana b臋dzie wymaga艂a du偶ej przer贸bki.
Oprogramowanie jest oczywi艣cie tworzone do realizowania cel贸w biznesowych, ale musi ono te偶 s艂u偶y膰 developerom. Mogliby艣my napisa膰 kiepski kod spe艂niaj膮cy w 100% wymagania klienta (o wysokiej jako艣ci zewn臋trznej), ale wprowadzanie zmian w oprogramowaniu niskiej jako艣ci jest skomplikowane, nieprzewidywalne i ryzykowne - z czasem wymagaj膮ce coraz wi臋kszej uwagi developera i nak艂adu czasu.
Podsumowuj膮c:
- im 艂atwiej i pewniej wprowadza膰 zmiany w oprogramowaniu tym lepiej
- by 艂atwiej wprowadza膰 zmiany w oprogramowaniu trzeba pisa膰 kod o wysokiej jako艣ci wewn臋trznej
- istnieje szereg technik do osi膮gni臋cia wysokiej jako艣ci kodu
Jak wida膰 tematy te s膮 pochodn膮 wydzielania Core Code i wzajemnie si臋 zaz臋biaj膮. Stosuj膮c wzorce Rdzenia Aplikacji b臋dziemy mogli 艂atwo przetestowa膰 jednostkowo tworzone obiekty, co dowodzi 偶e kod jest modu艂owy oraz niezale偶ny od kontekstu co jest r贸wnoznaczne z wysok膮 jako艣ci膮.
Wzorce Projektowe
Wymienione na samym pocz膮tku wzorce, pomagaj膮 w pisaniu kodu odseparowanego od infrastruktury. Opracowane by艂y na podstawie sumy do艣wiadcze艅 innych programist贸w w budowaniu aplikacji webowych. S膮 one dla programisty zestawem jasno zdefiniowanych i sprawdzonych element贸w budulcowych. Stosowanie wzorc贸w sprawia, 偶e kod jest czytelny, modu艂owy i 艂atwy w testowaniu. Developer znaj膮cy ca艂膮 palet臋 wzorc贸w mo偶e korzysta膰 z niej jak przybornika z narz臋dziami - dobieraj膮c narz臋dzie najlepiej dopasowane do probelmu. Nie trzeba wtedy wymy艣la膰 ko艂a na nowo i zastanawia膰 si臋 nad tym czy zastosowane rozwi膮zanie jest dobre. Maj膮c sprawdzony zestaw wzorc贸w oraz posiadaj膮c praktyczn膮 wiedz臋 ich stosowania jeste艣my w stanie modyfikowa膰 oprogramowanie szybciej i pewniej.
W r臋kach developera jest to czy poszerza on swoj膮 wiedz臋 w dziedzinie wytwarzania oprogramowania wysokiej jako艣ci. Zg艂臋bianie informacji na temat wzorc贸w projektowych sprawia 偶e, zaczynamy widzie膰 wi臋cej. Implementuj膮c kod mo偶emy wybiec w przyszo艣膰, przewiduj膮c jakie b臋dzie ni贸s艂 ze sob膮 konsekwencje, przed jakimi potencjalnymi problemami nas chroni, w jaki spos贸b sprawia 偶e jest wysokiej jako艣ci. Korzystaj膮c z danego wzorca dziesi膮tki b膮d藕 setki razy, pos艂ugujemy si臋 nim coraz lepiej, widzimy jakie warianty si臋 najlepiej sprawdzaj膮, a w jakich sytuacjach lepiej go nie stosowa膰.
Mo偶na powiedzie膰, 偶e przybornik z narz臋dziami developera uzupe艂niany jest o nowe elementy gdy poszerza on swoj膮 wiedz臋 - teoretyczn膮 i praktyczn膮. Warto szlifowa膰 swoje umiej臋tno艣ci pos艂ugiwania si臋 tymi narz臋dziami gdy偶 bezpo艣rednio przek艂adaj膮 si臋 na umiej臋tno艣ci tworzenia kodu wysokiej jako艣ci, czyni膮c nasza prac臋 prostsz膮.
Na sam koniec wrzucam ciekawy cytat Matthias'a Noback'a daj膮cy wiele do my艣lenia:
殴r贸d艂a
Wpis jak i ca艂a koncepcja zosta艂a zaczerpni臋ta przede wszystkim z przemy艣le艅 Matthias'a Noback'a (blog) zawartych w jego dw贸ch ksi膮偶kach:
馃摃 Advanced Web Application Architecture (2020)
馃摃 Object Design Style Guide (2019)
Wzmianka o Wewn臋trznej jako艣ci oprogramowania zosta艂a zaczerpni臋ta z ksi膮偶ki:
馃摃 Growing Object-Oriented Software, Guided by Tests (2009)