Tekst

Krótka rozprawka z good enough

07-04-2020
Krótka rozprawka z good enough

Good enough najczęściej źle interpretowane i zbyt często nadużywane potrafi bardzo mocno zdegradować każdy projekt. Bowiem fraza ta w niesprawnych rękach, używana jak jedno z podstawowych narzędzi inżynierskich, staje się jedynie ciężką, żeliwną tarczą, której codzienne dźwiganie męczy i w raz z upływem czasu jedynie coraz bardziej spowalnia drużynę - zarówno pod względem rozwój produktu jak i samych członków zespołu. Tarcza ta, niestety bardzo często nie ma na celu obrony niczego, poza autorytetem, pozycją i stanowiskiem pomysłodawcy. Jest jedynie jego ucieczką od rzetelnej dysputy, w której to przedstawia się konkretne argumenty.

Good enough na przykładach jest kontynuacją artykułu, gdzie co jakiś czas będą opisywane przykłady praktyczne na podstawie zbieranych doświadczeń.

Good enough - ujęcie praktyczne

Przez lata swoiej kariery - poddając w wątpliwość słuszność jakiś rozwiązań - good enough mogłem usłyszeć jako odpowiedź na dosłownie każde, najgorsze partactwo jakie można sobie wyobrazic. Od kompletnej chałtury i bałaganu w kodzie, architekturze i infrastrukturze, przez wręcz amatorskie i prowizoryczne konstrukcje, smart-hacki, hardcode, kolejne if’y, code spaghetti, aż po brak jakich kolwiek elementów cointinous integration, code review, czy nawet systemu kontroli wersji. Wszystko to przysypane prostym good enough przez doświadczonego architekta, team leadera czy po prostu szarego seniora.
Chociaż prawada była taka, że całość przywodziła na myśl pełen bałaganu i chaosu pokój zbuntowanego nastolatka, niż rozwiązanie wychodzące z rąk profejsonalisty.

Dzisiaj, jeżeli miałbym zdefiniować tę frazę poprzez doświadczenie i pracę z ludźmi, to good enough jest to przedewszystkim:

  • dywan, pod który zamiata się problemy
  • tarcza, która ma w bardzo prosty sposób uchronić przed merytoryczną dyskusją
  • knebel, który ma zatkać usta, aby pewne braki komepetencyjne nie wyszły na jaw

I tak na przykład good enoguh z jakimi spotkałem się tylko w ostatnich paru latach:

  • metoda mająca ponad 1000 linii kodu
  • mieszanie logiki prezentacji z zapytaniami SQL
  • dziesiątki if-else
  • sztuczne byty, które nie odzwierciedlały dosłownie nic o czym mówił biznes
  • zmienne typu a1, b1, xflag
  • instrukcje goto
  • klasy z nazwami XClass, BetterClass
  • tabele-worki, mające dziesiątki kolumn
  • niesformatowany kod, gdzie format przypominał bazgroły pierwszo klasisty i linie potrafiły mieć 400 znaków.
  • hardcodowane wartości, magic numbers
  • spaghetti code, gdzie jedna zmiana powodowała 10 błędów w nieoczekiwanych miejscach

Wszystko to budowane na sprawdzonych przez lata i solidnych fundamentach: przecież działa, brak czasu, terminy, priorytety, kiedyś się poprawi, wrzućmy do backlogu, oj tam Uncle Bob,…

Kiedy wracam do wspomnień o tych wszystkich tłumaczeniach i usprawiedliweniach, ciężko mi uwierzyć, że wypowiadały to potencjalnie dorosłe, dojrzałe osoby. Architekt, TeamLeader, Teach leader, Senior - wszyscy Ci, którym zaufano i płacono za pełnienie ról, które z definicji miały czuwać nad jakością i utrzymywaniem rozwiązań na właściwych torach oraz nad rozwojem technicznym mniej doświadczonych członków zespołu.

Good enough - w ujęciu polskim

Jeżeli przetłumaczymy good enough na język polski to będzie to wystarczająco dobry. Brzmi całkiem rzetelnie, ale jeżeli głębiej nad tym się zastanowić, to co to właściwie znaczy? Dlaczego nie po prostu dobry? Dlaczego dodajemy przysłówek wystarczająco? Czy to nie brzmi trochę tak, jakbyśmy chceli jakoś usprawiedliwić wystąpienie słowa dobry? w głębi wiedząć, że dobre to, to wcale nie jest i jakoś trzeba je wesprzeć.

Te rozwiązanie to kompletna fuszerka ale wystarczająco dobre w tym kręgu, aby zostało zaakceptowane.

Chcąc zmapować wystarczająco dobry na skalę ocen szkolnych, to jakaż byłaby to ocena?

  • 6 (celujący) i 5 (bardzo dobry) z oczywistych względów możemy odrzucić. Zwolennicy good enough to nie piątkowi uczniowie.
  • 4 (dobry) - też do odrzucenia, gdyż wierząc w to, że rozwiązanie jest dobre, nie dodawalibyśmy wystarczająco. Oczywiście pamiętam, że były oceny jak 4-, czy 3+/3,5, jednak idźmy dalej.
  • 3 - dostateczny
  • 2 - dopuszczający

I tutaj wystarczająco dobre plasuje się. Jest to rozwiązanie między 2 (dwóją), a 3 (dostateczną). Z silnym wskazaniem na 2 (dwóje). Z jednej strony jeżeli szukalibyśmy synonimu słowa dostateczny, to byłoby to właśnie wystarczający, jednak z drugiej strony, mówiac wystarczająco dobry mamy na myśli to, że coś spełnia jedynie minimalne kryteria i jest tuż przy granicy ‘niedopuszczalne’.

Good enough - aby… właściwie co?

Kiedy używamy wystarczająco dobry wskazujemy, że to wcale nie jest idealny stan w którym chcielibyśmy się znaleźć, że ma on wady, ale…
No właśnie bardzo często brakuje jasnego wskazania tych wad. Ilekroć słyszałem good enough występowało to nieme… aby działało, aby szybko dostarczyć, ale nigdy o konsekwencjach z tego płynących. A one zawsze były. Świadomość o ich istnieniu, już niekoniecznie. Bo jeżeli wszystko jest tak good enough, to skąd mamy pojęcia długu technicznego czy flaccid scrum ?

Większość z nas chciałaby zacząć pracować przy nowym projekcie, ale kto tworzy te nowe projekty? Kto doprowadza do stanu, że projekt po pewnym czasie to kompletna ruina, której rozwój coraz bardziej spowalnia, męczy zespół, burzy zaufanie klienta, który ma już dosyć słowa refactoring. Na pewno nie my, to oni.
Przecież jeżeli lider techniczny mówi, że ten kolejny if jest good enough to oczywistym jest, że jeśli dodamy jeszcze tylko jeden to nie sprawi on, że kod nagle stanie się gorszej jakości. Jeżeli funkcja ma już 300 lini, to te trzy kolejne też są good enough! Jeżeli klasa robi już 4 różne rzeczy, no to po co tworzyć nową, piąta też jest good enough.

Good enough - ujęcie mierzalne

W teori good enough można zobrazować, za pomocą wykresu, wysiłku włożonego w rozwiązanie od realnej korzyści. Ma to jak najbardziej sens, jednak to co jest pomijate to fakt, że wartość która mówi good enough jest jedynie wartością lokalną, silnie zależną od kontekstu, a nie globalną czy uniwersalną.

  • W jednym projekcie estymaty z dokładnością do 2-3 tygodni mogą być wystarczające, ale w innym już nie.
  • W jednej aplikacji można wydać aplikację bez pięknego UI, w innym nie.
  • W pewnych obliczeniach zastosowanie typów float może być właściwe, w innych nie.
  • W jednym systemie eventual consistency może sprawdzać się doskonale, w innym może być niedopuszczalne.
  • Jeden raport może generować się kilka godzin, ale drugi musi być gotowy w mniej niż sekundę.

Podejście takie, może sprawdzać się jako odniesienie do ogólnej koncepcji, logicznego rozwiązania czy perspektywy użytkownika. Natomiast, jeżeli mówimy o jakości rozwiązania to good enough w praktyce to funkcja, która nie posiada minimum. Każde jest jedynie lokalnym minimum dla środowiska, w którym znalazłeś się i zawsze można sięgnąć niżej. Zawsze znajdzie się ktoś, kto powie good enough na coś będącym poniżej jakiej kolwiek krytki i nieakceptowalnym w profesjonalnym środowisku.

My profesjonaliści, realizując wymagania, mając do wyboru wachlarz sposobów ich realizacji, powinniśmy informować klienta o konsewkwncjach z nich płynących. Jednak zawsze powinniśmy wykonywać naszą pracę nawet nie tyle, co według standardów globalnych, a wręcz podnosząc te standardy - ze wzlędnu na wiek i niedojrzałość naszej branży.

Good enough - ujęcie zwinne

Tworząc produkty w sprintach (iteracyjnie i przyrostowo), nierzadko z MVP (Minimum Viable Product) na czele, komunikując się całym zespołem bezpośrednio z klientem/właścicielem produktu, dostarczamy bardzo prostą, okrojoną funkcjonalność, która jest jedynie małym fragmentem większej układanki. Nierzadko, układanki której ostatecznego kształu nikt nie zna.

Good enough, aby zainteresować klienta, good enough, aby użytkownik zobaczył, good enough, aby uzyskać feedback. Na tej podstawie Klient może podjąć decyzję, czy to dobra droga, czy nie?, czy idziemy dalej? skręcamy w lewo, w prawo ? a może zawracamy?.

Jednak to właśnie ze swej natury good enough ma wpisaną w sobie jakość, rzetelność i staranność. Bo dziś TO mało istotne rozwiązanie good enough, które nigdy się nie rozrośnie, jutro może zmienić się w not enough i zalać nas kolejnymi wymaganiami.

Development to nie bieg na 100 metrów w lini prostej, to nawet nie maraton, to coś znacznie więcej. Jest jak bieg zespołowy gdzie nie wiemy dokąd biegniemy i ile kilometrów przed nami, bieg gdzie członkowie zespołu odchodzą i przychodzą nowi, a biec cały czas trzeba.

Good enough nie dotyczy jakości wykonania

Kiedy mówię good enough mam namyśli to, że z pośród kilku sposobów na jakie można rozwiązać problem, zrealizować funkcjonalność, świadomie wybraliśmy jeden z nich. Może nie taki, który sprosta wszystkim problemom świata, który będzie najbardziej wydajny, który nigdy nie będzie wymagał poprawy czy dalszego rozwoju. Ale taki który w naszym kontekście, w danym czasie sprawdza się w sposób akceptowalny dla wszystkich. A przedewszytkim w sposób dzięki, któremu klient zoptymalizuje wartość produktu poprzez zrealizowaną funkcjonalność.

Ale good enough nie może być wymówką do partactwa, bałaganiarstwa i chałtury. Powodem do wymówki dla kolejnego if’a, kiedy to złożoność cyklomatyczna dawno już przekroczyła wszelkie granice zdrowego rozsądku, powodem do niepodzielenia metody, kiedy ta zaczyna zmieniać się w powieść, do niewydzielenia klas, kiedy to jasno wyklarowała się kolejna odpowiedzialność. Do nieutworzenia wspólnej klasy, kiedy to kolejny raz robisz tę samą zmianę w kilku miejscach. Do niezaktualizowania domeny w postaci klas, zmiennych, metod, testów, projektów, namespaców, kiedy to jasno zmieniło się nazewnictwo.

Good enough to nie rozwiązanie po łebkach, to nie partactwo i nie byle działało

rozwiązanie good enough to przede wszystkim rozwiązanie bardzo dojrzale i wybrane świadomie, z dogłębnym zrozumieniem wszystkich jego wad i pełnej ich akceptacji - przez wykonawcę ale najczęściej przez odbiorcę. Dalej to rozwiązanie wykonane z tą samą najwyższą starannością i kunsztem, wraz z wykorzystaniem dobrego warsztatu i praktyk.

- MD