Table of Contents Refaktorointi................................................................................ 1 1 Tehtävänanto............................................................................. 1 2 Johdanto................................................................................. 1 3 Refaktoroinnin taustaa...................................................................... 1 4 Menetelmä............................................................................... 2 5 Edut.................................................................................... 2 5.1 Teoria............................................................................... 2 5.2 Todellisuus.......................................................................... 2 6 Haitat................................................................................... 2 6.1 Teoria............................................................................... 2 6.2 Todellisuus.......................................................................... 3 7 Käytännön sovellutus....................................................................... 3 8 Kokemukset ja muutokset................................................................... 3 8.1 Toteutukset.......................................................................... 3 8.1.1 Toteutukset 1a ja 1b............................................................... 4 8.1.2 Toteutukset 2a ja 2b............................................................... 4 8.2 Refaktorointeja....................................................................... 4 8.2.1 StructureLoaderin kutsuminen....................................................... 4 8.2.2 Vakiot.......................................................................... 4 8.2.3 Servlettien karsiminen............................................................. 4 8.2.4 Poikkeuskäsittely................................................................. 5 8.2.5 Parametrien yhdistäminen........................................................... 5 8.2.6 Kaksinkertaisen koodin poisto....................................................... 5 8.2.7 StructureLoader................................................................... 5 8.2.8 Arkkitehtuuri..................................................................... 6 8.3 Refaktorointien vastaavuus suunnitelmiin ja sääntöihin........................................ 6 9 Yhteenveto............................................................................... 6 10 Viitteet................................................................................. 7
1 (7) Refaktorointi Autere Aleksi, 57412R Welin Jan, 49620N Versiohistoria Versio Pvm Tekijä Kuvaus 0.1 04.12.2005 AA & 0.2 05.12.2005 AA & 0.3 05.12.2005 AA & 0.4 19.02.2006 AA & Ensimmäinen versio Toinen versio Vain pieniä muutoksia 0.5 20.02.2006 Omat osuudet 0.6 22.02.2006 AA Omat osuudet 0.7 25.02.2006 AA & Muistiinpanot ja tehtävienjako Yhteenveto, oikoluku ja tarkistus 1 Tehtävänanto Refactoring means improvement of source code without adding any functionality. The purpose of refactoring is to guard the code against decay that is typical to any software developed for a longer time. Assignment: Plan how and when you will do refactoring, and how you decide when refactoring is necessary, e.g., based on the occurrence of bad code smells. [Fowler and Beck] 2 Johdanto Valitsimme refaktoroinnin SEPA aiheeksi koska projektissamme tultaisiin joka tapauksessa käyttämään ko. tekniikkaa, koska otimme käyttöön kesken projektin evolutiivisen kehityksen ja yksinkertaisen suunnittelun ja refaktoroinnin. Tekniikka on suurimmalle osalle projektilaisista uusi, tosin muutamat ryhmän jäsenet ovat käyttäneet refaktorointia järjestelmällisesti myös aikaisemmissa projekteissasaan. Legend: - BL - Businesslogiikka - DAO - Data Access Object, oliot joita tietokannan ja BL:n välillä vaihdetaan - XP - extreme Programming, ketterä ohjelmistokehitys metodologia 3 Refaktoroinnin taustaa Refaktorointi (eng. refactoring) tarkoittaa suomeksi tekijöihin jakamista uudelleen eli tekijöiden yhdistämistä, mutta tietotekniikassa puhuttaessa tarkoitetaan lähdekoodin rakenteen muokkaamista siten että ohjelman tominnallisuus ei muutu. Tarkoituksena on saada koodista selkeämpää ja ymmärrettävämpää. Tekniikan tutkimus ja systemaattinen
2 (7) käyttö on melko uutta ohjelmistotuotannossa. Näkemyksiä refaktoroinnista näyttää olevan monia, aina DO-NOT-FIX-IT-IF-IT-IS-WORKING näkemyksestä "refaktoroi kunnes ei ole enää refaktoroitavaa" ideologiaan. Huomattavaa on että refaktorointia tapahtuu jokaisessa ohjelmistokehtiysprojektissa vaikka tekniikkaa ei systemaattisesti tai tiedostaen käytettäisi. Armoton refaktorointi (engl. Refactor Mercilessly) on yksi XP-metodologian menetelmä, joka lähtee ajatuksesta "Refactor whenever and wherever possible.". / 1/, /4/ 4 Menetelmä Refaktorointia voidaan tehdä usealla eri tasolla. Alimmalla tasolla refaktoroitaessa toimitaan yksittäisten luokkien sisällä. Tällöin voidaan esimerkiksi vaihtaa muuttujien nimiä kuvaavimmiksi tai pilkkoa metodeja pienempiin kokonaisuuksiin jne. Seuraavalla tasolla, eli luokkatasolla refaktorointi tarkoittaa arkkitehtuurin selkeyttämistä luokkarakennetta muokkaamalla. Esimerkkejä luokkatason refaktoroinnista ovat luokkien yhdistäminen tai pilkkominen tarvittaessa mikäli luokissa on liikaa tai liian vähän toiminnallisuutta. Ylimmän tason refaktorointi koskee pakettirakennetta. Luokkia voidaan jakaa selkeämpään hierarkiaan niiden ominaisuuksien mukaan. Refaktorointi sekoitetaan monesti virheellisesti koodin uudelleenkirjoittamiseen. Tästä ei kuitenkaan ole varsinaisesti kysymys, vaan refaktorointi on koodin rakenteen muokkaamista. Refaktorointia tulisi tehdä ohjelmoinnin yhteydessä, eli ohjelmoijan pitäisi miettiä jatkuvasti tuottamaansa koodia ja parannella sitä vastaamaan hyviä ohjelmointikäytäntöjä. Monissa tapauksissa myös muut ohjelmoijat voivat refaktoroida toistensa koodia. Erityisesti tätä on rohkaistu tekemään XP-ohjelmointikäytännössä. Yleisesti tulisi välttää kerralla tehtäviä laajoja refaktorointeja, koska virheiden mahdollisuus kasvaa ja on mahdollista tehdä vaikeasti peruutettavia virheellisiä toimenpiteitä. Yksi tapa välttää virheitä laajaa refaktorointia tehtäessä, on ottaa refaktorointia varten kopio tarvittavasta koodista ja tehdä refaktorointi kopiolle. Tämän jälkeen muutokset tuodaan alkuperäiseen koodiin pienemmissä osissa. Jokaisen muutoksen jälkeen testataan toimivuus. /3/ 5 Edut 5.1 Teoria Tässä kappaleessa on pyritty miettimään menetelmän tuomia etuja. Etuja ovat ainakin: - Koodin ymmärettävyys ja ylläpidettävyys paranee. - Refaktoroidusta koodista saattaa olla helpompi löytää virheitä. 5.2 Todellisuus Huomasimme tietenkin, että koodin ymmärrettävyys ja ylläpidettävyys paranee, kun siitä refaktoroidaan bad-code-smellien perusteella. Sen sijaan virheiden helpompaa havaittavuutta refaktoroidusta koodista emme käytännössä huomanneet. Sen sijaan refaktoroinnin aikana koodin rakennetta tulee mietittyä uudelleen ja kyseenalaistettua aikaisemmin tehtyjä ratkaisuja. Siinä mielessä refaktoroinnin aikana löytyi kyllä virheitä. Lisäksi huomasimme, että oli kätevää projektin edistymisen kannalta, että saatiin toimivaa koodia aikaiseksi ilman, että tarvitsi pyrkiä täydellisyyteen. 6 Haitat 6.1 Teoria
3 (7) Tässä kappaleessa on pyritty miettimään menetelmän mahdollisia haittoja. - Refaktoroimalla on mahdollista rikkoa ohjelman toimivuus. - Refaktorointi on työtä, joka ei varsinaisesti näy lopputuotteessa, eli käännetyssä ohjelmassa. - Refaktorointi saattaa sekoittaa "liian suurissa annoksissa" muiden projektilaisten käsitystä koodin rakenteesta. Ja aiheuttaa näin lisätyötä. - Jos refaktorointiin käyttää väärään aikaan liikaa resursseja, saattaa käsillä oleva työtehtävä kärsiä. - Jos refaktoroinnin jälkeen ei suoriteta regressiotestausta on vaarana että systeemi menee rikki. /2/, 6.2 Todellisuus Projektissa huomattiin että refaktorointi on todella hyödyllinen työkalu, mutta refaktorointia tulisi käyttää harkiten ja suunnitellusti. Refaktoroinnin suunnittelun tarpeellisuus oli se joka yllätti hieman. Jotta lopputulos olisi hyödyllisempi kuin refaktoroimaton koodi suunnittelu on tosissaan tarpeellista, huomasimme että vain ryhtymällä toimeen lopputulos on kutakuinkin samaa tasoa kuin lähtökohta. Esimerkiksi refaktorointi isoissa määrin osoittautui käytännössä mahdottomaksi, vaihtoehtona olisi ollut ottaa vain osa järjestelmästä huomioon jolloin vaikutukset kokonaisuuteen olisi jäänyt tuntemattomaksi. Tästä syystä StructureLoaderin refaktoroinnin viimeistely jouduttiin hylkäämään, aikaa ei olisi riittänyt enää lopuksi. Käytännössä jokainen edellisessä Teoria-kappaleessa mainittu kohta piti paikkansa projektissamme. Hyvä että nämä asiat olivat tiedossa. 7 Käytännön sovellutus Projektin kaikki ohjelmakoodi kirjoitetaan Eclipseä käyttäen. Eclipse tukee monia tyypillisimpiä refaktorointeja helpottaen niiden tekemistä huomattavasti. Esimerkiksi muuttujan tai metodin nimeä muutettaessa Eclipse korjaa kaikki projektissa esiintyvät viittaukset automaattisesti. Lisäksi metodien ja instanssimuuttujien siirtely perittävältä luokalta perijälle tai toiseen suuntaan onnistuu Eclipsen avustamana helposti. Myös muihin siirtoihin, kuten metodien siirtoon luokkien välillä ja luokkien siirtoon pakettien välillä löytyy Eclipsestä automatiikkaa. Refaktorointia kasittelevällä wiki-sivustolla /5/ esitellään tiettyjä refaktorointikäytäntöjä, joista käytämme ainakin seuraavia: - The First Refactoring Step Ennen refaktorointia tulee olla toimivat yksikkötestit valmiina muutettaville luokille. Tällä tavoin voidaan varmistua siitä, ettei refaktorointi aiheuta uusia virheitä. - Bodyguard Pattern Mikäli virheitä kuitenkin syntyy, varmistutaan siitä, että voidaan palata refaktorointia edeltävään tilanteeseen. Taaksepäin palaaminen on helppoa CVS-versionhallintaa käyttäen. - Refactoring In Very Small Steps Refaktorointi suoritetaan aina mahdollisimman pienissä erissä, ja testataan koodin toimivuus jokaisen refaktoroinnin jälkeen. Suuriin muutoksiin syntyy helpommin virheitä, ja virheiden löytäminen suuresta massasta on vaikeampaa kuin pienestä. 8 Kokemukset ja muutokset 8.1 Toteutukset Toteukset 1 ja 2 jaettiin ensimmäisen iteraation alussa alitoteutuksiin 1a, 1b, 2a ja 2b.
4 (7) 8.1.1 Toteutukset 1a ja 1b Käytännössä systemaattista refaktorointia ei ensimmäisen a-iteraation aikana tapahtunut. Syynä tähän oli aikataulun venyminen kuten projektisuunnitelmasta käy ilmi. 1b-vaiheessa "refaktorointia" kuitenkin käytettiin lähes aina kun koodia tuotettiin tai muokattiin. Lienee kuitekin oikeaoppisempaa puhua jollain muulla termillä tästä iteratiivisesta koodin kehityksestä kuin termillä refaktorointi, koska koodi/luokkarakenne muuttui niin usein. 8.1.2 Toteutukset 2a ja 2b Iteraatioissa 2a ja 2b koodia syntyi huomattavasti nopeammalla vauhdilla 1a- ja 1b-iteraatioihin verrattuna. Lisäksi ohjelmointityöllä oli erittäin kiire. Nämä tekijät yhdessä vaikuttivat siihen, että ohjelmakoodista oli selvästi tunnistettavissa ongelmakohtia, jotka kaipasivat refaktorointia. Usein ongelmakohtia ei tarvinnut edes systemaattisesti etsiä, vaan ne hyppivät silmille etsimättäkin. Välillä huonoa koodia tuotettiin jopa siinä mielessä tarkoituksella, että uuden toiminnallisuuden tuottaminen nopeasti oli tärkeämpää kuin ohjelmakoodin oikeaoppisuus. Tästä hyvänä esimerkkinä oli poikkeuskäsittelyn epäyhtenäinen toteutus alussa, joka refaktoroitiin loppuvaiheessa yhtenäiseksi. Refaktorointia tehtiin määrällisesti eniten 2b iteraation aikana loppua kohti enenevissä määrin. Yksittäinen suurin refaktorointi oli arkkitehtuurin järjestely uudestaan aivan 2a iteraation alussa. Refaktorointeja suorittivat arkkitehti, kaikki kehittäjät ja testaaja. Kaiken kaikkiaan projektin aikana refaktoroitiin lähes joka toista luokkaa. 8.2 Refaktorointeja Alla on kuvattu joitain tehtyjä refaktorointeja. 8.2.1 StructureLoaderin kutsuminen StructureLoader on luokka, joka vastaa hierarkisen aluerakenteen rakentamisesta tietokannasta noudettujen tietojen mukaiseksi. Aluerakennetta tarvitaan sekä dynaamisen javascriptin luomiseen, että hierarkisen html-hakupuun luomiseen. Nämä ovat toisistaan riippumattomia tehtäviä, joita voidaan kutsua erikseen, joten ne myös kumpikin kutsuivat StructureLoaderia toisistaan riipumatta erikseen. Rakenteen luominen on kuitenkin varsin raskasta, sillä se aiheuttaa lukuisia tietokantakyselyjä. Tämän vuoksi päätettiin ladata rakenne vain kerran ja tallentaa rakenneolio sessioon, josta se voidaan tarvittaessa hakea. Tämän refaktoroinnin suoritti Aleksi ja Jani, eikä toteutuksessa törmätty ongelmiin. Eclipse ei tässä tapauksessa tarjonnut mitään hyödyllisiä aputoimintoja. Refaktorointi vaikutti kahteen luokkaan, jotka olivat pääkäyttöliittymän lataava servletti sekä hakupuun lataava servletti. 8.2.2 Vakiot COTOOL on Rauinfoon myöhemmin integroitava lisäominaisuus, ja alusta asti oli tiedossa, ettei integrointia tulla suorittamaan projektin aikana. Tämän vuoksi saatoimme asettaa vakioiksi tiettyjä arvoja, jotka Rauinfo-integroinnin jälkeen olisivat Rauinfon asettamia muuttujia. Alusta asti ei kuitenkaan ollut yhtenäistä käytäntöä eri vakioille. Tästä syystä vakioita oli luokissa siellä sun täällä, sekä jopa kovakoodattuina metodikutsuissa. Vakiot eriytettiin omaan luokkaansa 2a-iteraation alussa. Refaktoroijana oli pääasiassa Kimmo. Tämän refaktoroinnin jälkeen myös uusille vakioille oli luonnollinen paikka, eikä rumia kovakoodauksia enää ilmestynytkään. 8.2.3 Servlettien karsiminen
5 (7) COTOOL:n arkkitehtuuri suunniteltiin siten, että servletteihin tulisi mahdollisimman vähän logiikkaa - niiden tarkoitus on vain välittää businesslogiikan tuottamaa dataa JSP-sivuille. Sen takia alussa käytetty dynaamisen Javascriptin palauttava GetJavascript-servletti todettiin turhaksi, koska sen tehtävänä oli vain IEJavascriptLoaderin muodostaman merkkijonon tulostaminen HTTP-streamiin. Servlettien karsintaan vaikuttaneet bad code smellit olivat "duplicate code" sekä "shotgun surgery", sillä kaikki servletit olivat hyvin samanlaisia. Dynaaminen Javascript yhdistettiin suoraan pääkäyttöliittymän servletin kautta HTML-koodiin. Myös tämän refaktoroinnin suoritti Kimmo 2a-iteraation alussa. Aivan projektin lopussa saimme asiakkaan oman toteutuksen SVG-kuvien lataamisesta tietokantaan. Tätä myötä siirryimme käyttämään myös Rauinfon omaa download-komponenttia, joka palauttaa kuvan URL-parametrina annetun kuva-id:n perusteella. Tämä muutos vaati uuden tietokantametodin luomista, jotta kuvanlatausservletille saatiin välitettyä halutun kuvan id HTML:n läpi, sillä vanhassa servletissä oikea kuva valittiin rakennuksen id:n perusteella. 8.2.4 Poikkeuskäsittely Projektin alkuvaiheessa käytettiin CotoolExceptionia yleisesti lähes kaikissa poikkeustilanteissa. Rauinfon käytäntö on valuttaa poikkeukset servleteille asti ja kirjoittaa virhesanoma lokiin sekä näyttää käyttäjälle ylimalkaisempi virheilmoitus. Asiakkaan kanssa todettiin, ettei Cotoolin omaan poikkeusluokkaan ole mitään tarvetta, vaan RauinfoException ja RauinfoDbException riittävät täydellisesti tarpeisiimme. Oman poikkeusluokan käyttäminen aiheutti "shotgun surgery smellin". CotoolExceptionien refaktoroinnin Rauinfon exceptioneiksi suoritti Matti. Tässä refaktoroinnissa ei ollut kyse pelkästään viittausten muuttamisesta, vaan koodi vaati paikoin laajempaakin uudelleen strukturointia, sillä poikkeuskäsittelyn yhdenmukaisuus oli kärsinyt kovassa kiireessä, ja monesti kehittäjien tavoitteena oli ollut saada vain koodi kääntymään välittämättä poikkeuskäsittelyn konsistenssista. Poikkeuskäsittelyn refaktorointi kosketti 33 tiedostoa ja vei aikaa noin kahdeksan tuntia. Pääosin tehtävä suoritettiin käyttäen Eclipsen rename-toimintoa, ja loput tarkistukset ja siivoukset tehtiin käsin ja search/replace-toiminnolla. 8.2.5 Parametrien yhdistäminen BL-luokissa sekä tietokantarajapinnassa käytettiin aluksi vain muutamaa argumenttia metodeissa. Järjestelmän kehittyessä ja toiminnallisuuden lisääntyessä metodien argumenttien määrä moninkertaistui nopeasti. Tässä vaiheessa oli tarve miettiä ongelmalle ratkaisu. Päätettiin että luodaan Parameters-luokka johon laitetaan argumentit jotka ovat käytössä näissä metodeissa. Tämän jälkeen lähes jokainen metodi saa parametrikseen Parameters-luokan instanssin ja käyttää tästä vain niitä kenttiä joita tarvitsee. Tietysti tälläkin päätöksellä oli kauaskantoisia vaikutuksia. Esimerkiksi tarkistusten määrä lisääntyi, tarpeesta tarkistaa onko tiettyjä kenttiä asetettu parametreissä. Kaiken kaikkiaan parametrien yhdistäminen selkeytti BL-kerroksen ja tietokantarajapinnan toimintaa ja nopeutti kehitystyötä, mutta toisaalta lisäsi hieman yksikkötestien määrää, kun testattavia variaatioita tuli hieman lisää. 8.2.6 Kaksinkertaisen koodin poisto Koska ensimmäisen iteraation jälkeen oltiin jäljessä tavoitteista oli toisen iteraation alussa tärkeämpää saada jotain näkyvää aikaiseksi. Usein tämä tapahtui suunnittelun kustannuksella. Kaksinkertaista koodia oli tässä tapauksessa järkevämpää vain tehdä ja luottaa siihen että lopuksi voidaan koodit lajitella uudelleen. Device-luokan metodi hasmeasurement(string) on yksi esimerkki refaktoroidusta kaksinkertaisesta koodista. Metodi palauttaa totuusarvon liittyen siihen onko laitteella annetun tyyppistä mittaustulosta. Ennen refaktorointia koodia oli kahdessa metodissa yhteensä 30 riviä. Refaktoroinnin jälkeen ko. metodi käytti jo olemassa olevaa metodia hyväksi jolloin koodin määrä laski 20 riviin. Lisäksi koodin luettavuus ja ylläpidettävyys paranivat. 8.2.7 StructureLoader Kahdella viimeisellä viikolla oli tarkoitus tehdä viimeiset silaukset koodille sekä refaktoroida viimeisimmät koodit. Kuitenkin ylläpitokäyttöliittymä vei enemmän resursseja kuin olimme suunnitelleet. Tämän johdosta StructureLoaderiin (SL) suunniteltu iso refaktorointi jouduttiin jättämään tekemättä.
6 (7) SL-luokassa rakennetaan Javascriptiä varten näytettävä alue alialueineen sekä liitetään jokaiseen (ali)alueeseen niiden laitteet sekä virtuaaliset laitteet (laitteet jotka ovat alialueiden "varjoja"). Tällä hetkellä SL:n metodi getarea(parameters) on todella pitkä ja ulottaa lonkeronsa melko pitkälle muiden bean-luokkien syövereihin (Message Chains). Toinen ongelma metodin kanssa on sen if-lauseviidakko (Switch Statements, mutta if-lauseilla toteutettuna). Tällä hetkellä if-lauseita ei ole kuin yksi haara jossa tarkistetaan onko laitteen tyyppi lämpötilamittari. Mutta koska tiedettyjä eri mittarityyppejä on n. 20 ja näillä tällä hetkellä jokaisen mittarityypin 3-4 eri mittausdatatyyppiä käydään läpi jokaiselle mittarityypille erikseen. Jokainen mittausdatatyypin tarkistus vie n. 30 riviä koodia, nopeasti laskettuna tällä tavalla saataisiin yli 2000 riviä lähes identtistä koodia! Refaktoroinnille olisi siis todellakin tilausta, kutenkin tehtävän laajuus suunnitteluineen - kaikkineen on valitettavasti liian laaja jotta sitä enää oltaisiin projektin lopuksi voitu totetuttaa. Tulevaisuudessa olisikin siis tärkeää saada jaettua SL:n ko. metodin tehtävien vastuuta jaettua hieman uudelleen (ei pitkiä lonkeroita) sekä switch-lauseen korvaaminen oliomalliin sopivalla rakenteella. 8.2.8 Arkkitehtuuri Ensimmäisen iteraation lopuksi tehdyn roolivaihdoksen jälkeen uusi arkkitehti Kimmo joutui suunnittelemaan arkkitehtuuria uudestaan, jotta ensimmäisen iteraation aikana tehdyt valinnat saataisiin yhtenäistettyä ja turvattua tuleva kehitystyö. Lisäksi DAO-luokan metodit olivat kasvaneet ja monimutkaistuneet ensimmäisen iteraation aikana ilman että muutoksia oli juurikaan suunniteltu, toisin sanoen ne olivat vain kasaantuneet. Tämän jälkeen arkkitehti teki päätöksen DAO:n yksinkertaistaistamisesta. Käytännössä yksinkertaistaminen tarkoitti logiikan siirtämistä DAO:sta BL:aan, jonne jouduttiin suunnittelemaan uusi arkkitehtuuri toiminnallisuuden säilyttämiseksi. Tämä refaktorointi oli koko projektin suurin niin ajallisesti kuin laajuudellisesti. Koko prosessiin meni n. neljä työpäivää, pelkästään refaktoroinnin suunnitteluun ja toteutukseen jouduttiin käyttämään aikaa kaksi työpäivää, toiset kaksi päivää menivät uusien toiminnallisuuksien suunnitteluun. Työkaluna refaktoroinnissa käytettiin Eclipseä, Borland Together Architect 2006:aa sekä kynää ja paperia. Eclipsellä hoidettiin verrattaen pienet muutokset kuten metodien siirrot ja uudelleen nimeämiset. Togetheriä, kynää ja paperia käytettiin lähinnä refaktoroinnin suunnitteluun vaikka mahdollisuus olisi ollut vaikka generoida koodia automaattisesti Togetherillä. Koska refaktorointi tehtiin vaiheessa jossa toteutusta ei kovin paljoa oltu tehty verrattuna lopulliseen toiminnallisuuden määrään, vaikutti tehty refaktorointi suureen osaa koodista, mutta vain kouralliseen luokkia. Tämä refaktorointi oli projektia ajatellen hyvin tärkeä, jopa pakollinen jotta projekti olisi pysynyt hanskassa. Tämä refaktorointi olisi varmasti suoritettu ilmankin SEPA-aihetta niin välttämätön tämä refaktorointi oli. 8.3 Refaktorointien vastaavuus suunnitelmiin ja sääntöihin Käytännössä kaikki refaktoroinnit noudattivat alussa valittuja menetelmä tapoja ks. kappale Toteutukset 2a ja 2b. Yksikkötestit oli kaikista refaltoroiduista tapauksista, eräissä yksittäisissä tapauksissa lisättiin muutama yksikkötesti jotta saatiin refaktorointi katetuksi. Toista sääntöä ei koskaan tarvinnut käyttää, koska jokainen tehty refaktorointi tehtiin niin pienin askelin ettei mitään mennyt huomattavasti rikki. Kolmas sääntö oli tuli tehdessä kuin itsestään, refaktorointi suurissa määrin projektilaisten kokemuksella ei vain käytännössä ollut mahdollista. 9 Yhteenveto
7 (7) Refaktoroinnin vaikutus servletteihin projektin lopussa Projektin aikana tuli selväksi että refaktorointi on välttämätöntä projektin edetessä. Refaktorointi parantaa oikein toteutettuna oikeasti koodin ymmärrettävyyttä. Se vaatii tosin ennalta suunnittelua ja järjestelmällisyyttä. Muuten projektin lopulla päädytään liian suuriin muutoksiin yhdellä kertaa, joka aiheuttaa kiusauksen jättää refaktorointi pois tai aiheuttaa koodin rikkoontumisen ja vaikean korjausprosessin. Vaikka refaktorointi oli tiedostettua ja suunniteltua tässä projektissa olisi käytännössä ollut hyödyllisempää jos refaktorointi olisi ollut vieläkin tiukemmin kontrolloitua. Tällöin refaktorointia olisi tullut tehtyä vielä tiuhemmin joka puolestaan olisi vähentänyt refaktoroinnin tarvetta projektin lopulla. Lisäksi refaktorointi pienissä määrin on kokemustemme mukaan hyödyllisempää kuin suurissa määrin yhdellä kertaa toteutettuna. Totuus on että refaktoroinninkin osalla aika ja resurssit loppuivat projektissa kesken. Yksi refaktoroinnin suunnittelua hankaloittanut asia oli järjestelmän tulevaisuuden epävarmuus. Koska asiakas ei ollut projektin aikana missään vaiheessa oikein varma tarpeistaan liian moni asia jouduttiin vain tekemään panostamatta asiaan enempää, luottaen siihen että myöhemmin tämäkin asia voidaan refaktoroida ja uudelleen suunnitella paremmin. 10 Viitteet Kaikki internet-viittaukset avautuvat uuteen ikkunaan. 1. http://www.extremeprogramming.org/rules/refactor.html 2. http://www.refactoring.com/ 3. http://c2.com/cgi/wiki?whatisrefactoring 4. http://en.wikipedia.org/wiki/refactoring 5. http://c2.com/cgi/wiki?refactoringpatterns