
WM Talks: Biznesowe podejście do długu technologicznego
Poruszone tematy:
Jakie są przyczyny powstawania długu technologicznego w projektach, jakie są jego aspekty techniczne i czy może być on korzystny?
O tym, w kolejnym odcinku podcastu naszej serii WM Talks rozmawiali: Paweł Kaźmierczak - Project Manager, Damian Maślanka - CTO oraz Szymon Kania - CEO.
Paweł: Cześć, z tej strony Paweł Kaźmierczak. Dzisiaj mam dla was przyjemność poprowadzić kolejny odcinek serii podcastów WM Talks. Moimi gośćmi są Damian Maślanka i Szymon Kania. Dzisiaj będziemy mieli okazję porozmawiać sobie trochę na temat długu technologicznego. Co to w ogóle jest i jak wpływa na prowadzenie biznesu w branży IT. Może najpierw nakreśmy słuchaczom, co to takiego jest, ten dług technologiczny, bo wiem z doświadczenia, że to nie jest taka oczywista kwestia dla wszystkich. Jak najprościej wytłumaczyć to pojęcie, tak żeby każdy to zrozumiał.
Damian: Jak sama nazwa wskazuje dług, w przypadku np. długu finansowego to mamy pewne zobowiązanie, czyli coś co zostało wcześniej zaciągnięte na poczet przyszłości i jeżeli chodzi o dług technologiczny to to jest podobna analogia, czyli w pewnym momencie tak jakby zaciągnęliśmy pewne zobowiązanie budując projekt z myślą o tym, żeby w przyszłości kiedyś to wyprowadzić. Wiąże się to z tym, że w pewnym etapie projektowym doszło do pewnych uproszczeń, do zaniechania pewnych procedur, tylko po to, żeby właśnie przykładowo dany projekt pociągnąć szybciej do przodu, czy też żeby zaoszczędzić zasoby na poczet jakichś innych funkcjonalności. No i ze zbiegiem tym dług albo jest spłacany, albo jest cały czas zaciągany, co w efekcie prowadzi do tego, że jak w realnym życiu zobowiązania finansowe też mogą przerastać co niektóre jednostki. Podobnie dzieje się z technologiami. W pewnym momencie też zbyt bardzo zacągnięty dług technologiczny może doprowadzić do tego, że sam projekt przestanie być stabilny i spełniać swoją funkcję.
Paweł: Czyli jakby przekładając to jeszcze na kwestie takie finansowe, jakie mamy tutaj podobieństwa właśnie do zaciągania tego długu finansowego, musimy sobie wziąć pod uwagę, że każda funkcjonalność to jest jakiś koszt czasu pracy dewelopera i powiedzmy nieoptymalnie napisany kod potem generuje takie koszty na przyszłość, że deweloper musi siedzieć, coś refaktorować i tak dalej, dopracowywać jakieś funkcje i to wszystko niesie ze sobą dodatkowe koszty finansowe.
Damian: Tak, wcześniej trochę można powiedzieć uprościłem to, bo porównałem dług do potrzeb czegoś rozwojowego, a to nie zawsze tak jest. Często, nawet może i można powiedzieć, że częściej wynika to z tego, że kompetencje zespołowe tak jakby sprawiają, że ten dług samoistnie powstaje nawet nieświadomie. Można to porównać do takiej sytuacji, że ktoś ma dom i po prostu lekceważy bieżące remonty. Tak naprawdę ten dom funkcjonuje na takim minimum. Jak wiemy, po 20-30 latach taki zaniedbany, nieremontowany dom zaczyna dawać o sobie znać, podobnie jest właśnie z projektami, gdy zaniedbamy bieżący refaktor, bieżące optymalizowanie kodu, pójście z nowinkami, aktualizowanie poszczególnych bibliotek, możemy doprowadzić do tego, że taki projekt po kilku latach właśnie jest na takim etapie starego domu, który po prostu został zaniedbany.
Paweł: Ok, czyli tutaj reasumując, jeśli nie dbamy o projekt na bieżąco i powiedzmy tak jak z remontami, nie odświeżamy czegoś, czegoś nie aktualizujemy w kodzie, to później stajemy przed obliczem tego, że trzeba coś zrobić tak naprawdę jeszcze raz, ale od nowa. Czyli powiedzmy tutaj trochę brnę do tego, że stajemy w obliczu, pytanie czy dalej nam się opłaca rozwijać stary kod, Czy pójdzie już na przykład w napisanie nowej aplikacji?
Damian: Tutaj znowu tak nawiązując właśnie do analogii domów, też różnie z tym bywa i tak samo można powiedzieć pod kątem technicznym. Czasem warto, da się jeszcze uratować dany budynek, pomimo że wiąże się to z dużymi kosztami, no ale jest sens tego uratowania, podobnie z projektami, że czasem jeszcze ten dług technologiczny, pomimo że jest ogromny, no to jest potencjał, jest możliwość tak jakby dopracowania tego kodu, wyprowadzenia tego na proste tory, no a czasem i to jest dosyć częste w technologiach, bo znowu nawiązując do realnego świata, to można powiedzieć, że takie zaniedbanie domu to jest proces długofalowy. W przypadku technologii tutaj bardzo szybko się wszystko zmienia dookoła, bardzo szybko powstają nowe biblioteki, nowe metodologie programowania, powstają nowe języki, nowsze wersje, więc tutaj tak naprawdę kilka lat zaniedbań można śmiało powiedzieć, że to jest tak jakby kilkadziesiąt lat zaniedbania właśnie remontowania domu, więc jest to inna skala i przeważnie kończy się tym, że po prostu trzeba tak jakby zburzyć ten budynek i zbudować projekt na nowo.
Szymon: Można to trochę porównać też w tym świecie finansowym do nakręcającej się spirali długu, tutaj jest podobnie. Jeżeli tych zaniedbań będzie dużo w różnych elementach systemu, to też jakby ten dług będzie i postępował szybciej i może wywołać też sytuację, tak jak tutaj Damian mówi, sytuację, w której trzeba zburzyć dom, zburzyć cały system i zbudować go na nowo, ale to też nie da się jednoznacznie odpowiedzieć, wszystko jakby to zależy. Zależy od sytuacji i wymaga po prostu rzetelnej analizy danego tematu, analizy konkretnego długu i w tym momencie podjęcia decyzji biznesowej, co jest bardziej opłacalne, wyprowadzenie tego długu technologicznego, podjęcie się właśnie refaktoryzacji kodu, czy mimo wszystko tak naprawdę i szybsze, i tańsze, i bardziej przyszłościowe okaże się napisanie systemu na nowo. Na przykład w sytuacji, gdy jest oparte o bardzo stare technologie i nawet aktualizacja frameworka, czy bibliotek no jakby już jest niemożliwa i czasami po prostu jakby przez środowisko, w którym dany system działa, dany system jest zrealizowany, wymusza inne podejście do rozwiązania problemu długu technologicznego.
Paweł: Okej, to teraz bym chciał, żebyśmy sobie porozmawiali na temat właśnie tych przyczyn. Jakie mamy przyczyny długu technologicznego? Co bezpośrednio albo pośrednio wpływa na to, że ten dług się tworzy w kodzie?
Damian: Z mojego doświadczenia to przeważnie to jest upraszczanie. Często jest tak, że programiści pracują nad danym projektem, no i żeby sobie tak jakby przyspieszyć pracę, no to zaniechają tak jakby pewnych procedur. Nie dbają o to, żeby napisać daną funkcję, można powiedzieć, zgodnie ze standardami, tylko to też nie do końca jest ich wina, bo to może wynikać bezpośrednio od klienta, który daje mocny nacisk czasowy, że zależy mu na szybkim rozwoju, a jednocześnie nie ma określonego budżetu, który sprawiłby, że ten zespół projektowy byłby większy. No i taki programista staje w obliczu, że musi pewne rzeczy tak jakby uprościć, czyli nie zrobić tego zgodnie ze sztuką. No i to jest taka pojedyncza cegiełka, która jedna na drugą się nakłada, aż w końcu budujemy sobie takiego potworka, który daleko odbiega od tego, jak powinien wyglądać z technologicznego punktu widzenia. Więc to jest jedno, a drugie to często można trafić po prostu na niewłaściwe osoby w projekcie, czy nawet niewłaściwe firmy, które też z racji cięcia kosztów, czy też tak jakby przeliczenia się ze swoimi kompetencjami, nie tworzą jakościowego kodu. Myślą, że tak naprawdę ten kod jest okej, ale nie jest okej i z upływem czasu, gdy tego kodu robi się coraz więcej, tak zwany spaghetti code, powstaje taki potworek, nad którym ciężko teraz zapanować i dopóki w zespole nie pojawią się doświadczone osoby lub poważna firma, która się weźmie za to, to tak naprawdę nie ma tej świadomości, że jakikolwiek tutaj dług technologiczny istnieje. Wiadomo, to jest w różny sposób sygnałowane, że strasznie długo zajmuje tworzenie poszczególnych modułów, czy też wydajność aplikacji drastycznie spada. Jednakże to są takie ślady, można powiedzieć, pośrednie, które są widoczne, ale nie do końca utożsamiane z długiem technologicznym i dopiero spojrzenie trzeciej osoby daje taki werdykt, że o to tutaj właśnie chodzi.
Szymon: Warto do tego dodać jeszcze, że czasami ten dług technologiczny zaciąga się celowo i to też nie zawsze jest jakby złe, bo czasami trzeba przyspieszyć bardzo pracę. Prace nad projektem są tak dynamiczne, jest tak ograniczony czas z uwagi na aspekty biznesowe, że część długu technologicznego jest zaciągana w pełni świadomie, żeby go wyprowadzić, żeby spłacić ten dług technologiczny np. po starcie jakiegoś etapu projektu, kiedy przechodzimy do momentu, gdzie projekt już działa na rynku, zdobywa klientów i w tym momencie powiedzmy przechodzimy do jakiejś spokojniejszej fazy, czy rozwoju, czy właśnie momentu, gdzie może być ten dług technologiczny spłacony, to znowu można porównać do rynku finansowego. Też jakby zaciąganie długu czy kredytów nie zawsze jest złe. Zaciąganie kredytów konsumpcyjnych może być złe, ale w danym momencie zaciągnięcie jakiegoś kredytu inwestycyjnego, gdzie świadome zaciąganie długu technologicznego można porównać do takiego kredytu inwestycyjnego, może być też dobrym krokiem, dobrym podejściem biznesowym. Dużo zależy od konkretnego przypadku i od konkretnej sytuacji.

Damian: Nawiązując do tych rynków finansowych, jest podobna analogia w technologiach. Trzeba świadomie podchodzić do zaciągania długów i przede wszystkim mieć plan na jego spłacanie w projektach, jeżeli nie ma tego planu, tylko cały czas zaciągamy z myślą, że kiedyś posprzątamy i zrefaktoryzujemy ten kod, a to się nigdy nie wydarza, to tak naprawdę wpadamy w taką spiralę, że ten dług coraz bardziej rośnie. Podobnie jak jest spiralą zadłużenia w kwestiach finansowych, też można wpaść w taką spiralę i po prostu zderzyć się ze ścianą, która już nie ma powrotu.
Paweł: Czyli spłacać tam jedną pożyczkę, drugą i tak dalej i się tak zapędzić?
Szymon: Myślę, że można to tak porównać, że to jest czasami kwestia łatania dziury, powodując kolejną dziurę, naklejając kolejny plaster na odpadający plaster. To się nigdy dobrze nie kończy. Finalnie sprowadza się to, że w pewnym momencie będzie trzeba się zderzyć z tą decyzją stworzenia tego systemu całkowicie na nowo. No i tego typu przypadki też przerabialiśmy. Wiecie, smutno jest czasami powiedzieć klientowi, to jest wręcz przykre, jeżeli ktoś do ciebie przychodzi, analizujemy jakiś temat i okazuje się, że klient poświęcił masę czasu i pieniędzy na inwestycje w jakiś system i okazuje się, że jednak ten system ma tak duży ten dług technologiczny, jest tak dużo narastających, warstwiących się problemów, że jednak jedyny możliwy, jedyny rozsądny kierunek jest wyrzucenie tego wszystkiego do kosza i napisanie od nowa. Też mieliśmy tego typu przypadki. Tak jak mówię, to jest zawsze ciężka rozmowa i ciężka decyzja do podjęcia co zrobić, ale skala problemów wynikających z tych zaniedbań i narastającego długu technologicznego potrafi być bardzo duża. Jeśli klient zamiast na własnym biznesie czy jego rozwoju skupia się na przykład na obsłudze setek zgłoszeń z problemami od użytkowników swojego systemu lub z podejmowaniem błędnych decyzji, bo system z uwagi na problemy jakby zaczyna działać niestabilnie, zaczyna działać źle, to jest kwestia później decyzji biznesowych, co tak naprawdę zrobić i jak do tego podejść.
Paweł: Tak, dokładnie. Czyli tutaj podsumowując to, co sobie tutaj wymieniliśmy, na pewno trzeba zwracać uwagę na to, żeby dbać o tą jakość kodu, stale go optymalizować.
Damian: Można powiedzieć support tego kodu.
Paweł: Tak, żeby nie zaprzepaścić tego, co wytworzyliśmy, czyli tak pod kątem technicznym stale coś tam uporządkowywać. Tak jak przy remontach domu, też trzeba zwrócić uwagę prawdopodobnie na sam plan, zanim zaczniemy pisać projekt, na kompetencje zespołu, który chcemy tutaj wdrożyć, bo to tutaj fajnie Damian powiedziałeś, że często jest tak, że np. jeśli ktoś nie posiada odpowiednich kompetencji, to może coś napisać właśnie nieoptymalnie i ten dług się nawarstwia. No i tak samo można sobie taki dług, tutaj co wybrzmiało, zaplanować w czasie, czyli jeśli badamy dopiero nasz produkt, czy to się opłaci na rynku, możemy wypuścić MVP, czyli taką minimalną wartość dla klientów, ale przy tym chyba należałoby gdzieś tam sobie zaznaczać takie przynajmniej w dokumentacji, tak ja myślę, punkty, które będą wymagały późniejszej refaktoryzacji.
Szymon: Nie zawsze to jest powiązane tylko z MVP, ale po prostu z szybkim rozwojem. Czasami nawet dostarczenie funkcjonalności, która nie będzie jakimś POC czy MVP, tylko pełnoprawną funkcjonalnością, pełnoprawnym modułem czy projektem wymaga po prostu znacznie przyspieszenia prac. Są pewne rzeczy, które odkłada się na bok, tylko tak jak Damian chyba wcześniej o tym wspominał, jeżeli jest na to plan, robi się to świadomie, jest to poukładany proces, nie stanowi to zagrożenia. Jeżeli robimy to chaotycznie, nie myślimy o tym, nie panujemy nad tym, nie mamy planu, no to robi się to potencjalnie bardzo dużym zagrożeniem, które nawet jeżeli nie wyjdzie od razu, bo to nie jest tak, że można powiedzieć trupy z szafy wysypują się w miesiąc po starcie projektu, choć bywa i tak. Zazwyczaj problem długu technologicznego jest po prostu coś narastającego i odzywa się po pół roku, roku, latach. Wszystko jakby w zależności od danej sytuacji, danego konkretnego projektu.
Damian: Dług technologiczny trzeba traktować jako proces, a nie, że to jest rzecz, która się po prostu nagle wydarza. To jest po prostu nieustanny, długotrwały proces, który narasta z czasem.
Paweł: Ok, to ja bym przeszedł dalej do np. jakichś technicznych decyzji, które mogłyby wpływać na ten właśnie pojawiający się dług technologiczny w projektach. Czy możemy wskazać jakieś takie typowe techniczne praktyki, które przyczyniają się do narastania tego długu? No i np. jakie są takie symptomy tego długu w kodzie i infrastrukturze?
Damian: Tak, przede wszystkim to niewłaściwy dobór technologii. To już na wstępie można tak naprawdę zacząć projekt z długiem technologicznym. Jeśli źle podejdziemy do tego procesu i na przykład obstawimy framework, bibliotekę, która nie jest od dłuższego czasu rozwijana lub też została totalnie porzucona, lub ma sporo jakiś bugów, jakiś luk bezpieczeństwa, już tutaj na wstępie sobie tak jakby wrzucamy tego konia trojańskiego, który z czasem zamieni się w dług technologiczny. Drugi czynnik, taki najczęściej występujący, to jest po prostu niedbałość o to, żeby na bieżąco aktualizować te biblioteki, frameworki, które wybraliśmy jako tak jakby budulce tego naszego projektu. Nie zawsze się o to dba, pojawiają się nowsze wersje, a tak naprawdę nie dbamy o to, żeby je podnieść. No i w pewnym momencie się okazuje, że nawet jak podjęliśmy dobrą decyzję, wybraliśmy właściwe biblioteki, najnowocześniejsze w czasie kiedy zaczęliśmy realizację projektu, to po dwóch latach dalej zatrzymaliśmy się na tej samej wersji tej biblioteki, która już dawno została przedawniona, nie jest dalej wspierana, ma jakieś tam wykryte luki bezpieczeństwa, no i po prostu to tak zostaje w tym projekcie. I tutaj ważne jest to, żeby też na bieżąco doglądać, orientować się, sprawdzać, czy pojawiły się nowsze wersje i po prostu aktualizować. Trzeci czynnik, który często się też pojawia, no to niedbałość o dokumentację. Wbrew pozorom, dług technologiczny nie dotyka tylko kodu źródłowego, tutaj dokumentacja też jest bardzo ważna. Dodajemy jakieś nowe funkcje w projekcie, dodajemy jakąś nową technologię, w żaden sposób tego nie spisujemy, bo po prostu dany programista wie w danej chwili jak się do tego odnieść, ale mija jakiś czas, przychodzi inna osoba lub nawet ta sama osoba wraca do projektu i nagle się okazuje, że nie spisała sobie kiedyś tego, nie udokumentowano i nagle ten dług dokumentacyjny też daje o sobie znać. Więc tutaj, jeżeli chodzi o takie techniczne aspekty, to przede wszystkim dbałoś o takie bieżące aktualizowanie i dobieranie tego, na czym opieramy nasz projekt. A druga kwestia, to jest kwestia już stricte jakościowa, czyli właśnie to, co wcześniej wspominałem, odpowiednie kompetencje programisty, który ma odpowiedni skill i wie, jak do tego podejść odpowiednio. Tworzy wartościowy kod zgodny z zasadami. Te zasady są też na bieżąco pilnowane. Code review, pair programming pomiędzy programistami, takie wzajemne dawanie sobie feedbacku, nie poleganie tylko na jednej osobie, bo wiadomo jak to jest, jedna osoba może żyć w swojej bańce i jej się wydawać, że tak naprawdę robi dobry kod. No a ktoś inny przyjdzie z boku i powie, że ten kod no jednak jest daleki od dobrej jakości, więc jakość kodu też ma kolosalne znaczenie jeżeli chodzi o dług technologiczny. To jest na każdym można powiedzieć obszarze od pojedynczych linii kodu, czyli po prostu są w optymalny sposób napisane do wyższych warstw jak cała architektura aplikacji. Wystarczy, że gdzieś na którymś z tych szczebli odpuścimy, pozwolimy na to, że wymyka się to trochę spod kontroli, jest stworzone w niewłaściwy sposób no i już od tego momentu zaczyna narastać dług technologiczny.
Zadbaj o bezpieczeństwo swojego systemu.
Paweł: Ja tu bym jeszcze wrócił może do tych frameworków. Czy zawsze na pewnym etapie, jak sobie wymyślimy jakiś produkt, który będziemy chcieli wypuścić na rynek, czy mamy pewność, że dany framework na przykład po kilku latach nie zostanie porzucony przez twórców? I tutaj, bo miałem w jednym z projektów taką sytuację, że przepisywaliśmy właśnie projekt na nowo, bo tam był straszny dług technologiczny i było napisane w Visual Basicu, który został tam porzucony, powiedzmy w 1998 była jakaś ostatnia aktualizacja, a porzucony chyba w 2006. Tak gdzieś tam doszedłem do takich ciekawostek. I była tam sytuacja, że dla dewelopera, który wszedł w ten projekt, to był czysty koszmar przepisywanie wszystkich relacji, robienie jakichś migracji w tym projekcie, tego typu rzeczy. No bo już dużo funkcjonalności ciężko było przełożyć na nowe technologie. Często trzeba było jakoś inaczej do tego podejść.
Damian: Tutaj niestety nie ma czarodziejskiej kuli, która wskaże, czy dana technologia przetrwa na rynku i tutaj nie można tak naprawdę obwiniać tego, który tę technologię wybrał, chyba że już na etapie wybierania było wiadomo, że ta technologia po prostu nie ma przyszłości. Sam znam z doświadczenia z naszego podwórka nasz ekosystem PHP, którym się specjalizujemy. Też 10 lat temu było mnóstwo frameworków. Nikt tak naprawdę nie był w stanie przewidzieć, który z nich się utrzyma dłużej na rynku i będzie tym stabilnym frameworkiem. Też można było postawić na Zenda, można było postawić na Codeigniter czy inne takie bardziej niszowe frameworki, których dziś po prostu nie ma. Jeżeli ktoś dobrze wtedy postawił np. na Symfony czy Laravela, no to tak naprawdę temat długu pod warunkiem, że było to na bieżąco aktualizowane, nie jest taki istotny. Więc tutaj ciężko tak naprawdę wytypować i tutaj przeczulam przed tym, że po prostu już na etapie wyboru bardziej patrzeć na to, czy już w tej chwili dana technologia nie jest zagrożona. Plus dwa, też jakie są perspektywy. To czasami widać po społeczności, po nastrojach. Wiadomo, nie przewidzimy nigdy, że za pięć lat może pojawić się technologia, która namiesza na rynku i totalnie wyprze tamte pozostałe, ale to jest i tak bardziej racjonalne podejście niż, decydowanie się od samego początku na coś mało pewnego. W przypadku Visual Basic'a, pewnie też jak klient zaczynał ten projekt, nikt nie był w stanie przewidzieć, że ta technologia wymrze. To nie jest tak, że technologia znika z dnia na dzień. Też idą sygnały, że przestaje być mniej rozwijana, są jakieś plotki, pogłoski najpierw, że coś tam się szykuje, że ta technologia za chwilę może być porzucona, to już jest taki etap, gdzie warto po prostu to podnosić z klientem, że wsparcie dla danej technologii za jakiś czas się może skończyć, że warto już pomyśleć o jakiejś migracji, czy nawet o zabezpieczeniu się, żeby mimo, nawet jeżeli klient powie: "nie będziemy przepisywać całego projektu w tej chwili", to maksymalnie się zabezpieczyć, żeby jak najdłużej ten support utrzymać, a jednocześnie gdzieś tam w tle pracować nad tym, żeby jednak do przepisania tych core'owych funkcji doszło. Siłą rzeczy to, że technologia znika, to może przez pierwszy rok, dwa nie być problemem, no ale już minie kolejne kilka czy dziesięć lat, no to tak naprawdę to jest sytuacja jak właśnie tak jak z tym programistą, no on zobaczy ten kod i powie, że tak naprawdę to jest nie do ruszenia, dokumentacji w internecie już też nie będzie na temat tego frameworka czy języka, szukanie jakichkolwiek zasobów wiedzy praktycznie nie będzie istniało, no i tutaj się już zaczyna prawdziwy, poważny problem.

Paweł: Dobra, to teraz chciałbym się zastanowić, czy dług technologiczny zawsze jest zły. Czy są sytuacje właśnie i tu coś już wspomnieliście na ten temat, że właśnie taki dług jest strategicznie korzystny dla jakiegoś biznesu i jakie mogą być korzyści właśnie z takiego powiedzmy krótkoterminowego długu technologicznego, że piszemy się na niego, że chcemy wypuścić coś nowego na rynek, mamy jakąś wizję, chcemy to przekuć w działania i w realny produkt, ale mamy ograniczony budżet.
Szymon: To jakby sam dług technologiczny będzie pewną drogą na skróty. Jakby często powstaje z uwagi na drogę na skróty. I teraz jeżeli mówimy o długu technologicznym, który powstał z uwagi na przyspieszenie prac i jest zaplanowany, to jakby to jest coś, co może być uznane, że dług technologiczny nie jest zły, ale jeżeli dług technologiczny powstaje z uwagi na brak kompetencji, o których też wspominał Damian. No to jakby taki dług technologiczny, co do zasady, będzie czymś złym, bo nie wynika z tego, że został zaplanowany, z tego względu, że jest to przyspieszenie jakichś prac, chęć wypuszczenia szybciej danego rozwiązania, tylko wynika po prostu z braku umiejętności, podjęcia złych wyborów. Kiedy już na wstępie wybieramy technologię, która ma ogłoszone zakończenie supportu do któregoś czasu, to wybieranie takiej technologii wynika albo z niewiedzy, że ktoś tego nie sprawdził, nie dopilnował, źle podszedł do całej analizy, albo ze świadomego wyboru, bo jako programista, jako firma mam kompetencje w takiej technologii, więc do samego końca próbuję tego klienta namawiać na technologię, która jest złym kierunkiem, złym wyborem, ale klient o tym się dowie dopiero za jakiś czas.
Damian: Ja powiem tak, niech pierwszy rzuci kamieniem ten, kto nie dostał taska pod tytułem jest to do zrobienia na wczoraj. W tym przypadku zaciągnięcie długu technologicznego jest jak najbardziej zasadne, bo mamy dwie opcje, że albo po prostu nie zrealizujemy tego taska, bo musimy przeprocesować go i zrobić go zgodnie ze sztuką, po prostu idziemy na ułatwienia, uproszczenia i jesteśmy w stanie dowieźć to w takim można powiedzieć dzikim deadline. Tutaj jest ważne, żeby później po prostu wziąć, usiąść i gdy już ta presja czasowa mija, no to dopracować ten dany task.
Szymon: Nie udawać, że ten problem nie istnieje z racji czasu, tylko wrócić do tego.
Damian: To jest świadoma decyzja. A druga rzecz, gdzie widzę, że dług technologiczny nie jest szkodliwy, to gdy naprawdę mamy takie projekty legacy, które działają stabilnie, są też odpowiednio zabezpieczone jeszcze jakimiś tam dodatkowymi warstwami, w żaden sposób nie spowodują, że coś się może nagle nieoczekiwanego zadziać. Służy on też często jako takie, można powiedzieć, stabilne rozwiązanie pomiędzy jakimiś tam nowymi technologiami. No to tutaj nawet jeżeli coś trzeba gdzieś dopracować, a ten kod jest przestarzały, architektura przestarzała i nie ma jakiegoś biznesowego, logicznego uzasadnienia, żeby jakkolwiek mocniej to ruszać, no to w myśl zasady, że jak coś działa, to lepiej tego nie ruszać, no to tutaj już się zgodzić na ten dług.
Paweł: Jak działa to nie ruszaj.
Damian: Tak, to już po prostu zgodzić się na ten dług i niech to po prostu funkcjonuje pod warunkiem, że po prostu nie przyjdzie taki moment, że jednak tych prac jest więcej, ciągle trzeba coś modyfikować, dodawać. Jeżeli to z poziomu ligacji wchodzi znowu na taki można powiedzieć development, no to tutaj już usprawiedliwienia na to nie ma.
Szymon: Zwłaszcza w momencie jakiejś migracji, bo często jest tak, że jak migrujemy do nowego systemu, to legacy musi przez jakiś czas działać. No i wtedy walka o to, żeby w takim projekcie nie zaciągać długu technologicznego, który już jest zaciągnięty, jakby dalsze jakiekolwiek prace nawet utrzymaniowe, czy prace związane z reakcją na jakiś problem wymagałyby wyprowadzenia długu technologicznego, no to to może być po prostu nieopłacalne z punktu widzenia biznesowego, jakby nie mieć totalnie sensu, bo wiemy, że żywotność tej platformy jest przewidziana tylko na X czasu, bo w trakcie powstaje nowa, czy jest w trakcie jakiejś migracji.
Paweł: Ja bym jeszcze wrócił do tych tasków na wczoraj, bo to jest ciekawe zagadnienie, jak właśnie biznes, bo ma bardzo duży wpływ na tę technologię i jeśli zlecamy sobie takie taski na wczoraj, bo są jakieś priorytety, często już w takich można powiedzieć projektach, które działają produkcyjnie jest tak, że z jednej strony klienci oczekują jakichś nowych funkcjonalności od nas, które trzeba dowieźć, zgłaszają błędy i te taski się kumulują. I dlatego może dojść do sytuacji, że powiedzmy project manager pójdzie do devów i powie, o to trzeba mega pilnie dowieźć, bo to już jest właśnie na wczoraj, to jest critical. No ale właśnie jak z perspektywy tej technicznej możemy, nie wiem, uświadomić biznes, że słuchajcie, ale "tego nie wolno bagatelizować, bo za x czasu pojawi się problem z tym, z tą funkcjonalnością".
Damian: Tutaj jest ważne, żeby była rola, może być takiego Tech Leada, osoby, która leaduje całym teamem technologicznym, żeby tego typu rzeczy raz, że sygnalizowała, dwa, notowała i też systematycznie przypominała klientowi, że musi być budżet, żeby rzeczy, które zaciągnęły ten dług technologiczny zostały wyprowadzone. Jeżeli nie, to będzie się wiązało to z tym, że ten dług będzie narastał. Myślę, że jedyne sensowne nadzorowanie tego to jest po prostu pilnowanie. Pilnowanie, bo tak naprawdę nic więcej w tym temacie nie jesteśmy w stanie zrobić. Wszystko jest zależne tak naprawdę od zasobów i budżetu.
Paweł: Ok, a jak na przykład powiedzmy mamy, działa produkcja i wspomniałeś o tych projektach legacy, że utrzymujemy taki projekt. Jest dużo zgłoszeń od klientów i mamy jakąś taką sytuację, że fiksujemy jedną funkcjonalność, ale pojawiają się jakieś inne problemy powiązane z daną funkcjonalnością, powiedzmy w innym module, że naprawa jednego buga powoduje szereg kolejnych. Jak można zareagować na taką sytuację?
Damian: To jest trochę... Przeczy tej idei właśnie projektu legacy, bo dla mnie definicja jest taka, że ten projekt już funkcjonuje bardzo długi odcinek czasu. No i działa dobrze, że ten etap tak jakby znalezienia tych błędów już mamy za sobą. Wiadomo, zawsze nie ma bezbłędnego oprogramowania i po czasie może wyjść jakiś bug, ale to jest też wtedy taka kalkulacja, no bo jeżeli nawet załatanie tego bugu to jest, można powiedzieć, ułamek tego czasu, który ten dany system funkcjonuje, a wiązałoby się to z tym, że trzebaby było go gruntownie przebudować, to wiadomo, tutaj z biznesowego punktu widzenia nie ma to jakiegoś uzasadnienia i lepiej tak naprawdę dalej to załatać po najmniejszej linii oporu, żeby po prostu działało. Z takim zastrzeżeniem, że jeżeli ta sytuacja się będzie powtarzała i te błędy się będą pojawiały w czasie, no to tak jak wspominałem, trzeba po prostu znowu projekt wziąć tak jakby na warsztat, przestać nazywać go legacy i traktować jako po prostu rozwojowy produkt.
Szymon: Kwestia założeń i przyjętej odpowiedniej strategii, bo jeżeli projekt nazywamy legacy i chcemy do niego w ten sposób podchodzić, a nagle wchodzimy w regularny development, bo jednak chcemy zrobić taką funkcjonalność, taki moduł, no to jakby to podejście, o którym tu rozmawiamy, tu mamy sprzeczności.
Paweł: Tak, zakładamy, że jeszcze nie została podjęta ta decyzja o przepisywaniu aplikacji na nowe technologie i musimy to w jakiś sposób utrzymywać.
Szymon: Tu często zasada złotego środka, że jakby nieprzesadzanie w żadnym kierunku w tego typu projekcie, próba wyprowadzenia wszystkich problemów, spłacenia całego długu, często okazuje się totalnie niemożliwa, a na pewno często nieuzasadniona biznesowo z tego ekonomicznego punktu widzenia. Z drugiej strony pozwolenie na to, żeby dług technologiczny przy takich założeniach, jak teraz mówisz, narastał dalej bez końca w niekontrolowany sposób, no to też nie prowadzi do niczego dobrego, bo w pewnym momencie możemy dojść już do totalnego impasu, do ściany, gdzie nagle tak dużo problemów się wysypie, że będziemy zmuszeni do bardzo gwałtownej migracji, do bardzo gwałtownego przejścia na nowy system, a pośpiech nigdy nie jest tutaj dobrym doradcą, ani czymś co pomaga. Zresztą tak jak powiedzieliśmy, dług technologiczny bardzo często właśnie powstaje z uwagi na pośpiech, brak czasu, drogę na skróty.
Paweł: No tak, właśnie ja tu widzę taką analogię np. często w startupach tak jest, że trzeba robić, zwiększać sprzedaż i tak dalej i często nie ma czasu na zastanawianie się, co by trzeba było uporządkować w kodzie, nad jakimiś takimi technicznymi rzeczami. Może właśnie też w przypadku spisywania dokumentacji, nie ma na to czasu. Często jest tak, że jest kilku deweloperów, którzy całą architekturę, taką koncepcję technologiczną mają w głowie. Potem rodzi się problem natury takiej właśnie czysto biznesowej, jak np. dany dev będzie chciał odejść.
Damian: Nie bez powodu, jaka jest statystyka, 9 na 10 startupów upada?
Szymon: Można tak uprościć.
Damian: Tak, kwestie biznesowe i czy w ogóle pomysł był właściwy to jest jedno, ale też często startupy upadają, po prostu nie są w stanie unieść tego ciężaru długu technologicznego. Wprowadzanie nowych innowacyjnych modułów trwa znacznie dłużej. Inwestorzy też na to patrzą. Plus tak naprawdę spada też wydajność takiej załóżmy aplikacji, co też zaczyna odsuwać od użytkowników. No i te statystyki nie biorą się z niczego. Startupy często bardzo szybko się rozwijają, lecą można powiedzieć na takiej fazie, bo tutaj inwestor zainwestował i tak dalej. Po czym jest szybki gwałtowny upadek, bo po prostu sami się załamują nad ciężarem tak jakby niedopracowanej technologii.

Paweł: Tak, bo tu dochodzimy właśnie do kwestii jak ten dług technologiczny potem wpływa na rozwój tej naszej aplikacji, tego naszego produktu. I tutaj właśnie to fajne co powiedzieliście, że możemy w pewnym momencie dojść do pewnej ściany, że już wpisanie kolejnej funkcjonalności powoduje zagrzebywanie się w stosie innych błędów, które będą powiązane z innymi funkcjonalnościami. No i ja coś takiego przerabiałem, cenne doświadczenie pracy w startupie. No ale właśnie fajnie by było jednak, żeby ten produkt ciągle żył i na siebie zarabiał.
Damian: Tutaj jeszcze tak może dodam, że jedną z konsekwencji długu technologicznego to też jest takie może nie patrzenie na przyszłość, bo o ile nawet projekt legacy działa poprawnie, to nigdy nie wiemy, czy ten projekt legacy po X czasie zbierze tak dużą bazę danych, że jednak nie będzie stabilny. I myślę, że to też jest właśnie bolączka startupów, że nawet jeżeli ich produkt działa poprawnie, wydajnie, no to jeżeli nagle ma gwałtowne rozpopularnienie więcej klientów, no to zaczyna tutaj wychodzić kruchość architektury i nawet jeżeli nie ma stricte długu takiego, można powiedzieć, jakościowego, no to taki dług wydajnościowy, że nie były na bieżąco optymalizowane jakieś aspekty, powoduje, że też się zapada sam pod sobą.
Paweł: Okej, i te błędy architektoniczne właśnie, czy Wy znacie, czy może słyszeliście w przeszłości o jakichś takich, ja bym to nazwał, fałszywych trendach w IT, które spowodowały, że nie wiem, może wiele firm się nacięło na tym, że zastosowali właśnie niewłaściwą architekturę w swoim systemie. Ja już spotkałem takie projekty, gdzie można było z tego wyjść, że niewłaściwie zaplanowana architektura, że można było powiedzmy w długofalowym ujęciu, czyli taką metodą małych kroków, wychodzić architektonicznie z długu i biznes nadal dobrze prosperuje. Ale tu też duża zasługa jest po tej drugiej stronie właśnie klienta, który ma świadomość na ten temat i można wszystko w czasie sobie zaplanować. Czyli z takim podejściem, z wyprzedzeniem planując, możemy potem z tego jakoś tak sensownie wyjść, obronną ręką.
Szymon: Patrząc trochę od innej strony i być może wsadzę tutaj dosyć mocno kij w mrowisko, ale trochę taka rozmowa ad hoc z dzisiaj, rozmowa z klientem, jak właśnie błędny wybór technologii czy podejścia, jakim długiem się potrafi odbić. Wsadzę w kij w mrowisko, bo to są technologie, które się fajnie rozwijają i są coraz bardziej popularne. Mam na myśli no-code, low-code, który w wielu przypadkach może być bardzo dobrym wyborem, bardzo dobrym kierunkiem, ale zdarzają się też sytuacje, że nagle okazuje się, że podjęcie takiej decyzji na początku sprawia, że odbijamy się od takiej ściany. Przykładowo kwestie wydajności, których wybrana platforma nie ma dobrze rozwiązanych i nagle przy odpowiedniej skali zaczynają się problemy z wydajnością, których w żaden sposób nie da się rozwiązać, nie da się zoptymalizować, bo nie mamy dostępu do kodu. Nagle okazuje się, że jakaś funkcjonalność, która wydawało się, że początkowo się o niej w ogóle nie myślało, ale nagle doszliśmy do takiego etapu, takiej skali, że użytkownicy chcą jakby tej funkcjonalności. No i okazuje się, że jest dużo trudniej na tej platformie zrobić. Dochodzimy do jakiejś ściany, że nie jest to możliwe. Oczywiście dosyć mocno tutaj generalizuje, bo to wszystko jakby sprowadza się zawsze do wybrania odpowiedniej platformy, dostosowania jakby rozwiązania, czy dostosowania technologii do potrzeb. Ale jest to jeden z realnych przykładów, o których, tak jak mówię, dzisiaj dyskutowałem z klientem, gdzie podjęcie błędnej decyzji, można powiedzieć takiej kluczowej, strategicznej, na etapie planowania po dosyć krótkim czasie zaczyna odbijać się pewną czkawką, która może się okazać, że jakby finalnie skończy się tym, że projekt będzie trzeba przepisać od nowa, podejść do projektu od nowa, wykorzystując klasyczne technologie.
Damian: Dla mnie takie najbardziej kluczowe to, gdy dany podmiot czy osoba decydująca właśnie o technologii nie patrzy właśnie w przyszłość, nie dopyta klienta mniej więcej jaką on szacuje skalę projektu przy różnych scenariuszach pesymistycznym, optymistycznym i żeby już tutaj się zabezpieczyć, bo wiele technologii można wybrać mądrze na podstawie właśnie tego typu predykcji. Jeżeli przykładowo wiemy, że klient celuje, że będzie miał w przyszłości kilka milionów rekordów danego typu w bazie danych, a my w żaden sposób sobie nie przeprowadzimy takiego testu, czy dana baza danych jest w stanie przetworzyć takie ilości w akceptowalnym czasie, no to już tutaj popełniamy błąd architektoniczny. Powinniśmy po prostu dobierać technologię do tego, jak szybko potrzebujemy uzyskać jakieś dane, przetworzyć i też jakie mamy tutaj możliwości samych ich składowania. Swego czasu strasznie modne zrobiły się wszelkie bazy nierelacyjne, wiodły prym, ale to też nie zawsze był dobry wybór, bo znowu kij ma zawsze dwa kące, że możemy wybrać wydajną bazę danych, która bez problemu sobie poradzi z dużą ilością danych, ale tak naprawdę nie jest też w projekcie potrzebna i tak naprawdę ze zbiegiem czasu to daje więcej szkód niż korzyści, więc to zawsze trzeba podejrzeć przyszłościowo i czy faktycznie wykorzystamy potencjał danej technologii.
Paweł: I tutaj bardzo fajnie wybrzmiało, że ten etap planowania jest ważny, czyli zebranie potrzeb klienta, jakaś jego wizja, w ogóle branża, w której działa. Trzeba do tego bardzo odpowiedzialnie podejść, żeby potem na jakichś etapach nie pojawiły się jakieś liczne problemy, no i tak naprawdę strata pieniędzy. Więc tutaj na tym punkcie bym zakończył naszą pierwszą część dyskusji o długu technologicznym, bo tu moglibyśmy, wydaje się, bez końca rozmawiać. Także dzięki panowie za poświęcony czas, super się z wami rozmawiało, a my zapraszamy was na drugą część naszego podcastu, który ukaże się niebawem.
Damian: Dzięki.
Szymon: Dzięki.