Slovník pojmů
Refaktoring
Kód se může stát čitelnější a lépe testovatelný, aniž by uživatel dostal jinou funkci nebo pravidlo.
Stručná definice
Měnit uspořádání, ne slíbené chování.
Refaktoring upravuje strukturu zdrojového kódu: může odstranit duplicitu, pojmenovat nejasnou část, rozdělit příliš dlouhou metodu nebo přesunout odpovědnost do vhodnější třídy. Vstupy, výstupy a důležitá vedlejší chování mají zůstat stejné.
Tato hranice je důležitá. Pokud se má aplikace nově chovat jinak, jde o funkci nebo opravu chyby. Jestli se nahrazuje velká část systému jinou implementací, jde spíše o rewrite. Refaktoring může takovou práci připravit, ale není zástěrka pro smíchání všech těchto změn do jednoho kroku.
Kdy pomáhá
Když současná struktura zbytečně ztěžuje další změnu
Dobrá příležitost není neurčitý pocit, že je kód „ošklivý“, ale konkrétní problém při porozumění, testování nebo úpravě.
- stejné pravidlo je zkopírované na více místech a hrozí, že se začne lišit
- metoda nebo třída má více nesouvisejících odpovědností
- název skrývá význam hodnoty, rozhodnutí nebo hranice mezi vrstvami
- nová změna je riziková, protože závislosti nejdou snadno dohledat pomocí statické analýzy a testů
- před plánovaným rozšířením pravidel, pokud lze nejdřív bezpečně zjednodušit výchozí stav
Praktický příklad
Výpočet ceny objednávky je zapsaný dvakrát
Checkout i administrace obsahují téměř stejný výpočet slevy a zaokrouhlení. Než se kód přesune, testy popíšou dnešní výsledky pro běžné i hraniční objednávky. Tím vznikne ochrana, že po změně zůstane cena pro stejné vstupy stejná.
V prvním malém kroku se jen vytáhne společný výpočet do jedné třídy a oba původní vstupy ji začnou volat. Potom se spustí testy v PHPUnitu a PHPStan a změna projde code review. Kdyby se při tom změnilo pravidlo pro nový typ slevy, už by nešlo o čistý refaktoring; tato funkční změna má mít vlastní zadání a ověření.
Postup
Bezpečný refaktoring po malých krocích
Menší změny se lépe kontrolují, vracejí i reviewují. Každý krok má mít jeden srozumitelný účel.
- Pojmenovat problém Popiš konkrétní bolest: duplicitu, nejasnou odpovědnost, těžko testovatelnou větev nebo nepřehlednou závislost.
- Zachytit současné chování Spusť existující testy nebo doplň charakterizační test pro důležitý scénář. Test zde neříká, jak má systém vypadat uvnitř, ale co musí zůstat navenek.
- Udělat nejmenší změnu Například přejmenuj výraz, vytáhni funkci nebo odstraň jednu duplicitu. Nemíchej do stejného kroku nové pravidlo ani hromadné formátování celého projektu.
- Ověřit kontrakty Spusť relevantní testy a statickou analýzu. Zkontroluj veřejné rozhraní, chybové stavy a důležité vedlejší účinky, ne jen to, že aplikace naběhne.
- Zkontrolovat a navázat Nech změnu projít review, ulož ji jako čitelný samostatný commit a až potom pokračuj dalším krokem nebo funkcí.
Co je co
Refaktoring není každá změna kódu
Pojmenování účelu změny pomáhá vybrat správné testy, velikost pull requestu i způsob nasazení.
Čistý refaktoring
Záměrně nemění pozorovatelné businessové chování. Mění strukturu, názvy, rozdělení odpovědností nebo duplicitu a musí zachovat stávající kontrakt.
Nová funkce a bugfix
Funkce přidává nové očekávané chování. Bugfix záměrně mění chování, které je chybné vůči zadání nebo kontraktu. Obě změny mohou následovat po refaktoringu, ale je lepší je oddělit.
Rewrite
Přepis nahrazuje podstatnou část implementace nebo systému. Má větší riziko skrytých rozdílů, datových migrací a provozního dopadu; několik přejmenování z něj neudělá refaktoring.
Optimalizace
Výkonová změna se opírá o měření a může měnit časování, využití paměti nebo provozní vlastnosti. Pokud zachovává funkční kontrakt, může obsahovat refaktorovací kroky, ale úspěch se měří i výkonem.
Výhody a rizika
Menší budoucí cena za nutnou disciplínu dnes
Přínosy
- čitelnější hranice a názvy pro další vývoj
- menší duplicita a menší riziko rozdílných oprav stejného pravidla
- snazší cílené testování a dohledání závislostí
- menší a srozumitelnější změny pro code review
Na co pozor
- smíchání strukturální změny s funkcí nebo bugfixem
- velký hromadný diff, který zakryje skutečnou změnu
- přesun kódu bez testu důležitého chování
- předčasné vytváření abstrakcí pro zatím neexistující potřebu
Praktické použití
Nejlepší čas je těsně před bezpečnější další změnou.
Refaktoring se často vyplatí při opakované práci ve stejné části systému. Když tým rozumí aktuálnímu chování a má aspoň základní ověření, několik malých kroků sníží riziko nadcházející funkce i budoucích oprav.
U citlivých částí, jako je platba nebo import, je vhodné postupovat ještě opatrněji: změny rozdělit, porovnat výsledky a využít Git pro dohledatelnou historii a snadný návrat. Pokud chování zatím nikdo nezná, první krok je jeho zjištění a charakterizační test, ne okamžitý přepis.
Kontrolní seznam
Jak poznat, že refaktoring zůstal bezpečný
Každá položka chrání jiný druh kontraktu. Zelený build sám o sobě nemusí zachytit změnu důležitého pravidla.
- předem vymezený strukturální problém a deklarovaný nezměněný výsledek
- relevantní existující nebo nově doplněný charakterizační test
- spuštěné testy, statická analýza a podle potřeby architektonická kontrola
- malé samostatné commity bez hromadného formátování a nesouvisejících změn
- review zaměřené na zachování kontraktu, ne jen na nový vzhled kódu
Časté otázky
Kdy změnu nazvat refaktoringem
Je oprava chyby refaktoring?
Ne sama o sobě. Bugfix záměrně mění chování z chybného na správné. Refaktoring může opravu připravit tím, že zpřehlední kód, ale funkční změna má být v review rozpoznatelná.
Musím mít před refaktoringem testy?
U důležitého chování ano, alespoň v rozsahu, který chrání daný krok. Když testy chybí, začni charakterizačním testem nebo jiným ověřením současného kontraktu.
Je přejmenování proměnné refaktoring?
Ano, pokud nezmění chování a zlepší srozumitelnost. I malá změna ale vyžaduje pozornost u veřejného API, serializovaných dat nebo konfigurace, kde název může být kontraktem.
Má být optimalizace součástí refaktoringu?
Jen pokud je jasně oddělená a změřená. Optimalizace má navíc výkonový cíl a může přinést provozní rizika; neschovávej ji do pull requestu označeného jen jako refaktoring.
Jak udržuji kód v praxi
Strukturu zlepšuji po krocích, které jde bezpečně ověřit.
Při práci kombinuji malé změny, testy a statickou kontrolu, aby další funkce nezvyšovaly zbytečné riziko v existujícím systému.