Każdy kod można usprawnić / napisać lepiej. Bez wyjątku. Nie ma kodu idealnego (jak już zresztą kiedyś pisałem). Jednak w pewnym momencie trzeba przestać, tzn. nie można dopieszczać w nieskończoność jednego kawałka kodu zaniedbując wszystko dookoła. Ale nie oznacza to, że powinniśmy akceptować każde poplątane ścierwo jakie wyjdzie spod naszych skrzypiących paluchów i mówić “spoko, jest wystarczająco dobrze“.
Istnieją dziesiątki metryk pozwalających określić “dobrość” kodu. Wszystkie one mają dwie wspólne wady (albo o czymś nie wiem:)). Po pierwsze: są “generic“, więc aplikuje się je bez szerszego spojrzenia na to, co w życiu (a przynajmniej w branży software) najważniejsze: kontekst. Po drugie: nie odpowiadają na pytanie “po co dążyć do granic określonych tymi metrykami?”.
W miniony weekend, gdy z głowy całkowicie wyrzuciłem życie codzienne i zanurzyłem się w gorącej wodzie z bąbelkami, przy akompaniamencie My Dying Bride (norrrrrmalnie romantische situazion!), niespodziewanie naszły mnie refleksje na ten właśnie temat. Ot, figiel spłatany przez dość mocno ostatnio zaniedbany dev-umysł. Z przemyśleń wyszła mi całkiem krótka lista pytań, które należy sobie zadać. Znalezienie granicy, za którą nasza praca jest “wystarczająco dobra” sprowadza się do paru prostych punktów:
Czy poniższe kwestie mieszczą się w akceptowalnych ramach czasowych?:
- wprowadzenie nowej funkcjonalności
- poprawienie buga
- dodanie nowej osoby do projektu
Czy poniższe kwestie mieszczą się w akceptowalnych ramach ilościowych?:
- bugi wprowadzane przy implementacji nowych funkcjonalności
- bugi wprowadzane przy poprawianiu bugów
- bugi znajdowane przez końcowych użytkowników
Jeżeli na każdy z podpunktów odpowiedź brzmi “tak, jest ok” – to system jest wystarczająco dobry. Mało tego, proces wytwarzania i zarządzania cyklem życia tego systemu również jest wystarczająco dobry. W przeciwnym wypadku – trzeba zmienić albo implementację części systemu, albo architekturę, albo proces, albo… wartości kryteriów użytych do zadawania pytań.
Im dłużej się nad tym zastanawiam, tym bardziej jestem przekonany, że tak, to takie proste. W końcu właśnie po to tworzymy “ładny i porządny kod” a nie masę spaghetti…
…która to masa także może być dobrym wyborem, w zależności od kontekstu. Czy w PoC, którego czas życia od napisania pierwszej linii do skasowania z dysku wynosi max miesiąc stosowanie TDD daje jakieś korzyści? Może tak, a może nie. A co z IoC/DI? Niekoniecznie. Intensywne testy przeprowadzane przez dedykowany zespól testerów? Pewnie nie. Bo wartości dla zadawanych pytań są zupełnie inne niż dla produktu komercyjnego. Dla systemu “internal” będą jeszcze inne. Dla aplikacji wykorzystywanej przez 10 osób będą jeszcze inne, a dla portalu z setkami tysięcy użytkowników – jeszcze inne.
Tak więc: pojęcie “kod wystarczająco dobry” oznacza co innego dla każdego systemu. I, co ważne i charakterystyczne: nie jest to odpowiedź stała. To, co dzisiaj jest wystarczająco dobre, za rok może wymagać dodatkowych inwestycji aby jednak podnieść jakość odpowiednią dla nowych realiów.
Czy coś pominąłem, jakieś kluczowe pytanie nie podpadające pod jedno z powyższych? Kryterium, dla którego stosujemy wszelkiego rodzaju best practices, a które nie podpada pod powyższe kwestie?