Wzorce i dobre praktyki

 Wzorce i dobre praktyki




Poznając domenę zagadnienia widzimy obszary które dają potencjał rozwoju i takie, gdzie funkcjonalność może zostać potraktowana dość marginalnie. Widząc sklep, lub producenta widzimy rozmaite obszary. Producent może rozwinąć sklep, a sklep może zechcieć część produktów wydelegować do własnego działu wytwórczego. Procesy jednak zasadnicze odbywają się w określonym kontekście. 


Wzorce projektowe i praktyki, czy style architektoniczne przystają do siebie dość luźno i częściowo rozwiązują podobne problemy. Nagromadzenie ich powoduje problemy w częściach nie przylegających zbyt łatwo. Przykładem może być architektura warstwowa i modularny monolit. Olbrzymia część prostych systemów próbuje czerpać z DDD i w efekcie powstają sromotne konstrukty korporacyjne spoglądające na developera z wyższością, obwarowane zasadami i ustaleniami, pajplajnami i procesami.


Moim głównym celem jest dobranie odpowiednich rozwiązań do problemu i skali, definiowanie rodzaju aplikacji, jej typu, przeznaczenia i funkcjonalności w celu zakreślenia granic odpowiedzialności poszczególnych modułów, oraz wyznaczenie kontraktu między tymi modułami w taki sposób by tworzyły szkatułkową kompozycję połączonych ze sobą elementów za pomocą portów i adapterów.


W jednym przypadku konieczne będzie użycie “heksagonalnej” koncepcji do separacji bazy danych, innym zaś razem znacznie lepszy rezultat przyniesie wydelegowanie warstwy web. Próba wyodrębnienia modułów technologicznych najczęściej spotykanych w korporacyjnej wizji architektury i podzielenie jednej funkcjonalności na kilka osobnych bytów rozmywa proces utrudniając jego testowanie i wdrażanie, wydłuża pracę zespołu i prowadzi do powstania “czystego” i dziewiczego kodu nietkniętego pragmatyzmem, który dopiero aktualizuje się w zetknięciu z technologią. W teorii.


Każdy kto przechodził proces zmiany architektury SOAP na REST, albo gRPC, komunikację asynchroniczną za pomocą narzędzi takich jak Kafka czy z wykorzystaniem 2PC za pomocą JMS, czy zmieniał bazę danych relacyjną na nie-relacyjną widział jakie trzęsienie ziemi powoduje to w całym sposobie myślenia o systemie i nawet jeśli domena to wytrzymuje wymaga to ogromnej pracy po stronie adapterów. Ostatecznie nie jest istotne nad czym pracujemy ale jak długo i jak przekłada się to na koszt.


Biorąc pod uwagę koszt całkowity wprowadzenia warstwowego podziału i delegowania całej infrastruktury do modułów i licząc w tym komplikacje pojawiające się przy próbie zastosowania podziału funkcjonalnego na moduły odzwierciedlające maksymalną właściwą granularyzację do poszczególnych agregatów wydzielonych również portami i adapterami dochodzimy do takiego stopnia skomplikowania który rozkłada wydajność każdego zespołu. Zwiększa koszt pracy i przeróbki stają się równie ciężkie jak w typowej kupie błota.


Tym sposobem zataczamy koło kiedy przypadkowa złożoność i wybory wynikające z dobrych praktyk stają się morderstwem dla dobrze zapowiadającego się biznesu.


Rozważając za każdym razem dylematy takie jak bogaty vs anemiczny model staram się kierować przełożeniem na czas wykonania zadania, skalę problemu i środki. Wydaje się że znacznie taniej jest czasem napisać aplikację od nowa niż utrzymywać ją jeśli znajduje się w stanie wysokiej standaryzacji i przypadkowej złożoności. Zastanawiam się ile zajęłoby mi to gdybym pisał nagimi strukturami danych i logikę zostawił w serwisie, co by się stało gdybym stan z bazy danych zwrócił do klienta i zyskał od niego te zmiany stanu o które chodzi klientowi. Czy redukcja zapytań i zdarzeń wysyłanych do bazy danych będzie kompensowana przez problemy wynikające z niespójnością stanu współdzielonego z innymi aktorami. Czy aktor dla którego projektowana jest funkcjonalność powinien mieć dedykowaną dla siebie strukturę, czy wystarczy struktura znajdująca się w bazie danych. Oczywiście wyśmiane rozwiązania jak wszystko posiadają zalety i idea REPRESENTATIONAL STATE TRANSFER przeciwstawiona jest idei transmisji zdarzeń. Pytanie jakie zawsze należy sobie zadawać to pytanie o to czy składowanie snapshotów stanu z numerem wersji nie jest bardziej wartościowa od składania zdarzeń i rekonstrukcja stanu. Przypomina ona archiwa kserokopii dokumentów kserowanych, podpisywanych i zatwierdzanych w organizacjach od dziesięcioleci, które mają swoje życie i przełożenie na to czego biznes w danym momencie może potrzebować. Oprogramowanie odzwierciedlać ma strukturę przedsiębiorstwa.


Pisząc to wiem że wcielam się w rolę adwokata diabła, piszę naopak, argumentuje rzeczy od których każdy próbuje odciągać programistów, ale z drugiej strony może to co robią jest zwyczajnie naturalne, proste i tanie w opozycji do wyrafinowanej złożonej maszynerii pochłaniającej niezliczone środki na wytworzenie i utrzymanie.


Każdy element wchodzący w skład architektury musi wynikać z analizy wymagań funkcjonalnych, niefunkcjonalnych i kosztów. Nie istnieje jedna słuszna droga, jeden wzorzec i jedno rozwiązanie. Sztuka architektury oprogramowania to twórcze połączenie i wypadkowa prowadząca do sukcesu optymalną drogą. Nie najkrótszą, ale na pewno nie najdłuższą wynikającą z próby zaaplikowania każdej mądrej idei jaka pojawiła się w świecie filozofii organizacji kodu. Kod to ikebana. Nie jest łatwo o idealną proporcję a wrzucenie wszystkiego do wiadra i zagryzienie miętowym opłatkiem kończy się jak w słynnym skeczu Monty Pythona z filmu “Sens Życia”.





Comments