**Koodi refaktoreerimine** (ingl *code refactoring*) on protsess olemasoleva lähtekoodi ümberstruktureerimiseks, muutmata koodi visuaalset käitumist. 

Refaktoreerimise tulemusel paranevad tarkvara funktsioonivälised omadused: koodi loetavus, keerukus, hallatavus ja laiendatavus. Tavaliselt tehakse refaktoreerimise käigus lähtekoodis rida väikseid muudatusi, millest ükski ei mõjuta tarkvara käitumist või vastavust funktsionaalnõuetele. Mitmed arenduskeskkonnad pakuvad tööriistu, mis aitavad levinud refaktoreerimisvõtteid automatiseerida ja rakendada.

Refaktoreerimine võib olla abiks defektide ja turvanõrkuste avastamisel, lihtsustades programmi loogikat ja kõrvaldades üleliigset keerukust.

Ülevaade
--------

Refaktoreerimine võib osutuda vajalikuks, kui avastatakse lõhnav kood. Näiteks võib vaadeldav meetod olla liiga pikk või väga sarnane mõne teise meetodiga. Selliste probleemide kõrvaldamiseks refaktoreeritakse lähtekoodi, mille käigus muudetakse koodi struktuuri nii, et see käitub samamoodi, kuid enam ei "lõhna". Refaktoreerimisega võib näiteks ühe suure meetodi jagada kaheks väiksemaks meetodiks ja korduvate koodilõikude kaotamiseks asendada kordused ühe sarnast ülesannet täitva meetodiga.

Refaktoreerimine võib parandada loodava tarkvara peamiselt kahte omadust:

1. hallatavus. Kergesti loetava koodi puhul on lihtsam defekte kõrvaldada, kuna koodi kirjutaja eesmärk on lihtsamini hoomatavam. Loetavust saab parandada näiteks suurte koodiplokkide jaotamisega väiksemateks alammeetoditeks, millel on üks konkreetne ülesanne. Samuti võib koodi loetavust parandada meetodite tõstmine sobivamasse klassi või eksitavate kommentaaride eemaldamine.
2. laiendatavus. Rakendusele lisamoodulite kirjutamine on lihtsam, kui loodud tarkvara kasutab äratuntavat disainimustrit. Refaktoreerimise tulemusel võivad avaneda võimalused laiendamiseks kohtades, kus see varem võimalikuks ei osutunud.

Enne koodilõigu refaktoreerimist peab nimetatud lõiku katma ühiktestide komplekt. Ühiktestid garanteerivad, et kood töötab ootuspäraselt enne ja pärast muudatuste tegemist. Testide puudumisel on raske eristada, kas defekt tekkis refaktoreerimise käigus või oli eelnevalt olemas.

Refaktoreerimine on sammsammuline protsess, kus iga etapi järel tehakse väikseid disainimuudatusi. Näiteks konsolideeritakse selle käigus olemasolevad ideed, eemaldatakse kasutu kood ja täpsustatakse mitmeti mõistetavused. Esmalt kontrollitakse ühiktestidele vastavust, misjärel tehakse väike muudatus ning viimaks veendutakse lahenduse korrektsuses uuesti teste käitades. Seda tegevust korratakse lõhnava koodi kõrvaldamiseni. Mitut muudatust ei soovitata vahepealse testimiseta korraga teha, kuna defekti ilmnemise järel on raske välja selgitada, millise muudatuse tulemusel viga tekkis.

Refaktoreerimise võtted
-----------------------

Siin on toodud mõned refaktoreerimise võtted. Mõned neist võivad kehtida ainult teatud programmeerimiskeelte või -tüüpide puhul. Suurema nimekirja refaktoreerimisvõtetest leiab Martin Fowleri refaktoreerimise raamatust ja kodulehelt.

* Abstraheerimise võtted:
	+ Välja kapseldamine (*Encapsulate field*) – avaliku isendivälja asendamine privaatsega, ligipääsu delegeerimine *get*- ja *set*-meetoditele
	+ Tüübi üldistamine (*Generalize type*) – meetodite kirjutamine üldisemate tüüpidega, et meetodi oleks võimalik laiemalt kasutada
	+ Tingimuslause polümorfismiga asendamine
* Koodi osadeks lahutamise võtted:
	+ Klassi ekstraheerimine (*Extract class*) – koodi viimine olemasolevast klassist uude klassi
	+ Meetodi ekstraheerimine (*Extract method*) – koodi viimine olemasolevast meetodist uude meetodi. See on rakendatav ka funktsioonide puhul.
* Koodi nimede ja asukoha parandamise võtted:
	+ Meetodi või välja liigutamine – meetodi või välja viimine sobivamasse klassi või lähtekoodi faili
	+ Meetodi või välja ümbernimetamine – nime muutmine nii, et meetodi või välja eesmärk oleks selgem
	+ Üles tõmbamine (*Pull up*) – ülemklassi liigutamine (ainult objektorienteeritud programmeerimisel rakendatav)
	+ Alla lükkamine (*Push down*) – alamklassi liigutamine (ainult OOP rakendatav)

Refaktoreerimise tööriistad
---------------------------

Mitmed arenduskeskkonnad pakuvad automatiseeritud tööriistu refaktoreerimisvõtete rakendamiseks. Näiteks võib kasutaja klõpsata muutuja nime peale ja seejärel valida refaktoreerimise menüüst "Kapselda väli". Seejärel pakub arenduskeskkond võimalusi täpsemate sätete määramiseks ning kinnitamise järel rakendab arenduskeskkond soovitud muudatused kogu koodis.

Siin on mõned automaatset refaktoreerimist pakkuvad rakendused:

* Eclipse baasil:
	+ Eclipse (ennekõike Java jaoks)
	+ Pydev (Pythoni jaoks)
	+ Photran (Fortrani jaoks, pistikprogramm Eclipse arenduskeskkonnale)
	+ Embarcadero Delphi
* InttelliJ baasil:
	+ AppCode (C, Objective C ja C++ jaoks)
	+ IntelliJ IDEA (Java jaoks)
	+ PyCharm (Pythoni jaoks)
	+ WebStorm (JavaScripti jaoks)
	+ Android Studio (Java jaoks)
	+ JDeveloper (Java jaoks)
	+ NetBeans (Java jaoks)
	+ Smalltalk (enamiku keelte jaoks)
* Visual Studio baasil:
	+ Visual Studio (.NET ja C++ jaoks)
	+ CodeRush (pistikprogramm Visual Studio jaoks)
	+ Visual Assist (pistikprogramm Visual Studio C# ja C++ jaoks)
	+ Wing IDE (Pythoni jaoks)
	+ Xcode (C ja Objective C jaoks)

Viited
------

1. 1 2 3 4 5  Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts (2012, August). *Refactoring: Improving the Design of Existing Code*. Addison-Wesley.
2. 1 2  Joshua Kerievsky (2004). *Refactoring to Patterns*. Pearson Education.
3. ↑  Robert C. Martin (2008, August). *Clean Code: A Handbook of Agile Software Craftsmanship*. Pearson Education.
4. 1 2  Martin Fowler (10.12.2013). "Catalog of Refactorings" (inglise). Vaadatud 18.03.2018.
5. ↑  Ivan Marsic (2012). *Software Engineering*.
6. ↑  Trevor Page (30.09.2012). "5 Tips to Being a Better Programmer – Refactoring Tools" (inglise). Vaadatud 25.03.2018.