Refaktorovn Refactoring Dominik epk FJFI VUT 2019 Co
- Slides: 30
Refaktorování (Refactoring) Dominik Šepák FJFI ČVUT 2019
Co je refactoring? Refactoring (noun): a change made to the internal structure of software to make it easier to understand cheaper to modify without changing its observable behavior Zejména objektově orientované jazyky a non-real-time aplikace „Malá úprava, test, malá úprava, test, …“ Neupravujeme funkčnost, pouze tvar
Jak takový refactoring vypadá?
Proč refaktorovat? Zlepšení designu programu Odstranění duplicitního kódu Lepší srozumitelnost kódu Celkové urychlení práce na projektu
Kdy refaktorovat? Nejlépe „za běhu“ a průběžně Cíl: ulehčit přidání další funkce do programu a. Pravidlo tří – implementovat, implementovat podruhé, refaktorovat b. Je těžké přidat novou funkčnost c. Musím opravit chybu
Kdy nerefaktorovat? Téměř neopravitelný kód Reraktorovat do několika funkčních celků -> ty pak ponechat či ne Před deadlinem
Refactoring a design kódu Nepotřebuji perfektní design – stačí dostatečně dobrý Zbytek obstará refaktoring
Refactoring a výkon Refactoring může program zpomalovat X Dobře čitelný a strukturovaný program se mnohem lépe optimalizuje
Zápachy v kódu (v OOP) Konstrukce, které naznačují potřebu refactoringu Duplicitní kód Dlouhé metody Dlouhé seznamy parametrů Nahradit objektem Metoda, která „vyjídá“ jinou třídu Přesunout/rozdělit
Zápachy v kódu (v OOP) Switch Využít polymorfismus (Téměř) prázdná třída Dlouhé řetězce volání (prostředník) Třídy, které slouží výhradně jako kontejner pro data Odstranit veřejný přístup k datům Pokusit se přenést metody Komentáře snažící se zamaskovat nesrozumitelnost kódu
Jednotkové testy (unit tests) Self-checking Plně automatické Význam: vyhnout se debugování Otestovat zejména extrémní případy (netřeba otestovat úplně všechno)
Příklady Kompletní referenci lze nalézt v M. Fowler: Refactoring: Improving the Design of Existing Code
Extract method Přemění část kódu na metodu Použití: a. dlouhé metody b. řešení nesrozumitelnosti kódu 1. Vytvořit novou metodu 2. Zkopírovat kód 3. Nalézt lokální proměnné a v případě potřeby je předat jako parametr 4. Dočasné proměnné přesunout do nové metody, pokud to lze Vrátit modifikované proměnné (jako návratovou hodnotu) Pro více proměnných je potřeba metodu „rozřezat“ 5. Zkompilovat 6. Nahradit původní kód voláním metody, odstranit zbytečné dočasné proměnné 7. Zkompilovat a otestovat
Replace temp with query Přemění výraz na metodu a nahradí všechny výskyty dočasné proměnné touto metodou Cíl: odstranění dočasné proměnné Je potřeba si dávat pozor, zda do proměnné nepřiřazuji více než jednou! 1. Nalézt lokální dočasnou proměnnou, do které se přiřazuje jednou 2. Deklarovat ji jako final 3. Zkompilovat Pokud bych do této proměnné ukládal vícekrát, způsobí to chybu 4. Změnit pravou stranu přiřazení na metodu 5. Zkompilovat, otestovat 6. Nahradit výskyty proměnné metodou, po každém nahrazení otestovat, následně vymazat dočasnou proměnnou
Move Method 1. Vytvoří novou metodu s podobným tělem v třídě, jejíž data daná metoda užívá nejvíce Prozkoumat prostředky využívané původní metodou a rozhodnout se, zda je také přesunout Více metod najednou se přesouvá snadněji 2. Ověřit předky a potomky na deklarace této metody (nechci porušit polymorfismus) 3. Deklarovat metodu ve výsledné třídě 4. Překopírovat zdrojový kód a upravit ho tak, aby fungoval a. Přesunout používané metody/atributy do cílové třídy b. Vytvořit či využít referenci na zdrojovou třídu v cílové třídě c. Předat zdrojový objekt jako parametr d. Předat proměnnou jako parametr
Move Method 5. Zkompilovat 6. Prohledat zdrojovou třídu a zjistit, zda se mohu odkazovat na cílovou třídu, případně opravit (např. přidat atribut) 7. Přeměnit původní metodu na delegující metodu (pouze volá novou metodu) 8. Zkompilovat, otestovat 9. Rozhodnout o odstranění původní metody ANO: nahradit všechny výskyty novou metodou 10. Zkompilovat a otestovat
Encapsulate Field Změnit veřejný atribut na soukromý a přidat přístupové metody 1. Vytvořit getter a setter 2. Nalézt všechna použití atributu mimo třídu a nahradit getterem či setterem 3. Zkompilovat a otestovat po každé změně 4. Deklarovat atribut jako final 5. Zkompilovat a otetsovat
Move Field Atribut je/bude více využíván jinou třídou Přesune atribut do jiné třídy 1. Pokud je atribut veřejný, použít nejdřív „Encapsulate field“ 2. Zkompilovat, otestovat 3. Vytvořit atribut, setter a getter ve výsledné třídě 4. Zkompilovat 5. Promyslet, zda se jde odkazovat ze zdrojové třídy na cílovou, případně upravit kód tak, aby to šlo 6. Odstranit atribut ve zdrojové třídě 7. Zaměnit všechna použití 8. Zkompilovat, otestovat
Replace data value with object Mám atribut, co k sobě potřebuje „přibalit“ další atributy či metody Přemění atribut na objekt
Replace data value with object 1. Vytvořit třídu s daným atributem, deklarovat tento atribut jako final, přidat getter a konstruktor 2. Zkompilovat 3. Změnit typ atributu ve zdrojové třídě na novou třídu 4. Změnit getter ve zdrojové třídě tak, aby volal getter nové třídy 5. Pokud je atribut zmíněn v konstruktoru zdrojové třídy, zavolat v tomto konstruktoru konstruktor nové třídy 6. Změnit setter tak, aby vytvářel novou instanci této třídy 7. Zkompilovat, otestovat
Replace magic number with symbolic constant double potential. Energy(double mass, double height) { return mass * 9. 81 * height; } double potential. Energy(double mass, double height) { return mass * GRAVITATIONAL_CONSTANT * height; } static final double GRAVITATIONAL_CONSTANT = 9. 81;
Replace magic number with symbolic constant 1. Deklarovat konstantu a dát jí hodnotu nahrazovaného čísla 2. Najít všechny výskyty nahrazovaného čísla 3. Pokud se jedná opravdu o použití této konstanty, nahradit číslo konstantou Zkompilovat, otestovat
Decompose conditional Vytvoří z podmínky a bloků if-else metody Vhodné pro dlouhé nečitelné podmínky v if-else if (date. before (SUMMER_START) || date. after(SUMMER_END)) charge = quantity * _winter. Rate + _ winter. Service. Charge; else charge = quantity * _summer. Rate; if (not. Summer(date)) charge = winter. Charge(quantity); else charge = summer. Charge (quantity);
Decompose conditional 1. Vytvořit z podmínky metodu 2. Vytvořit z bloků if-else metody 3. Zkompilovat, otestovat
Introduce assertion Určitá část kódu implicitně předpokládá něco o programu Mnohdy je tento požadavek vyjádřen pouze v komentáři Učiní tento požadavek explicitní double get. Expense. Limit() { // should have either expense limit or a primary project return (_expense. Limit != NULL_EXPENSE) ? _expense. Limit: _primary. Project. get. Member. Expense. Limit(); } double get. Expense. Limit() { Assert. is. True(_expense. Limit != NULL_EXPENSE || _primary. Project !=null); return (_expense. Limit != NULL_EXPENSE) ? _expense. Limit: _primary. Project. get. Member. Expense. Limit(); }
Rename method Jméno metody nevypovídá o tom, co dělá Přejmenuje metodu Dnes obvykle součást IDE 1. Vytvořit novou metodu stejné signatury a jiného jména, zkopírovat kód 2. Zkompilovat 3. Změnit tělo staré metody tak, aby volala novou 4. Zkompilovat, otestovat 5. Najít všechna použití staré metody, vždy změnit, zkompilovat, otestovat 6. Zkompilovat, otestovat
Preserve whole object Posílám velké množství informací z objektu jako parametr funkce Poslat celý objekt int low = days. Temp. Range(). get. Low(); int high = days. Temp. Range(). get. High(); within. Plan = plan. within. Range(low, high); within. Plan = plan. within. Range(days. Temp. Range());
Preserve whole object 1. Vytvořit nový parametr – objekt, co se bude předávat 2. Zkompilovat, otestovat 3. Zjistit, které parametry používají daný objekt. 4. Nahradit jeden parametr voláním metod předávaného objektu 5. Odstranit tento parametr 6. Zkompilovat, otestovat 7. Zopakovat pro ostatní parametry
Děkuji za Vaši pozornost!
Zdroje FOWLER, Martin, et al. Refactoring: Improving the Design of Existing Code.
- Km fjfi
- Fjfi
- Astolfo feynman
- Refactoring: improving the design of existing code
- A survey of software refactoring
- Refactoring vs shimming
- Code refactoring
- Refactoring
- Refactoring extreme programming
- Software refactoring beratung
- Refactoring and restructuring methods
- Joshua kerievsky refactoring to patterns
- Fekt horde
- Normy vut
- Vut fch
- švaříčková fast vut
- Moodle fast vut
- Intraportal vut
- Vut model handboek voor leraren
- želví diagram
- Vut usi
- Vut-model
- Bvnt2
- Dtb vut
- Heronova fontána
- Vut usi
- Vut wiki
- Vut fit mapa
- Dtb vut
- Fast vut adresa
- Vut