neděle 13. dubna 2014

Refaktoring, část I.: Proč já?!

Úvod

Četl jsem už spoustu článků i blogů o tom, co programátor má nebo nemá dělat, a jak užitečný a dokonce nutný je refaktoring. Nikde se ale moc nepíše o strategiích refaktoringu a dost lidí se ho pořád i tak trochu bojí. Tož jsem se rozhodl, že o tom něco napíšu sám, neb s tím mám dlouholeté zkušenosti.

V roce 2007 jsem přišel do firmy ICZ, jako "junior", který o Javě "už někde slyšel". Ne jako nějaký odborník, zkraje jsem byl zkrátka tolerován. Ne na dlouho ... po dvou měsících na jednom projektu ze mě udělali vedoucího projektu jiného, o dost většího, který dodnes (2014) přežil leccos, neustále narůstá a komplikuje se, ale paradoxně se i zlepšuje jeho stabilita i udržovatelnost - přitom na něm dělá pořád míň a míň lidí. Jak to?
Postupně začnu popisovat své zkušenosti - řekněme takovou formou "občasníku". Nebudu vám vtloukat do hlavy agilní metodiky, scrum, extrémní metodiky, zkrátka, nebudu vám říkat, co máte dělat. On totiž každý projekt potřebuje "svoje". To samozřejmě není nic proti těm metodikám, je dobré je znát, a vybírat si vhodné "zbraně k boji".
Jen pro zajímavost: "můj" projekt má po 11 letech vývoje zhruba 500 000 řádek kódu (kódu v Javě! čili ne javadoc, ne prázdné řádky a dokonce ani webové stránky - JSP).

Jsem nový v týmu

Tak to začalo. Návyky z minulé práce se tu nevedly. Nové návyky byly pro mě zvláštní, nové, chvílemi jsme se vzájemně odsuzovali, ale ve výsledku jsme stále táhli za jeden provaz.

Fáze 1: První zákaz

Když jsem uviděl víc jak 1000 řádkovou třídu, servlet, dokonce s jedinou metodou, chvíli jsem na to zoufale zíral, a pak začal refaktorovat. Když jsem se zmínil šéfovi, bylo mi řečeno, že nemám "spravovat co není rozbité" a "zákazník tohle neplatí".
Obvyklá rada zní - z takové firmy rychle utíkejte!
Mám takový "zlozvyk", vlastně dva:
1) Neutíkám z boje, nerad se vzdávám, radši zkusím, co se s tím dá udělat.
2) Nenechám si zakázat něco, o čem vím, že to dokážu dotáhnout do konce.

Fáze 2: Tolerance

Ukázalo se, že porušení zákazu nemá negativní důsledky. Pořád mi to nikdo nevěřil, někteří programátoři mě považovali za magora, kamikaze, a někteří to vzali jako výzvu. Výsledkem bylo mlčení na obou stranách, termíny se stíhaly, všechno víceméně fungovalo jako předtím, ok.
V tuhle chvíli se musím zastat možná i vašich projekťáků: postavte se do jejich role, pochopte, o co jim jde:
1) Více změn, větší pravděpodobnost chyb.
2) Změny v předaném hotovém kódu mohou způsobit změnu chování a ta se těžko vysvětluje zákazníkovi - ten NECHTĚL, abyste cokoliv z toho měnili.
3) Pokud se nestihne termín, vaší firmě hrozí penále a pokud navíc měníte něco, co nikdo nechtěl měnit, bude to bez slitování. Zákazníka refaktoring nezajímá, berte to na vědomí.

Musíte získat důvěru šéfa, ne hysterčit. Musíte být dost pečliví a dobří na to, aby se za vás mohl s čistým svědomím postavit.

Situace, kdy v týmu panuje nevraživost, když se se svými šéfy nechcete bavit o tom, co děláte, a vzájemně si lžete, je opravdu chvíle vhodná ke zvážení odchodu jinam. Ale pokud se to ani nepokusíte změnit, pravděpodobně jinde dopadnete stejně.
Většina programátorů jsou vysokoškoláci, odborníci, experti, dokonce se dá říct vědci. Pokud něco víte, musíte umět taky najít argumenty, důkazy, a mít trpělivost je ukázat a vysvětlit každému, komu bude třeba. Já vím, nejspíš jste ve vsyvětlování stejně špatní jako já - učte se to, jinou radu nemám ;)

Změna týmu (vítej v pekle!)

Fáze 3: Nedůvěřivá polopodpora

Po pár měsících mě přesunuli do jiného týmu na jiný projekt, kterému nikdo z programátorů nechtěl velet.
"Unit testy? Co to je? To si nikdo neobjednal!" - první reakce na otázku automatických testů. Refaktoring mi byl opět zakázán a opakovaně jsme si s projekťákem vysvětlovali, proč ano a proč ne - nicméně nikdy jsem s tím nepřestal. Testy jsme ale nepsali ještě dlouho.
Můj první úkol byla "opravička" (podle zadání droboučká) v aplikaci, která měla asi 5000 řádek ve 4 třídách (jedna měla přes 3000 řádek). To snad ani nebyla Java, to bylo peklo. Dostal jsem na to 12 člověkodní. Po dopoledni, stráveném "pícháním klackem" do zdrojáků, jsem pochopil, že netuším, co to dělá a jak.
Za nějakých 5 člověkodní jsem z těch 4 tříd udělal 42, aniž by se aplikace chovala jinak. Jen víc psala do logů. Později popíšu detailně, jak na to ;)
Za další den jsem našel hledanou chybu. A cestou našel asi 4 další, které stoprocentně uživatel musel vidět také!
Při ručním testování se zjistilo, že analytici našli další chyby, a že jsou i v provozní staré verzi. Po konzultaci se zákazníkem došlo i na opravy těchto chyb, načež po 7 člověkodnech jsem byl hotov (později vysvětlím, jak se to pozná ;)).

Fáze 4: Poplácání po zádech ... a ... a jéje

Ano, to byla malá výhra. A protože jste "fakt dobří":
1) Příště máte času polovičku, ne-li mnohem méně
2) Dostanete na starost ostatní programátory
3) Nekonečné konflikty se všemi, jen vedoucí sousedního týmu se vám směje
4) Přibývá stresu, ubývá chuť k práci
5) Není čas na změny

Tohle je začátek konce, kdy nakonec buď odejdete, nebo dospějete a postavíte se definitivně na vlastní nohy. Opět jsme u argumentace - té se nikdy nezbavíte!

Odhad pracnosti

S oblibou přirovnávám práci programátora k luštění křížovek - hodí se to jak pro vysvětlování věcí projekťákům, tak laikům.
Baví vás to? Tak si představte, že 8 hodin denně, 5 dní v týdnu, luštíte křížovky. Máte pocit, že vás to bude bavit? Ne, programátor vážně není "dělník, co jen pracuje hlavou"!
Takže, zkuste to takhle - šéfovi přineste libovolnou těžší křížovku, a za 5 minut se ho zeptejte, kdy jí už bude mít hotovou. A pak jemně konstatujte, že když on po vás chce odhad, je to podobné.
Pokud je navíc kód ve stavu, kdy se v něm nelze vyznat, je odhad prakticky nemožný. Nenaděláte nic, neexistuje řešení, jak dát byť řádově přesný odhad. Ano, měsíc je vhodná jednotka na jakoukoliv změnu v takovém kódu!

Programátoři

To znáte z amerických filmů, typicky vojenských, sportovních. Ne, nejsou to blbci, naopak! Někteří jsou chytří až moc - což je nejhorší varianta, pokud si je nezískáte na svou stranu. Oni se ve svém kódu přece vyznají a funguje! Nic je nedonutí změnit přístup, formátování, přestat psát Javu ve Vimu, používat na všechno statické metody s názvem a() a 20 parametry nebo hashmapou (vede se věčný boj, co z toho je horší).
Krom věčného vysvětlování a kontrolování cizí práce musíte stíhat i své vlastní programování. Ne, nemůžete přestat programovat - jednak by tým přišel o (aspoň jakýstakýs) vzor, jednak je to váš způsob získat si nějakou autoritu, ale hlavně se pořád ještě učíte nové věci - nemůžete radit a dohlížet na jiné, když sami nevíte, jak na to.
Ano, je to přesně jako v těch amerických filmech: hledejte silné stránky, buďte tolerantní, ale zároveň někdy musíte prostě někoho seřvat, nedá se nic dělat. Pravda je, že až tady mě naučili se "nasrat", do té doby jsem byl flegmatikem.

Konflikty

Z předchozího odstavce už je jasné, že buď najdete alespoň nějaké spojence, nebo odejdete. Nebo zatnete zuby a budete makat, dokud všechno nepřijde samo.
Jako vedoucí jsem byl tehdy řekl bych dost špatný. Jako programátor jsem dělal velké pokroky, ale nově nabyté zkušenosti a informace jsem neměl dost zažité na to, abych je někomu dokázal předávat.
Zpětně vím, že mám vážně moc dobré šéfy. I když se někdy hádáme, odsekávám, jednou jsem projekťáka dokonce nazval diletantem, načež on se neurazil, počkal, až "vyšumím", já se omluvil, a argumentoval a argumentoval, než jsme se nějak dobrali k tomu, že "doufá, že vím, co dělám".
Zkrátka, pokud víte, že jste něco přehnali, nebo dokonce byli na někoho nespravedliví, řešte to co nejdřív a velkoryse.

Stres

S tím mám problém dodnes. Je toho moc. Rady už znám taky, ale neumím se jimi důsledně řídit: vstávejte rituálně, pravidelně a stejně pravidelně choďte z práce. V práci nezapínejte Facebook ani jiné podobné blbiny, žerou neuvěřitelné množství času a oberou vás buď o výsledky, nebo o zbytek dne, kdy ty výsledky budete dohánět. Dodržujte pitný režim a jezte střídmě. Po práci se fyzicky hýbejte.
Tož jsem si to teď hezky sepsal, třeba se konečně polepším :-)
Chuť k práci mám, tu mi dává pohled zpátky na to, co všechno se už změnilo k lepšímu.

Změny

Z pohledu projekťáka, natož zákazníka, není na výslovně zákazníkem neobjednané změny čas nikdy.
Takže pracujete tak trochu v ilegalitě. Opět, jste experti, musíte vědět, co můžete změnit a co nemůžete změnit v dané iteraci. Prakticky jde o to, aby to neoddálilo termín - a pokud, aby to bylo obhajitelné. Což se lehko říká, ale těžko dělá.
Řekněme, že do toho budete dávat zhruba 30% času týmu. Pro projekťáka je to strašně moc a bude to chtít snížit. Nebo aspoň pro tuhle iteraci. Ne, neexistuje. Proč? Protože pokud to neuděláte TEĎ, termín bude možná (!) splněn, ale:
1) Větší riziko (řekněme rovnou, jistota) chyb, které tým bude řešit zdarma v rámci záruky
2) Oddálení údržby neznamená, že příště jí strávíte 60% další iterace, ale zůstane tam těch 30% a mezitím vám přibude produkce z minulé iterace.
3) Nezapomínejme na lidskou paměť - o dvě iterace dál už se učíte chápat svůj vlastní kód, čili stojí to další čas navíc.

Pokud změny uděláte, má to "nenápadné" bonusy:
1) Odhad pracnosti je řádově přesnější (z měsíců jdeme na dny)
2) Opravy jsou záležitostí hodin, dokonce minut
3) Od nějaké úrovně stavu kódu lze levně psát unit testy
4) Rozvoj aplikace má tah na branku, víte, co děláte a co ještě budete dělat, neobjevují se záhadné chyby.

Dnes

Fáze 5: Mám nejlepší tým v historii projektu

Ne, pořád jsme nevyhráli. Ale vedeme si dobře. Ta věta z podnadpisu mě napadla chvíli poté, co jsem se na jednoho "mého" programátora ukrutně naštval, seřval ho a za chvíli mi došlo, že neprávem. A že jsem poslední dobou dost nepříjemný. A že to není poprvé. Obratem jsem se mu omluvil a na další poradu přinesl láhev vína a nešetřil jsem.
Stresu je hodně, ale to není žádná omluva, takhle by se ten tým rychle rozložil. Vyhrazuji si právo být člověkem a občas se zachovat jako idiot, načež to ale neznamená, že bych tím nenáviděným idiotem hodlal zůstat.

Zpětně jsme udělali ohromný kus práce s tou půlmilionřádkovou saní. Ano, pořád půlmilionřádkovou, počet řádek narůstá velmi pomalu, protože pořád je tu těch 30% investice (někdy méně, někdy více). Mezitím se aplikace naučila komunikovat s asi 6 dalšími systémy, přešla z Javy 1.4 na JDK6 a má našlápnuto na JDK8, bylo napsáno asi 3000 testů od knihoven až po aplikace a testy GUI, přešlo se z Antu na Maven2 a později Maven3, kvalitu nám už několik let "známkuje" Sonar, máme automatický build systém a zasílání změn, atd.

V jednu dobu bylo na projektu neuvěřitelných 13 lidí. Dnes je nás 5 a děláme toho snad ještě více.
Náš projekťák má občas pořád tendenci někde "ušetřit", ale nechá si to vysvětlit a nepochybně svou práci dělá dobře.

Dostávám nabídky na dvojnásobek současné mzdy, ale není to jen tak - neodcházím z několika rovnocenných důvodů:
1) Mám rád evoluce, ne revoluce. Chci si užít pocit, kdy už budu vědět, že všechno klape. Myslím, že nejsem tak daleko od tohoto stavu.
2) Jiná práce, jiný tým, jiné podmínky, dost možná bych musel znovu někoho přesvědčovat, že používá technologie, ke kterým už se dnes nikdo nezná, že psát testy není ztráta času, že požadovat nějakou úroveň zdrojáků není perfekcionalismus, ale pud sebezáchovy.
3) Mám rád živé projekty, ne režim "přijít - napsat - spustit - odejít".
4) Mám tým, ve kterém se dokážeme domluvit, vyhovět si, a případně i zabojovat, aby projekt dopadl dobře (zákazník spokojený, projekťák spokojený, firma dostane zaplaceno a my možná odměny :-) ).

Samozřejmě to neznamená, že tu ta možnost odejít není. Ale momentálně jí nevyhledávám a nabídky odmítám.

Závěr úvodu (no hurá)

O refaktoringu se tu vlastně dneska mluvilo málo, zato dlouho. Asi jsem nenapsal ani nic, co by člověk nevěděl, ale šlo mi o to nabídnout pohled na tu "evoluci" od začátku do konce (budiž prozatímním neustále utíkajícím koncem označen dnešní den).
Pokud přijdete na projekt o této velikosti, nečekejte, že s ním pohnete jen tak. Je to práce na dlouho a vy se pořád musíte vejít do rozpočtů a těžce si vydobývat důvěru jiných. Ta vzniká tak, že uspějete krůček po krůčku v zakázkách, že vaše dílo funguje, když jiná mají problémy.
Je to hodně o hledání rovnováhy a schopnosti dotahovat věci do konce tak, abyste se k nim nemuseli vracet nečekaně a často a ... neradi.

Ano, zákazník srovnává hrušky s jablky, a vy to děláte taky, jen si to neuvědomujete. Dnešní naší společnosti chybí respekt, empatie, schopnost podívat se na něco očima někoho jiného - ale o tom jindy a jinde. Učte se to. Většina firem nabírá programátory a analytiky v jednom, takže - analyzujte ;)

Další díly asi budou kratší a jelikož to píšu bez přípravy a konceptu, uvidíme, co ze mě "vypadne".  Každopádně bych se chtěl zaměřit na nějaké strategie refaktoringu a zhodnocení toho, která kdy může být úspěšná.

Poslední dnešní věta:
Neexistuje nerefaktorovatelný kód!