Przychodzi baba do lekarza. Mówi “panie doktorze, byłam już u doktora X i on zalecił mi Y“. Na co lekarz: “a-HA! znam X, to konował, nic nie umie, tak naprawdę to dopiero JA pani powiem co trzeba zrobić“. Baba jest od tej pory zakochana w swoim nowym doktorze, nie mając tak naprawdę pojęcia czy faktycznie jest tak dobry jak twierdzi. Chodzi po sąsiadach i rozpowiada jaki to on jest cudowny, bo z taką pewnością pojechał po X, że coś musi w tym być. A do X to ona już nigdy nie pójdzie skoro jest taki słaby.
Przychodzi klient do programisty. Mówi “panie programisto, byłem już i programisty X i on mi napisał ten kod“. Na co programista: “ojezuu, takiego ścierwa w życiu nie widziałem, to się nadaje tylko do kosza, nic z tym się nie da zrobić, wyrzuć i napisz od nowa“. Zdarzy się (mi się zdarzyło gdy “byłem jeszcze taki”), że ów klient zachowa się podobnie jak wspomniana wcześniej baba – zakocha się w tak pewnym siebie i najwidoczniej zakochanym w jakości programiście, psy wieszającym na poprzedniku. “Och, drogi nowy programisto, jakież to nieszczęście że dopiero teraz ścieżki nasze się krzyżują, od tej pory zlecę ci wszystkie moje nowe projekty“. Domyślić się można, że te nowe projekty, pokazane jeszcze innemu programiście, mogą zostać potraktowane w identyczny sposób jak oryginalny kod programisty X.
Nie wiem jak wam, ale mi taki scenariusz nie jest obcy (w obu przypadkach). Co ta sytuacja pokazuje? Że bardzo łatwo jest zbudować sobie reputację alfy i omegi jadąc bez trzymanki po czyjejś pracy jak po burej suce, najlepiej z uśmieszkiem pełgającym w kąciku ust. Zerowym praktycznie wysiłkiem. Czy to faktycznie świadczy o wielkim doświadczeniu, o nieomylności i genialności “krytyka”? Nie. Do każdego kodu można się przyczepić. Nie ma kodu, którego nie da się napisać lepiej. Skrytykowanie cudzego kodu to zadanie najłatwiejsze na świecie dla każdego programisty, i szczególnie ci “dojrzewający” lubują się w podobnym gilganiu własnego ego. “To jest napisane bez DDD? Co za shit!“. “Nie ma ani jednej klasy wskazującej na zastosowanie wzorców projektowych? Jaki ciołek to pisał?“. Itd…
Porada “system jest tak źle napisany, że trzeba go napisać od nowa” to najbardziej amatorskie i godne pożałowania podejście, jakie można zaprezentować. Nie ma gwarancji, że po X miesiącach pracy nie skończymy z taką samą kupą kodu, zawierającą te same lub inne niedociągnięcia. A właściwie jest gwarancja, że tak się właśnie stanie. W Rapid Development fajnie opisano takie historie.
Bo niby czemu miałoby być inaczej? Projektowanie i implementacja systemu zajmuje czas. W tym czasie stajemy się (miejmy nadzieję) coraz lepsi w swoim fachu. Efekt: po zakończeniu projektu moglibyśmy go napisać lepiej. Ja przyznaję się bez bicia: każdy napisany przeze mnie projekt ssie. Dlaczego? Bo dziś napisałbym go lepiej niż rok temu czy pięć lat temu. I to jest DOBRY znak. To znak, że nie stoję w miejscu. Ale to także znak, że projekt, który zaimplementuję dzisiaj wspinając się na wyżyny swoich programistycznych, za rok nie będzie wyznacznikiem mojej top-formy. Bo za rok napisałbym go lepiej.
Nie ma kodu idealnego. Jest co najwyżej kod wystarczająco dobry. Ale nie oszukujmy się: większość kodu, z jakim przychodzi nam się na co dzień stykać, nie jest nawet taka. I to się nigdy nie zmieni.
Zdarzało mi się dostawać prośby o przejęcie lub review cudzego kodu.
Najbardziej zapadający w pamięć przypadek to księgarnia online. Dostałem dostęp do repozytorium z pytaniem “czy da się to dalej rozwijać?“. I jeśli tak – to czy bym się tego podjął. Była to aplikacja napisana w MVC, z tym że… 90% kodu znajdowała się w jednej statycznej klasie: Manager. Ten Manager robił wszystko: od dostępu do danych, przez wyliczanie rabatów, po zarządzanie całym procesem składania i obsługi zamówienia. Pierwsza moja myśl, jak już się zorientowałem o co tam chodzi, brzmiała, jak się można domyślić: “o kur…”. Mogłem potencjalnemu klientowi odpisać, że to najgorszy kod jaki w życiu widziałem. Że nie da się z tym nic zrobić. Że chętnie napiszę to od nowa (licząc oczywiście stawkę x2 czy x3 bo terminy były już bardzo naglące). Że jestem tak doświadczony i zajebisty że mnie całuj po stopach, a napiszę to lepiej.
Ale tego nie zrobiłem. Dlaczego? Bo to DZIAŁAŁO. Jak mogę zarekomendować wyrzucenie do kosza czegoś, co działa? Odpisałem, że jeśli system funkcjonuje jak powinien i są z niego zadowoleni, to w chwili obecnej (terminy) najlepiej będzie brnąć w niego dalej. Ale że ja się tego nie podejmę. I że wprowadzenie zmian w przyszłości będzie bardzo niebagatelnym i kosztownym procesem. Jedyne co mogę zrobić to zaproponować pewne konkretne rozwiązania w określonych obszarach, ale to samo w sobie jest osobnym zleceniem, którego efektem nie będzie nowa funkcjonalność ani lepszy kod, a jedynie wydeptanie ścieżki którą przyszły programista powinien podążać.
Sztuką jest wyodrębnienie w analizowanym systemie pewnej rodziny problemów i zaproponowanie ich rozwiązania, wraz z korzyściami, jakie ono przyniesie. Wyciągnięcie wniosków z cudzych (lub swoich) błędów i upewnienie się, że sami ich więcej nie popełnimy. Zaplanowanie refactoringu mającego na celu eliminację najbardziej palących kwestii.
I to właśnie rozumiem przez “code review” bądź “audyt”. Owszem, tracimy w ten sposób satysfakcję płynącą z mieszania czyjejś pracy z błotem i rośnięcia w oczach słuchacza/klienta, który być może nie ma zielonego pojęcia o czym mówimy i widzi w nas, jak baba z pierwszego akapitu, nowego najlepsiejszego doktora.
Konstruktywna krytyka z konkretnymi propozycjami ulepszeń jest potrzebna. Krytyka dla krytyki, bez analizy, diagnozy i wniosków – nic nie wnosi. Takiej mówimy, jak parówkowym skrytożercom, mocne i stanowcze NIE!
Mały disklejmer, aby ubiec komentarze drobiazgowych analizatorów: cały ten post traktuje o krytyce KODU z perspektywy PROGRAMISTY. Moi twitterowi śledczy mogą zauważyć jak bardzo narzekam na wszelkie oprogramowanie z którym mam styczność. To chyba z 80% moich tweetów. Ale jest pewna subtelna różnica: narzekam z perspektywy UŻYTKOWNIKA… a to zupełnie inna para kaloszy.