Ego kontra jakość.  Ku pamięci dobrych praktyk programistycznych 

Zanim nastała era metodologii oraz transformacji je wdrażających światem IT rządziły mityczne Dobre Praktyki Programowania. Przykazania, budzące grozę wśród początkujących lub kiepskich programistów, były sumą doświadczeń i wypracowanej wiedzy ogółu ciała programistycznego – zsyntetyzowaną i zredagowaną w postaci konkretnych praktyk oraz standardów.

W swojej pierwotnej formie owe lekcje poprawnego programowania odnosiły się głównie do warsztatowych aspektów jego wytwarzania, czyli wydajności oraz efektywności pracy w IT. Było tak ponieważ często kilkuosobowy zespół lub nawet pojedynczy programista odpowiadał za całościowe dostarczenie produktu, czyli za wszystkie etapy projektu: od architektury, poprzez kodowanie oraz testowanie, aż po wdrożenie oraz wsparcie techniczne. Tym samym imperatywem technicznym było efektywne pisanie wysokiej jakości kodu, łatwego do modyfikowania, wdrażania, utrzymania oraz testowania. Pociągało to za sobą wspięcie się przez programistę na wyższy poziom abstrakcji oraz sięgnięcie po raczkujące jeszcze narzędzia ułatwiające (lub wręcz automatyzujące) poszczególne etapy pracy. Skutkowało to powstaniem kolejnych barier kwalifikacyjnych na ścieżkach karier programistycznych, których metryką była znajomości owych zasad oraz sposobów ich wdrażania w życie. Wyznaczały one poziom progresji danej osoby na skali od złego do dobrego programisty. Oczywiście nie chciałbym się skupiać na szczegółowym omawianiu wszystkich dobrych praktyk programistycznych – na przestrzeni lat zostało o nich już napisane wystarczająco dużo artykułów oraz książek. Chciałbym natomiast użyć ich jako swoistego wyznacznika profesjonalnej dojrzałości pracowników sektora IT w szerszym kontekście kultury pracy oraz związanej z nią jakości. Kultura pracy, a dążenie ku jakości

We wcześniejszych artykułach rozpisywałem się już na temat budowania kultury w IT – czy to w odniesieniu do rekrutacji, czy doboru metodologii, czy ich wdrażania. Teraz chciałbym, w kontraście do poprzednich dyskusji, omówić konkretną i wymierną stronę jakości, czyli kod oraz procesy jego wytwarzania we wspomnianym właśnie kontekście kulturowym. Każdy z nas zapewne nie raz słyszał, że mądrość jest świadomością ogromu rzeczy niewiadomych, które nas otaczają. Głupiec zachłyśnięty wiedzą stawia się na samochwalczym piedestale, podczas gdy mędrzec pokornie dąży do ciągłego poszerzania swoich horyzontów. To właśnie różnicuje początkujących, a tych bardziej doświadczonych programistów, a co za tym idzie – wskazuje nam potencjalny problem na ścieżce rozwoju oraz budowania pozytywnej kultury pracy w IT. Problemem tym jest pycha lub krócej – wybujałe ego.

Grzech pychy

Każdy z nas zapewne kiedyś, na jakimś etapie kariery, poklepywał samego siebie po plecach w przeświadczeniu, że już tak bardzo dużo wie, tyle się nauczył lub tyle osiągnął. Zazwyczaj niedługo później byliśmy konfrontowani z rzeczywistością i sprowadzani na ziemię – czy to przez kolejne wyzwania zawodowe, czy też bardziej doświadczonych kolegów i koleżanki po fachu. Nie wszyscy natomiast tak samo reagujemy w sytuacji, w której naszego ego dostaje mniejszego lub większego pstryczka w nos. Nasze poczucie własnej wartości domaga się reakcji, a te są tylko dwie: ukorzyć się i przyjąć ową lekcję, wyciągnąć wnioski oraz pójść do przodu, lub iść w zaparte. Niestety, problem ten nie dotyczy tylko wspomnianych już początkujących programistów zachłyśniętych wiedzą, lecz także tych bardziej doświadczonych, którzy odbierają krytykę, nawet tę konstruktywną, jako ujmę na honorze lub bezpodstawny atak na ich kwalifikacje zawodowe. Jak łatwo się domyślić, taki stan rzeczy powoduje problemy nie tylko personalne, ale także jakościowe i wydajnościowe. Omówmy pokrótce ich długofalowe konsekwencje.

Egocentryzm a konflikty w pracy

Oczywistym chyba jest to, jaki wpływ na atmosferę w pracy mają kłótnie. Jeśli jedna ze stron w projekcie nie przyjmuje do wiadomości jakiejkolwiek krytyki, czy to w bezpośrednim odniesieniu do samego napisanego przez nią kodu, czy też sposobu rozwiązywania problemów logicznych lub dowolnego innego aspektu jej pracy, to w konsekwencji nie poprawi ona też swoich złych nawyków. W przyszłości będzie ponownie popełniać dokładnie te same błędy. Tym samym nie tylko pogorszą się relacje interpersonalne w zespole, ale też ucierpi na tym jakość i/lub wydajność pracy. W praktyce oznacza to, że ktoś będzie musiał ciągle poprawiać wspomniane błędy, czyli poświęcać swój czas lub kod pozostawiony w formie dostarczonej będzie rósł w formie długu technicznego, który – prędzej czy później – przyjdzie komuś spłacić, zazwyczaj z pokaźnymi odsetkami. Dodatkowo wydajność pracy oraz poziom zaangażowania osoby krytykowanej może z czasem bardzo drastycznie spaść, bo przecież po co taka osoba ma w swoim mniemaniu cokolwiek robić, skoro i tak będzie tylko krytykowana. Sumarycznie może się okazać, że koszt posiadania w zespole takiej osoby to nie tylko brak jej jakościowego wkładu w projekt, ale także obniżenie wydajności pozostałych członków i potencjalne przekroczenie terminów. Chciałbym dodać, że nie mam tutaj na myśli różnic opinii w technicznych dyskusjach o architekturze czy jej implementacji. Czym innym jest spór oparty na merytorycznych argumentach, w których można wypracować, choć też nie zawsze, jakiś konsensus lub chociaż kompromis, a czym innym próba przebicia głową muru czyjejś apodyktyczności. Czasami też to nie stanowisko samego programisty może być przyczyną konfliktu, lecz błędna dystrybucja personelu w hierarchii zespołu lub nawet całej firmy.

Zamiana ról

W zależności od struktury organizacyjnej może się zdarzyć, że sytuacja będzie wertykalnie odwrócona – osobą problematyczną może być ktoś, kto zajmuje wyższe miejsce w hierarchii, ale niekoniecznie posiada wyższe kwalifikacje programistyczne. Jako przykład podam tutaj sytuację z początków mojej kariery, gdy – jako nieopierzony. ale ambitny programista – przez dwa tygodnie pracowałem nad modułem aplikacji. Po pewnym czasie z dumą wrzuciłem kod do systemu kontroli wersji tylko po to, by następnego dnia dowiedzieć się, że mój wysokopoziomowy (w mojej subiektywnej ocenie, oczywiście) kod został kompletnie przepisany przez senior dewelopera, robiącego przegląd kodu. Był on dla niego zbyt abstrakcyjny i tym samym kilkaset moich linijek obiektowego kodu zostało zastąpionych kilkoma tysiącami proceduralnego kopiuj-wklej, a próba koleżeńskiego wyjaśnienia sytuacji zakończyła się odbiciem od ściany oraz, z czego nie jestem dumny, znaczącą redukcją mojej motywacji i zaangażowania w projekt. Z drugiej strony niczym nowym nie będzie też dla osób zaznajomionych z pracą w dużych firmach czy korporacjach fakt forsowania rozwiązań technologicznych przez osoby na stanowiskach zarządzających. Szczególnie jest to niebezpieczne w sytuacji, gdy są one już na tyle oddalone w strukturze organizacji i zakresie swoich obowiązków od faktycznej codzienności pracy zespołu deweloperskiego, że nie pozwala im to na racjonalny i merytoryczny wkład w procesy operacyjne wspomnianej jednostki. Nie wspominając już nawet o innych motywacjach, nie związanych z kwestią jakości czy wydajności dostarczanego przez zespół kodu. Mowa tutaj głównie o kwestiach wyboru technologii, czyli na przykład decyzji o wyborze lub zmianie dostawcy rozwiązania chmurowego. Szczególnie, jeśli osoba decyzyjna na poprzednim stanowisku w innej firmie prowadziła projekt oparty o konkretną chmurę, mimo iż tak naprawdę nie miała z nią w praktyce nic do czynienia. To z kolei uwidacznia nam ponownie podstawowy problem kultury pracy z którym borykają się duże organizacje, czyli wyższość rangi nad argumentami merytorycznymi i doświadczeniem osób bezpośrednio pracujących z danymi technologiami. Innymi słowy, ponownie odbijamy się od czyjegoś ego.

Walka z wiatrakami

Jak zatem pogodzić ludzkie ego z potrzebami projektowymi i dążeniem do jakości? W mojej opinii okienko kompromisu jest w tej sytuacji ekstremalnie znikome. Droga ku jakości wymaga nieustannego podnoszenia kwalifikacji – czy to poszczególnych członków zespołu, czy też zespołu jako całości. Ego jest, niestety, przeszkodą w tym dążeniu i o ile w części przypadków – poprzez odpowiedni mentoring, budowanie pozytywnej kultury pracy oraz relacji międzyzespołowych – jesteśmy w stanie wyprowadzić poszczególne osoby na odpowiednią ścieżkę rozwojową i wypracować merytoryczny konsensus, o tyle w niektórych sytuacjach pycha może być na tyle wrodzoną czy ugruntowaną częścią czyjegoś charakteru, że uniemożliwi lub bardzo utrudni nam wypracowanie odpowiednich standardów jakości dostarczanego oprogramowania.

Nadzieja

Sytuacja mogłaby się wydawać beznadziejna, ale na szczęście z ratunkiem przychodzą nam wspomniane ponadczasowe dobre praktyki programistyczne, wsparte współczesnymi narzędziami, oferujące bardzo konkretne metryki jakości, które posłużą nam jako amunicja w naszej walce o jakość.

Jakość kontra programista

Po pierwsze: gdy sytuacja konfliktowa wytworzyła się na linii zespół kontra konkretna jednostka lub grupa, narzędzia – np. systemy kontroli wersji – dostarczają nam miarodajnych informacji na temat ilości oraz jakości pracy dowiezionej przez określonych jego członków. To także bardzo granularny wgląd w poszczególne zmiany kodu, co umożliwia nam merytoryczną analizę wykrytych problemów. W połączeniu z rutynowymi przeglądami kodu otrzymujemy możliwość bieżącego wyłapywania ognisk zapalnych oraz doraźnego reagowania na powstające z nich problemy. Dodatkowo wdrożenie zautomatyzowanych testów, czy to jednostkowych, czy regresyjnych, czy wydajnościowych, dostarcza nam ciągłych i szczegółowych informacji w odniesieniu do wyżej opisanej pracy, w kontekście nie tylko jakości, ale także konsekwencji i stabilności naniesionych zmian. Na zakończenie chciałbym jeszcze wspomnieć o systemach ciągłego dostarczania oraz integracji kodu. Uzupełniają nam one naszą narzędziową trójcę o kolejny element monitorujący jakość, który – w połączeniu z oprogramowaniem monitorującym produkcyjną pracę aplikacji – daje nam bardzo rozbudowaną warstwę kontroli jakości zarówno całego zespołu, jak i poszczególnych jego członków.

Jakość kontra siła wyższa

Po drugie: w przypadku spięcia na linii raportowania wzwyż omówione przed chwilą metryki często będą naszym jedynym sojusznikiem w obronie jakości przed arbitralnymi decyzjami technicznymi, podejmowanymi przez osoby znajdujące się w hierarchii ponad (lub nawet dużo ponad) zespołem deweloperskim. Jak bowiem przemówić do osób wysoko postawionych w strukturze firmy, często będących osobami nie technicznymi, jeśli nie statystykami prezentującymi konsekwencje wspomnianych ingerencji, a nawet rozwoju trendów jakościowych w czasie? Dane takie, zaprezentowane w przystępnej wizualnie formie, będą przyswajalne nawet dla kompletnego laika i umożliwią nam merytoryczną dyskusję na niekoniecznie technicznym poziomie.

Koło się zamyka

Na zakończenie tej części chciałbym wrócić do podstawowych założeń dobrych praktyk, czyli pisania łatwo modyfikowalnego, testowalnego, wydajnego kodu. O ile wyżej omówione narzędzia są ewidentnym rozszerzeniem tych standardów i oferują nam bardzo praktyczne sposoby wdrażania ich w życie, o tyle czynnikiem różnicującym jakość dostarczanego za ich pomocą oprogramowania nadal będzie oddolny pęd ku jakości. Może się to wydawać redukcjonistycznym poglądem, ale sama deklaracja utrzymywania określonych standardów oraz fakt wdrożenia uzupełniających je narzędzi nie gwarantują same w sobie pozytywnej kultury pracy w danej organizacji. Standardy w subiektywnej interpretacji mogą zostać przeinaczone lub wręcz skorumpowane, a narzędzie błędnie wdrożone lub wykorzystane. O sukcesie decyduje ponownie oddolna kultura pracy – tak, jak w przypadku transformacji metodologicznych.

Korzenie, korzenie i jeszcze raz korzenie

Mimo, że absolutnie nie chcę zabrzmieć jak zdarta płyta, jestem zmuszony ponownie przytoczyć oddolną naturę procesu budowania kultury w IT oraz powiązanego z nią poszukiwania jakości.

Nie umniejszając niczyim kompetencjom, według mnie umiejętność pracy w oparciu o te podstawowe zasady jest jednym z najważniejszych czynników, którymi powinniśmy się kierować, wartościując progresję ścieżki kariery danego programisty. Niestety, wartość wymierna technicznie wykwalifikowanego, ale egomaniakalnego specjalisty lub osoby decyzyjnej, nie umiejącej pracować z innymi ludźmi, oraz ich całościowy wkład w pracę zespołu, nigdy nie będzie tak dobry, jak wartość absolutna jego wiedzy technicznej.

Biorąc pod uwagę to, jak ważny w procesie budowania kultury pracy w IT jest wcześniej już omówiony etap rekrutacji, zachęcałbym do poświęcenia odpowiedniej ilości czasu na zadanie pytań o konflikty, problemy, wyzwania oraz klęski, których doświadczył kandydat na ścieżce kariery oraz w kontekście pracy zespołowej. Jego lub jej odpowiedzi często mogą dać nam wgląd w to, jak dana osoba odbiera i reaguje na krytykę, a co za tym idzie – czy będzie powodować problemy komunikacyjne lub nawet jakościowe w pracy zespołu. Pozwoli to nie tylko ocenić jej wiedzę merytoryczną, ale także poziom znajomości i przestrzegania świętych (z mojej perspektywy), dobrych praktyk programistycznych – tak, abyśmy w wyścigu po jakość nie startowali w ołowianych butach.