poniedziałek, 30 marca 2009

Inteligientny projekt



Ile kosztuje słaby i nieprzemyślany projekt?
Na początku wydaje się być kusząco tani - kokodżambo i do przodu.

Mimo iż dużo pisze się o zaciąganiu długu technicznego, o tym, że każda prowizorka i rozwiązania typu "na pałę" lub "byle jak - byle szybko" trzeba spłacić z nawiązką, to jakoś nie zawsze dociera to do świadomości.

Nudzenie o zgubnych skutkach niestosowania się np do paru prostych zasad GRASP czy SOLID jakoś nie jest zbyt przekonujące - chyba jest zbyt abstrakcyjne. Obiektowe filozofowanie typu DDD ustępuje miejsca metodykom RÓB i WHISKY (Why the Hell Isn't Somebody Koding Yet).

Aby zejść z poziomem abstrakcji i unaocznić problem w namacalny sposób zobaczmy na banalnym przykładzie pojazdu ile może kosztować (nie tylko pieniędzy ale i czasu oraz nerwów) słaby projekt.

Weźmy taki oto trywialny problem jak wymiana żarówki przedniego światła mijania w naszym modelowym systemie, którym niech będzie pojazd osobowy pewnej szwedzkiej marki, produkowany w duńskiej fabryce na amerykański rynek lecz użytkowany w centralnej europie.

/*
* Śpieszę wyjaśnić nielicznym paniom
* czytającym tego bloga, czym dla samca
* jest wymiana żarówki w jego własnym samochodzie.
* Otóż jest czymś co robimy SAMI - jest to
* punkt honoru.
* Zwracanie się z prośbą o pomoc do innego samca
* w tej jakże błahej sprawie
* jest czymś tak żenującym
* jak prośba o podtarcie tyłka.
* (Metafora może niezbyt elegancka, ale niestety
* nie znajduję w swej prostackiej głowie
* niczego co lepiej oddawało by wagę problemu)
*/


Zaczyna się od tego, że system logów wyświetla na konsoli informację sygnalizującą błąd lewego światła mijania. Hmmm mamy system autodiagnostyczny - pewnie zaszyli testy integracyjne w bootloaderze. Naajz, zapowiada się bułka z masłem.

Rozpoczynamy podejście do problemu jak rasowy informatyk. Nie informatyk, informatyk to obraźliwe słowo - coś jak konował albo znachor. Jak programista, tudzież developer lub inżynier oprogramowania. No więc zaczynamy od dokumentacji.

Dokumentacja jest co prawda nieco lakoniczna w temacie interesującej nas wymiany żarówek, ale w sumie to dobrze. Tu nie może być przecież wielkiej filozofii; cieszymy się wręcz, że nie mamy zbyt wiele do czytania - czarno na białym, jeden rysunek, jedno zdanie. Proste. Taką dokumentację to ja lubię... ukazuje sedno problemu, bez zbędnego kontekstu. Heh to musi być proste jak instalacja windowsa.

Pierwsze podejście do pracy na systemie. Dokonujemy wstępnych oględzin interfejsu użytkownika i już po paru próbach bezbłędnie lokalizujemy reflektory - na których to (jak wynika z dokumentacji) mamy za zadanie wykonać prace związane z maintenance. Właściwie to gwoli ścisłości interfejs użytkownika jest w środku. Na zewnątrz jest... hmmm powłoka (shell) mająca na celu separację użytkownika od podmuchów wiatru tudzież strug wody, która nie może się oprzeć sile grawitacji. Powłoka ma również na celu wywieranie wrażenia na blacharach - "osobnikach płci żeńskiej, dobierający sobie partnerów do prokreacji przez pryzmat samochodu jakim się poruszają" (że pozwolę sobie zacytować za nonsensopedią).

Powłoka spełnia zatem zadanie anticorruption layer (dosłownie chroniąc wnętrze przez rozkładem polegającym np na rdzewieniu) jak i warstwy servisów.

Zajrzyjmy jednak pod maskę, czyli warstwę niżej. Pięknie...cóż za separacja modułów. Niestety tylko z prawej strony. Coś co na pierwszy rzut oka wydawało się eleganckim warstwowym systemem z separacją modułów, po dokładnych oględzinach okazało się chaotycznym układem.

O ile instancja modułu oświetlenia zainstalowana prawej strony wydaje się być otwarta na prace utrzymaniowe to z lewej natomiast mamy kłębowisko spaghetti w okolicach modułu wyświetlania fotonów w kierunku jazdy. Do tego stwierdzamy silny coupling interesującego nas modułu z modułem chłodzenia - a dokładnie chyba z filtrem powietrza.

Co do cholery ma filtr powietrza z reflektorem?!? Kto scalił je tak blisko, że nawet mała rączka junior programera nie wcisnęłaby się aby sięgnąć do interfejsu żarówki - że o jej implementacji nie wspomnę! Spójrzmy jeszcze raz do dokumentacji. O ironio! Radość sprzed paru akapitów wywołana prostotą dokumentacji obraca się w rozpacz. Na tych cholernych rysunkach nie ma pudła z filtrem obok reflektora! Jak się dobrać do żarówki? Teraz przydało by się nieco więcej kontekstu w dokumentacji. Co robić? Aaaaa!

No ale może da cię coś obejść. Przecież nie pojadę z tym do warsztatu. Wyśmieją mnie. Minęło już 15 minut, czas na wunderwaffe - dekompilator, któremu nic się nie oprze - KOMBINERKI. Wspaniałe niskopoziomowe narzędzie, które obejdzie wszystkie zabezpieczenia. Metoda brute force. Wyciąganie flaków z core silnika aby zrobić nieco miejsca na ręczne prace utrzymaniowe. Hmm na moje oko jednak aby odłączyć moduł filtru powietrza należy iść dalej po zależnościach i wymontować połowę silnika. A przecież obok jest tyle miejsca. Nie możliwe aby zrobili to perfidnie - przecież to taka pożąda firma;)

Kto to projektował?!? Inżynier praktykant?

Sam tego nie zrobię, potrzeba guru od modułów oświetlenia z biegłą znajomością architektury (chyba burdelu) silników. Co za wstyd... może by tak wysłać żonę...

Ale na guru trzeba pewnie czekać w kolejce. I koszt będzie 10 razy większy niż samej żarówki. Ale jak mus to mus - przecież żadna blachara nie zainteresuje się systemem z niesymetrycznym UI.

Guru w pocie czoła przedarł się przez splątane niby-warstwy i po godzinie wymienił instancję żarówki oraz skompilował wszystko i zrobił deploy. Jeszcze tylko szybki test jednostkowy (szkoda, że po deployu:P) - tak dla formalności i bugfix można uznać triumfalnie za zakończony. Czas na commit faktury... Cholera - czerwony pasek! Yyyy to znaczy szara ściana - tzn żarówka nie świeci. Ponowna dekompilacja. Na szczęście udało się wykryć buga - spalona kostka. Szkoda, że w systemie występuje ona w egzotycznej wersji HB4 - jesteśmy uzależnieni od jednego dostawcy:/

Podsumowując
problem: wymiana 1 żarówki
czas: 2h
koszt: przemilczę
przewidywane problemy: wymiana 3 innych żarówek w lewym reflektorze w najbliższym czasie oraz związane z tym poczucie beznadziejnej bezradności:)


//===========================
Oczywiście nie wymagam absurdu polegającego na tym, że każdy kawałek systemu będzie niezależnym modułem czekającym na łatwą podmianę. Core to core - niektóre kawałki są silnie zespojone bo taka jest natura problemu - jestem w stanie to zrozumieć. Nie potrzebuję przecież zbyt często wyjmować skrzyni biegów, ale żarówka - przecież to podstawa.

Nie wymagam też niczego szczególnego typu otwartość na rozbudowę (np możliwość wymiany reflektorów na lasery służące do strącania pojazdów poruszających się nieskrajnie prawym pasem;). Chodzi o zwykłe i podstawowe czynności maintenance.

Chyba, że biznes polega na serwisie:)))

4 komentarze:

Sławek Chmiel pisze...

Bo widzisz, im większy i bardziej rozbudowany system tym koszty jego utrzymania rosną, a przecież do tego dąży każdy producent. Dodatkowo oznacza to więcej modułów, powiązań, a co za tym idzie więcej spaghetti i trudniejszy bugfix.

Weźmy np. popularne niegdyś auto produkowane w Polsce nazywane maluchem. W tym przypadku jak sama nazwa wskazuje mamy do czynienia z małym system. Ponieważ nie ma on zbyt wielu zależności nawet jeżeli wszystko jest ze sobą 'zespawane' i otwierając maskę mamy totalne spaghetti nie ma go aż tak wiele aby kilku wygłodniałych studentów sobie z tym nie poradziło. Taki system możemy rozbebeszyć nawet pod blokiem wymieniając lub naprawiając interesujące nas moduły.

Pytanie tylko co się stanie jeżeli Ci sami studenci zajmą się dużym system? Czy później będziesz w stanie go uruchomić i się nim poruszać nawet po prostym bugfixie...?

Ogólnie świetny post:D

Pozdrawiam

Aleksander Wojdyga pisze...

Hmmm dziwne u mnie prawa żarówka jest trudniej dostępna... Może to był samochód do ruchu lewostronnego?

Swoją drogą montaż i demontaż filtru powietrza to też coś co "macho" robi samemu :D

czerwiu pisze...

Sławek, uśmiałem się nieźle podczas czytania - miałem niemal wrażenie, że całą historię ukułeś na kanwie moich doświadczeń z ostatniego miesiąca. Mojej dziewczynie spaliła się żarówka w VW i gdy mi powiedziała, że przy ostatniej wymianie zapłaciła 50 złociszy w serwisie, no to było dla mnie jak strzał w potylicę - duma nie wytrzymała. "Ja nie zmienię?" I dokładnie ta sama kwestia - instrukcja (lakoniczna) sobie, a praktyka sobie. Z prawej strony poszło szybciej (30 minut), ale tydzień później strzeliła lewa... Różnica była tylko taka, że zamiast rzeczonego filtra powietrza, do reflektora przyklejony był akumulator. 1,5 h walki, podczas których złość przeplatała się z bezsilnością i rozkminianiem, jak tu Połowicy zakomunikować, że reflektor wyjąłem i żarówkę zmieniłem, ale już na miejsce wmontować się go nie da :) Ostatecznie się udało - ten męski strach przed przyznaniem się do porażki ma jednak ogromną siłę :]

Wracając do analogii do projektowania/programowania - jeśli ktoś, mimo wszystko, w swoich pracach programistycznych zamierza tak działać, jak inżynierowie-projektanci od samochodów, to niech przynajmniej robi wszystko, by nie zostawić śladu, że to ON jest autorem rozwiązania :) Żadnych @author w klasach, jakieś mnemoniczne konto w SVN'ie, itd... ;) To tak żeby zaoszczędzić sobie ostrych inwektyw pod swoim adresem ze strony tych, którym przyjdzie pracować z naszym kodem ;)

M. pisze...

U mnie w Corsie, którą miałem, wymiana żarówki to 30 sekund łącznie z otworzeniem i zamknięciem maski:)

W "M" i "N" jeszcze nie wiem;P Wiem natomiast od kolegów, że w Renault i niektórych Fordach, bez specjalnego wihajstra można rozkręcić nawet kawał silnika, żeby dostać się samodzielnie do reflektora hehehe :D

Co do kosztów i przygotowania projektów - zawsze będzie komuś drogo. Jest domyślna akceptacja kupienia badziewki, bo kasa rządzi. Zawsze jednak będzie "Get what you pay for":) Często bywa tak, że wymusza sie zmniejszenie budżetu kosztem... pęknięcia "żelaznego trójkąta projektu" ;)

I kto na tym cierpi? Biedny i bogaty zamawiający, który jeszcze nie wie, ale chce kilka razy płacić za badziewie robione na "pięć" różnych sposobów przez "pięciu" tanich wykonawców, zamiast raz a porządnie profesjonalnie. Najlepiej oczywiście być 5 razy tym samym "tanim" wykonawcą;)

Szkoci mawiają "nie stać mnie na kupowanie tanich rzeczy" i mają rację. Ale jak klienta stać płacić kilka razy za badziewki, to niech frajer płaci! :)