sobota, 11 maja 2013

Czy to już czas?

Jakiś czas temu, po długim ślęczeniu nad bugiem zgłoszonym przez klienta, gdy udało mi się w końcu odkryć źródło problemu i otworzyłem plik z klasą, której metoda była odpowiedzialna za całe wyrządzone zło, popatrzyłem na kod i przed oczami stanął mi obraz dżungli, pełnej pnączy, drzew, zwierząt, insektów i wszystkiego, co tam jeszcze w takich dżunglach się znajduje. Niby dżungla jedna, ale jak wejść do środka, szczególnie bez przygotowania i dość obszernej wiedzy, co w niej można znaleźć, to aż przebiega zimny dreszcz po plecach.

Taki też dreszcz pojawił się niespodziewanie, gdy rzuciłem okiem, nieprzygotowany na to, co mogą ujrzeć moje oczy. Muszę przyznać, że interfejs klasy przedstawiał się całkiem znośnie - ot, jedna metoda przyjmująca jeden parametr. Gwoli usprawiedliwienia swojej reakcji pragnę napisać tylko - metoda jedna, ale za to JAKA metoda. Szczerze mówiąc, to wydaje mi się, że nie przesadziłbym, gdybym napisał, że istnieją na tym świecie pakiety, które zawierają mniej linijek kodu. A tych linijek było pięć setek prawie.

Od razu wiedziałem, że tutaj raczej nic nie wskóram, refaktoryzacja bardziej niż niezbędna jest. Zanim jednak przystąpiłem do dzieła wykonałem dwie czynności.
Po pierwsze, sprawdziłem, czy są testy. Ku mojemu zdziwieniu okazało się, że są, nawet całkiem pokaźny ich zestaw. Tak na marginesie pragnę dodać, że takie doświadczenia za każdym razem przypominają mi, jak istotne są testy i jak bardzo pomagają. Muszę przyznać, że sam proces refaktoryzacji przebiegł całkiem sprawnie, a to przede wszystkim zawdzięczam bogatej gamie unitów, które towarzyszyły owej ogromnej metodzie.
Po drugie, nim przystąpiłem do właściwego zadania, pooglądałem sobie kod. Raczej nie chodziło o zrozumienie jego zawiłości (z doświadczenia wiem, że lepiej logikę w takich wypadkach poznawać w trakcie refaktoryzacji, bo odkrywamy ją stopniowo), a raczej o budowę samej metody. Wydaje mi się, że nikogo nie zaskoczę, gdy powiem, że if'ów, switch'ów i tym podobnych konstrukcji była tam imponująca ilość. Łatwo było sobie odtworzyć proces "rozwoju" takiego kodu. Tutaj jeden wyjątek, czyli jeden if, tutaj jeszcze jeden, a tutaj pewnie okazało się, że działanie zależy od czegoś, więc należy switch'a dorzucić itp. itd. Chyba każdy to widział i chyba każdy to zna.

Zdaję sobie sprawę, że post ten nie wniesie zbyt wiele wiedzy, ale nie w tym celu go piszę. Chciałbym raczej prosić Was wszystkich, tworzących/modyfikujących/rozwijających kod o to, abyście za każdym razem, gdy dodajecie jeden warunek, gdy sprawiacie, że ilość linijek się zwiększa, zastanówcie się, czy to już czas? Czy to już czas na refaktoryzację? Na przeniesienie odpowiedzialności? Na wydzielenie klasy? Metody?
Wiem, że dużo prościej jest dorzucić dwie linijki kodu i jeden, no może dwa testy, ale jeżeli odpowiednio wcześnie zauważycie potencjalną możliwość rozwoju fragmentu aplikacji i spróbujecie sobie z tym poradzić już przy tym pierwszym ifie, to możecie zaoszczędzić wielu godzin osobie, która w przyszłości i tak będzie musiała to zrobić. Może się okazać, że tą osobą będziecie Wy.

Ja ze swojej strony też postaram się nie tworzyć niepotrzebnych komplikacji :)

PS Gdybyście jednak doszli do wniosku, że to jeszcze nie ten moment, to pamiętajcie o testach, bo na pewno nie zaszkodzą, a ich obecność może przynieść ulgę przerażonemu programiście :)