Minna Hillebrand Verkkosovellusten uudistaminen Tietotekniikan pro gradu -tutkielma 11. joulukuuta 2003 Jyväskylän yliopisto Tietotekniikan laitos Jyväskylä
Tekijä: Minna Hillebrand Yhteystiedot: mmhilleb@mit.jyu.fi Työn nimi: Verkkosovellusten uudistaminen Title in English: Webware Reengineering Työ: Tietotekniikan pro gradu -tutkielma Sivumäärä: 92 Tiivistelmä: Tietokonesovellusten on kehityttävä jotta ne pysyisivät käyttökelpoisina. Lähdekoodiin tehdyt muokkaukset kuitenkin rapauttavat sovelluksen rakennetta hankaloittaen uusien muutosten tekemistä. Uudistaminen on keino rapautuneen rakenteen eheyttämiseksi. Joitain yleisiä metodeja ja työkaluja on kehitetty perinteisten ohjelmien uudistamisprosessin tueksi. Yhä suurempi osa nykypäivän sovelluksista on kuitenkin integroitu tietoverkkoon. Perinteiset uudistamisen keinot eivät yleensä riitä verkkosovelluksille, jotka luonnostaan kehittyvät nopeasti ja jatkuvasti. Tässä työssä kartoitetaan perinteisten sovellusten uudistamismallien ja erityisesti uudelleenrakentamisen menetelmien soveltamismahdollisuuksia dynaamisissa verkkosovelluksissa. Sovelluskohteeksi on valittu osia Jyväskylän yliopistossa käytetystä WWW-pohjaisesta opintotietojärjestelmästä. English abstract: All computer programs must evolve in order to stay vital. However, when the source code of the system is modified, the changes eventually corrupt the designed structure of the software. As the structure declines, further changes become even more difficult. These corruptions can be straightened by reengineering the software. Some methods and tools exist to help the reengineering process of legacy systems. The problem is that most new programs are implemented on web and these webwares differ from legacy systems in many ways. In this thesis some of the basic reengineering methods of the legacy systems are adapted to support the maintenance of a web-based course management system used in the University of Jyväskylä. Avainsanat: uudistaminen, uudelleenrakentaminen, verkkosovellus, JSP, Java Keywords: reengineering, refactoring, webware, JSP, Java
Sisältö 1 Johdanto 1 2 Termejä 3 2.1 Uudistamiseen liittyviä termejä...................... 3 2.2 WWW-tekniikoihin liittyviä termejä................... 4 2.3 Esimerkkisovelluksen toteutustekniikan termejä............ 6 3 Uudistamisen merkitys 7 3.1 Uudistamisesta käsitteenä......................... 8 3.2 Uudistamisen välttämättömyydestä................... 9 3.3 Uudistamisen riskit............................. 10 3.4 Uudistamisen etuja............................. 12 3.5 Uudistamisen suhteesta ylläpitoon.................... 12 3.6 Rapautumisen ennaltaehkäisy....................... 15 4 Uudistamismenetelmiä 16 4.1 Prosessikaavio................................ 16 4.2 Yht äkkinen uudistaminen......................... 17 4.3 Vähittäinen uudistaminen......................... 18 4.4 Uudistamismalleista............................ 19 4.5 Takaisinmallinnuksen vaihe........................ 20 4.6 Muokkaamisvaihe............................. 21 4.7 Muutosten toteutus kooditasolla..................... 23 5 Arkkitehtuurin uudistaminen 25 5.1 Rakenteen visualisointi........................... 25 5.2 Konkreettisen mallin muodostaminen.................. 27 5.3 Mallien käyttö uudistamisessa...................... 29 5.4 Olioarkkitehtuuriksi muuntaminen.................... 30 6 Verkkosovellukset erityisalana 33 6.1 Verkkosovellusten toimintaympäristö.................. 34 6.2 Yhtäläisyyksiä ja eroja perinteiseen ohjelmaan............. 35 i
6.3 Tiedon ja rakenteen suhteesta....................... 37 6.4 Verkkosovellusten kehittämisestä..................... 38 6.5 Verkkosovellusten uudistaminen..................... 40 6.6 Uudistamismenetelmien käytöstä..................... 42 6.7 Näkökulmia rakenteen hahmottamiseen................. 43 6.8 Ennaltaehkäisy............................... 45 7 Korppi uudistamiskohteena 46 7.1 Soveltuvuus uudistamiskohteeksi.................... 47 7.2 Korpin ylläpidon muodot......................... 47 7.3 Kehitystyön aloittamisen ongelmia.................... 48 7.4 Kehitysympäristön ja -tekniikoiden ongelmia.............. 49 7.5 Rakenteessa havaitut ongelmakohdat.................. 51 7.6 Piilevien ongelmakohtien kartoittaminen................ 52 7.7 Uudistamiskohteiden valinta....................... 54 8 Sivujen alustustoimien siistiminen 55 8.1 Alustustoimien kapselointi tiedostoon.................. 56 8.2 Erillisen tiedoston etuja ja ongelmia................... 59 8.3 Oliopohjaiseksi toiminnaksi muuntaminen............... 61 8.4 Yksinkertaistaminen ja optimoinnit.................... 62 8.5 Parametrien välittämisen kapselointi................... 65 8.6 Uudistettu rakenne............................. 67 9 Navigointipuun muokkaaminen 70 9.1 Navigointipuun ongelmakohdat..................... 70 9.2 Uusi luokkajako............................... 72 9.3 Puun haarojen oliointi........................... 75 9.4 Parannusten ja menetysten vertailu.................... 78 9.5 Suorituskyvyn muutokset......................... 79 10 Kokemuksia uudistamisesta 80 10.1 Kokemuksia muista projekteista..................... 80 10.2 Muokkaustoimien suhde perinteisiin menetelmiin........... 81 10.3 Korpin uudistamisprosessissa esiintyneitä ongelmia.......... 83 10.4 Korpin uudistamisen vaikutuksista.................... 83 10.5 Seuraavat uudistamisprosessit...................... 84 ii
11 Yhteenveto 85 12 Kirjallisuutta 87 iii
1 Johdanto Tietokoneohjelman elinkaari on perinteisesti kuvattu nelivaiheisena prosessina, jonka vaiheet ovat suunnittelu, toteutus, testaus ja käyttöönotto. Ohjelman elinkaaresta on kuitenkin tunnistettu myös viides vaihe, ylläpito, jonka osuus ohjelman elinajasta on usein kaikkein suurin. Ylläpidon tehtävänä ei ole pelkästään korjata ohjelmasta löytyneitä virheitä, sillä usein vasta käyttöönoton jälkeen huomataan, että ohjelmaan halutaankin lisää toiminnallisia ominaisuuksia. Ohjelman toimintaa tai sen käyttämiä algoritmeja voidaan joutua optimoimaan. Myös ohjelmassa käytetty tietorakenne voidaan havaita puutteelliseksi. Useimpia ohjelmia voidaan ylläpitää jonkin aikaa niiden valmistumisen jälkeen. Hyvin suunniteltu ohjelma voi kestää laajojakin muokkauksia pysyen luettavana, muokattavana ja alkuperäisen arkkitehtuurinsa mukaisena. Ohjelman sisäinen rakenne kuitenkin kärsii muutoksista ja lähdekoodin toistuvat muokkaukset alkavat rapauttaa ohjelman rakennetta. Ennen pitkää päädytään tilanteeseen, jolloin valtaosa ylläpitoon käytettävästä ajasta kuluu ohjelman rakenteen tutkimiseen: mille koodiriveille muutokset tulisi tehdä ja minne muutokset vaikuttavat. Rapautumista voidaan kuitenkin ehkäistä, ja jo rapautuneen ohjelman rakennetta voidaan parantaa olemassa olevaa sovellusta muokkaamalla. Prosessilla on useita nimiä, muun muassa uudelleenkonstruointi, uudistaminen ja uudelleenmuokkaus (reengineering). Tässä työssä prosessille käytetään pääasiassa termiä uudistaminen. Ohjelman uudistamisella pyritään siihen, että jatkossa ohjelman kanssa olisi helpompi työskennellä. Uudistamista on tutkittu aktiivisesti lähes 20 vuoden ajan ja uudistamisprosessin tueksi on kehitetty joitakin toimintamalleja ja työkaluja. Kuluneena aikana sovellusten luonne on kuitenkin muuttunut. Aikaisemmin sovellukset suunniteltiin yhden käyttäjän käyttöön, pääasiassa yhdessä työasemassa ajettaviksi. Sovelluksen ylläpito koostui lähinnä toiminnan täydellistämisestä johtuvista muutosvaatimuksista. Nykyään valtaosa järjestelmistä on jollain tasolla yhdessä toimivia tuotteita, jotka kommunikoivat keskenään tietoverkon välityksellä. Monet sovellukset sijaitsevat fyysisesti käyttäjän työaseman ulkopuolella, jolloin käyttäjän työasema esittää vain sovelluksen käyttöliittymän. Koska tietoverkossa sijaitsevien ohjelmien osuus kasvaa jatkuvasti, tämän työn tarkoituksena on keskittyä uudistamiseen verkkosovellusten näkökulmasta. Työssä kartoitetaan verkkosovellusten eroja perinteiseen ohjelmaan nähden sekä pohdi- 1
taan, millä tavoin sovellettuna perinteisten ohjelmien uudistamisprosesseja voidaan hyödyntää verkkosovellusten uudistamiseen. Aiheesta ei ole juurikaan tutkimustuloksia, sillä useimmat tutkimukset ovat keskittyneet staattisten WWW-sivustojen uudistamiseen ja niiden käänteistekniikoihin. Tässä työssä näytetään esimerkkisovellusta uudistamalla, kuinka perinteisiä menetelmiä voidaan soveltaa dynaamisten verkkosovellusten uudistamiseen ja millaisia sovellusalan ongelmia tällöin kohdataan. Työn seuraaminen edellyttää olio-ohjelmoinnin perustietojen hallintaa. WWWtekniikoiden tunteminen helpottaa huomattavasti työn loppuosan ymmärtämistä. Lukuun 2 on koottu tässä työssä käytettyjä uudistamiseen ja WWW-ohjelmointiin liittyviä termejä. Luvussa 3 esitetään tarkemmin uudistamista käsitteenä sekä perustellaan uudistamisen merkitys oleellisena osana ohjelmiston kehittymistä. Luvussa 4 esitetään perinteisille ohjelmille kehitettyjä uudistamismenetelmiä ja -malleja. Näihin läheisesti liittyvän ohjelman rakenteen kartoittamis- ja uudistamismenetelmiä kuvataan luvussa 5. Verkko- ja perinteisen sovelluksen eroja vertaillaan luvussa 6. Samassa luvussa esitetään myös yleisiä keinoja dynaamisen verkkosovelluksen uudistamisprosessin käynnistämiseen ja sovelluksen rakenteen hahmottamiseen. Luvussa 7 esitellään esimerkkinä käytetty WWW-pohjainen Korppi-sovellus, kartoitetaan sen kehittämisen ongelmia ja etsitään potentiaalisia uudistamiskohteita. Tämän jälkeen Korppi-sovelluksen osille tehdään kaksi uudistusta: luvussa 8 kapseloidaan sovelluksen osiin liittyviä alustustoimia selittäen melko tarkasti sovelluksessa käytetyn toteutustekniikan periaatteita, ja luvussa 9 kuvataan, kuinka navigointipuun rakenne muunnetaan aidosti oliomaiseksi uusia luokkia lisäämällä. Luvussa 10 pohditaan uudistamisen onnistumista erityisesti Korppi-sovelluksessa ja ehdotetaan muokkauskohteita seuraaviin uudistamisprosesseihin. Luvussa 11 esitetään yhteenveto työn tuloksista. 2
2 Termejä Tässä työssä on mahdollisuuksien mukaan pyritty käyttämään suomenkielisiä vastineita englanninkielisille termeille uudistamisen, yleisten WWW-tekniikoiden ja työssä esitellyn Korppi-sovelluksen alueilta. Uudistamiseen liittyvissä termeissä on noudatettu alan ainoan suomentajan, Harsun [12, 13] valitsemaa linjaa. Kaikille termeille ei kuitenkaan ole vakiintuneita suomennoksia. Esimerkiksi ohjelmien suunnittelumalleille [11] on esitetty suomennoksia, mutta ne eivät ole saavuttaneet kovin vakiintunutta asemaa. Tästä syystä useimmille menetelmille ja malleille käytetään tässäkin työssä niiden englanninkielistä alkuperäisnimeä. 2.1 Uudistamiseen liittyviä termejä Ohjelman uudistaminen (renovation, myös modernization) on laaja käsite, joka kattaa ohjelman rakenteen tulkitsemisen, ohjelman nykytilaa kuvaavan dokumentaation tuottamisen, ohjelman rakenteen ja luettavuuden parantamiseksi tehdyt suunnitelmat ja lopulta myös itse lähdekoodin muokkaamisen suunnitelmia vastaavaksi. Tässä työssä termiä uudistaminen käytetään vain prosessista, joka käsittää kaikki edellä mainitut työvaiheet. Erityisen tärkeää on, että uudistamisessa muokataan ohjelmaa siten, että lopputuloksena ohjelmalla on parempi rakenne kuin lähtötilanteessa. Uudistaminen voidaan jakaa karkeasti kolmeen vaiheeseen. Ensimmäisenä vaiheena on abstraktioiden tuottaminen nykyisen lähdekoodin pohjalta. Tämä tehdään takaisinmallinnuksen eli käänteistekniikoiden (reverse engineering) avulla. Vaiheen suorittamista tukevilla työkaluilla voidaan tuottaa sovelluksesta esimerkiksi UML:n mukaisia luokka- tai sekvenssi-kaavioita. UML (Unified Modeling Language) on pääasiassa oliopohjaisten järjestelmien rakenteen kuvaamiseen käytetty graafinen notaatio. Luokkakaaviot mallintavat, kuinka tieto on tallennettuna sovelluksessa ja millä tavoin tieto ja toiminta on liitetty toisiinsa. Sekvenssikaaviot puolestaan esittävät ohjelman vuorovaikutuksen (kontrollin) etenemisen sovelluksessa eri olioiden välillä. Käänteistekniikkatyökaluilla ei koskaan muuteta ohjelman tilaa, eikä niillä myöskään lisätä uusia toimintoja ohjelmaan. Suurin hyöty työkaluista saadaan, kun niitä sovelletaan sellaiseen ohjelmaan, jonka rakenteesta ei ole kunnollista mieliku- 3
vaa, eikä järjestelmän alkuperäisiä kehittäjiä tai ylläpitäjiä ole käytettävissä. Uudistamisen toinen vaihe on uuden rakenteen suunnittelu. Riittävän korkealla abstraktiotasolla toimittaessa voidaan tehdä suuriakin muokkauksia järjestelmän rakenteessa. Tämän työn kannalta sovelluksen uudelleenmuokkaaminen (reengineering) on uudistamisen oleellisin vaihe. Muokkausten edellytyksenä on olemassa olevan rakenteen tuntemisen lisäksi myös halutun lopputuloksen hahmottaminen. Muokkausvaiheessa voidaan ottaa huomioon myös uusien toiminnallisuuksien asettamat vaatimukset ohjelman rakenteelle. Ellei uudistamiselle ole asetettu konkreettisia tavoitteita, ei muokkausprosessiakaan voida tehdä kunnolla. Muokkausvaiheessa tuotetut suunnitelmat sovelluksen paremmasta rakenteesta täytyy vielä konkretisoida lähdekooditasolle. Uudistamisen kolmannessa vaiheessa lähdekoodia muunnetaan uudelleenrakentamisen (refactoring) keinoin. Uudelleenrakentamisen tyypillisiä toimintoja ovat esimerkiksi yliluokkien lisääminen ohjelman luokkarakenteeseen tai useaan kertaan toistuvien koodilohkojen eriyttäminen omiksi aliohjelmikseen. Kyseessä ei kuitenkaan ole täysin mekaaninen vaihe, vaan se vaatii sekä sovellusalueen että ohjelmoinnin asiantuntijoiden työpanosta. Uudelleenmuokkauksen vaihetta voidaan kuvata monilla lähes samansisältöisillä termeillä: parantaminen (improvement), uusiminen (renewal), kohentaminen (refurbishing) ja uudelleenkehittämistekniikoiden (redevelopment engineering) soveltaminen. Arnoldin [2, s. 5 ja 11 16] mukaan nämä kuvaavat kuitenkin erityisesti ohjelmiston laadun parantamista. Ajanmukaistaminenkin (modernization) voi liittyä laadun parantamiseen, mutta tämän lisäksi ajanmukaistamisella voidaan viitata itse ohjelmistokehityksen parantamiseen. Pelastaminen (reclamation) ja uudelleenkäyttötekniikat (reuse engineering) viittaavat sellaisiin muokkauksiin, joilla lähdekoodista saadaan erotettua uudelleenkäytettäviä osia. Kääriminen (wrapping) on eräs tunnetuimmista menetelmistä uudelleenkäytettävien osien kapseloimiseksi sovelluksesta. Yleisemmin käärimisellä voidaan eheyttää rajapintoja myös järjestelmän sisällä tai kapseloida toiminnallisesti hankalia ohjelmanosia omiin moduuleihinsa. 2.2 WWW-tekniikoihin liittyviä termejä Perintönä kulkevilla tai perinteisillä sovelluksilla (myös perinnejärjestelmä, legacy system) viitataan usein sellaisiin sovelluksiin, jotka ovat olleet olemassa pitkään. Usein tällaiset sovellukset ovat saavuttaneet merkittävän aseman työskentelyympäristössään, eikä niitä sen vuoksi ole voitu korvata muilla sovelluksilla. Ohjelmien olemassaolon aikana monet kehittäjät ovat päässeet ylläpitämään niitä. Käytännössä kaikki tällaiset sovellukset on kehitetty yhden käyttäjän ajettavaksi omalla 4
työasemalla. Verkkosovellukset eroavat näistä siinä mielessä, että yleensä verkkosovellusta ei ajeta käyttäjän työasemalla vaan tietoverkon kautta erilliseltä palvelimelta. Useimmat verkkosovellukset käyttävät WWW (World Wide Web)-selainta sovelluksen käyttöliittymän esittämiseen. Yksinkertaisin esimerkki tällä tavoin toimivasta verkkosovelluksesta on staattinen WWW-sivusto. Staattisella sivustolla tarkoitetaan sitä, että palvelimelta pyydetyt sivut eivät muutu käyttäjän toimintojen mukaan, eikä sivuston sisältöä tuoteta ohjelmallisesti. Joissain teoksissa sivujen dynaamisuudella viitataan esimerkiksi kuviin, jotka ladataan sivun tietojen mukaan vasta selaimen päässä. Tässä työssä tällaisia ominaisuuksia pidetään kuitenkin staattisina. Dynaaminen sivusto tai sovellus tarkoittaa, että sen sisältö generoidaan ohjelmallisesti palvelimella, jolloin sovellukseen liittyy väistämättä jokin juonto (eli skripti)- tai ohjelmointikieli. Sovellus voidaan luoda kerralla valmiiksi kokonaisuudeksi, tai sen osia voidaan kääntää lennosta käyttäjien esittämien pyyntöjen mukaan. Tässä työssä verkkosovelluksilla tarkoitetaan poikkeuksetta dynaamisia sovelluksia. Asiakkaan esittämä sivupyyntö palautetaan usein käyttäjälle HTML (Hypertext Markup Language)-muodossa riippumatta siitä, onko taustalla staattinen vai dynaaminen sovellus. HTML-dokumentti sisältää rakenteisessa muodossa käyttäjälle esitettävän tiedon. Dokumentin rakenne määritellään DTD (Document Type Definition)- kielen avulla. DTD:n avulla selain osaa esittää HTML-dokumentin käyttäjälle. Mikäli dokumentin rakenne vastaa sitä DTD:tä joka dokumentille on määritelty, sivun sanotaan olevan virheetön (valid). Virheettömälle dokumentille on olemassa tarkkaan määritelty esitystapa, vaikkakin useimmat selaimet ovat ottaneet vapauksia myös virheettömien dokumenttien esittämisessä. HTML on vain yksi esimerkki rakenteisesta dokumentista. Yleisemmin XML (Extensible Markup Language)-formaatti sisältää sekä dokumentissa käytetyn DTD:n kuvauksen että varsinaisen tiedon. HTML-muotoisen esityksen suurin puute on siinä, että se ei tarjoa käyttäjälle juurikaan mahdollisuuksia vuorovaikutukseen sivun kanssa. Parhaimmillaan staattiset sivustot voivat tarjota linkkejä toisille sivuille, jolloin käyttäjä pystyy siirtymään hallitusti sivuston eri osien välillä. Todelliseen vuorovaikutukseen päästään vasta syöttökenttien ja painikkeiden kautta, mutta nämä vaativat sivustolta dynaamisia ominaisuuksia. Näiden kahden ääripään väliin on kehitetty DHTML (Dynamic HTML) -tekniikka, joka mahdollistaa selaimella suoritettavia dynaamisia toimintoja. Tunnetuimmat esimerkit DHTML-tekniikasta lienevät JavaScript-kielellä toteutetut funktiot ja elementit, joilla saadaan aikaiseksi esimerkiksi syötteen oikeellisuuden tarkastuksia asiakaspäähän. DHTML ei kuitenkaan riitä yksinään kovin laajojen sovellusten tekemiseen. 5
Dynaamisten sovellusten peruskäsitteistöön liittyy tieto siitä, kuka sovellusta käyttää. Palvelin tarjoaa tätä varten istunnon (session) eli käytännössä muistitilan asiakkaan käyttöön. Asiakaspäässä istuntoa vastaa usein eväste (cookie). Näiden yhteistietona voidaan toteutusteknisesti tunnistaa palvelimella yksittäinen käyttäjä satojen samanaikaisten sivupyyntöjen joukosta. Koko ohjelman tilaa ylläpidetään sovellusavaruudessa (application), joka tarjoaa kaikille istunnoille yhteisiä elementtejä. Käyttämättömät istunnot vanhentuvat palvelimella määrätyn ajan kuluttua käyttäjän viimeksi suorittamasta toiminnosta, oletuksena noin puolen tunnin kuluttua. Sovellusavaruuden tiedot säilyvät puolestaan sovellukseen kohdistuneesta ensimmäisestä pyynnöstä (request) siihen saakka, kunnes palvelimella oleva ohjelma sammutetaan. 2.3 Esimerkkisovelluksen toteutustekniikan termejä Esimerkkinä käytetty WWW-pohjainen Korppi-järjestelmä on dynaaminen verkkosovellus, joka palauttaa käyttäjälle HTML-muotoisia dokumentteja. Järjestelmä rakentuu yksittäisistä JSP (Java Server Pages)-sivuista, jotka muodostuvat Java-koodista ja käyttöliittymän esittämiseksi tarkoitetusta HTML-koodista. JSP-sivun tarkoituksena onkin sekä esittää tietoa käyttäjälle että tehdä tarvittavat operaatiot annetun tiedon tallentamiseksi. Tiedon tallentamiseen käytetään PostgreSQL-tietokantaa. Tietokantaa ohjataan SQL (Structured Query Language)-kyselyillä, joilla voidaan sekä hakea, tallentaa että muokata tietoa. Korppi-järjestelmä toimii yhdellä palvelimella, jonka sivupyynnöt ohjautuvat Tomcat-palvelulle. Tomcat vastaa yksittäisiin sivupyyntöihin luomalla tarvittaessa pyydetystä JSP-sivusta käännetyn palvelinsovelman (servlet), joka koostuu pelkästään Java-koodista. Palvelinsovelmat suorittavat tarvittavat tietokantahaut ja - muokkaukset SQL-kyselyillä, ja muokkaavat tulokset asiakkaalle palautettavaksi HTML-koodiksi. 6
3 Uudistamisen merkitys Jokaisen ohjelmistotuotantoprosessin tuloksena pyritään valmistamaan asiakkaalle luovutettava valmis ohjelma. Tällöin ohjelmaan suunniteltu (as-designed) ja toteutettu (as-built) rakenne ovat melko lähellä toisiaan. Yleisesti sovelluksen määrittelyn, rakenteen ja lähdekoodin tuntevat tällöin ohjelman toteutuksesta vastanneet asiantuntijat siis melko suuri joukko kehittäjiä. Kuva 3.1 esittää, kuinka ohjelman rakenteen tuntevien asiantuntijoiden joukko pienenee, kun sovellukseen tehdään muutoksia. Kuvassa vaaleat alueet esittävät sovelluksen alkuperäisen rakenteen tai lähdekoodin mukaista osuutta ohjelman kulloisessakin tilanteessa. Mustat alueet ilmaisevat muutoksia ja rapautumia alkuperäiseen rakenteeseen. Muutosten myötä rapautuneen osan osuus kasvaa ohjelman rakenteessa ja lähdekoodissa. Rapautuminen ei välttämättä etene tasaisesti rakenteessa, vaan saattaa kasvaa joissain muutoksissa huomattavastikin. Yleensä rapautuminen koskee koko sovellusta eikä keskity pelkästään tiettyihin ohjelmanosiin. Lukuisten muutosten jälkeen ohjelman rakenteen tuntee vain hyvin pieni joukko ylläpitäjiä. muutos 1 muutos 2...muutos n asiantuntijat rakenne lähdekoodi Kuva 3.1: Ohjelman rakenteen tuntevien asiantuntijoiden joukko pienenee ja ohjelman rakenne rapautuu, kun ohjelmaan tehdään muutoksia [2]. Sovelluksen rakenteen rapautuminen voi olla huonon suunnittelun tai toistuvien muutosten seurausta. Uudistamisprosessi aloitetaan silloin, kun ohjelman rakenne havaitaan rapautuneeksi. Prosessin tarkoituksena on helpottaa ohjelman tulevaa ylläpitoa antamalla kehittäjille abstraktin tason mielikuva ohjelman sisäisestä rakenteesta ja muokkaamalla ohjelmaa myös kooditasolla rakenteellisesti järkevämmäksi kokonaisuudeksi. 7
Tässä luvussa selitetään, mitä uudistaminen sisältää käsitteenä ja perustellaan uudistamisen välttämöttämyys sovelluksen rakennetta parantavana toimintona. Prosessiin liittyy kuitenkin sekä riskejä että etuja. Nämä täytyy tunnistaa ja niiden valossa tulee arvioida millä ylläpidon muodolla sovelluksen kehitystä kannattaa jatkaa. Lopuksi esitetään arvioita siitä, kuinka sovelluksen rapautumista voidaan ennaltaehkäistä ja tällä tavoin välttää sovelluksen joutumista uudistamisen kohteeksi. 3.1 Uudistamisesta käsitteenä Ohjelman uudistamiselle on olemassa useita määritelmiä. Uudistaminen voidaan määrittää ohjelman rakenteen parantamiseksi joko sen toiminnallisia ominaisuuksia tai tiedon esitystapaa muokkaamalla. Nämä vaihtoehtoiset määritelmät ovatkin Arnoldin [2, s. 3 5] mukaan uudistamisen toteutuslähtökohtia. Hän painottaakin, että uudistamisprosessi kokonaisuutena voi käsittää molempia tekniikoita, sillä niiden rinnakkaisella käyttämisellä saadaan huomattavasti laajempia muokkausmahdollisuuksia. Vaihtoehtoisissa määritelmissä pitäytymisellä on kuitenkin oma etunsa: silloin voidaan helpommin säilyttää ohjelman sisältämät rajapinnat entisellään. Yleisemmin Arnold esittää uudistamisen prosessina, jonka tarkoitus on parantaa sovelluksen ymmärtämistä. Tällä määrittelyllä myös pelkkä dokumentaation generoiminen sovelluksen nykyisestä tilasta on eräs uudistamismuoto. Määrittely mahdollistaa myös ohjelman ylläpidettävyyden, uudelleenkäytettävyyden tai kehitettävyyden parantamisen suunnittelun osaksi uudistamista. Nämä prosessit eivät kuitenkaan muuta olemassa olevan ohjelman rakennetta. Todelliseen muutokseen ja jatkokehityksen turvaamiseen voidaan päästä vain ohjelmaa konkreettisesti muokkaamalla. Tästä syystä uudistamisella tarkoitetaan tässä työssä vain ohjelman muokkaamiseen johtavaa toimintaa. Uudistamisessa on kolme erillistä vaihetta: olemassa olevan koodin esittäminen abstraktimmassa muodossa käänteistekniikoiden (reverse engineering) avulla, rakenteen ja koodin uudelleenmuokkaus (reengineering) sekä muokkausten toteuttaminen. Käänteistekniikat eli takaisinmallinnus on itsenäinen keino tuottaa dokumentaatiota sovelluksen todellisesta tilasta ja saada tarvittava tietämys uudelleenmuokkauksen pohjaksi. Mikäli ohjelman alkuperäisiä kehittäjiä tai ylläpitäjiä on käytettävissä, voidaan vastaava tieto saada myös heiltä. Uudelleenmuokkauksen vaiheessa tehdään varsinainen työ eli sovelluksen abstraktion avulla hahmotellaan sovellukselle uusi rakenne. Prosessin loppuunsaattamiseksi täytyy suunnitellut muutokset myös toteuttaa järjestelmään. Demeyer et al. [5] ovat esittäneet uudistamisprosessin tueksi malleja, jotka kattavat sekä takaisinmallinnuksen että muokkaamisen vaiheet 8
abstraktilla tasolla kuvattuna. Uudistamisen malleja ja työn etenemistä on lyhyesti lueteltu luvuissa 4.4 4.6. Fowler [8] on esittänyt huomattavasti konkreettisempia malleja uudelleenrakentamisen tueksi kooditasolta lähtien. 3.2 Uudistamisen välttämättömyydestä Lehmanin lait [19] esittävät huomioita sovelluksen kehittymisestä käyttöönoton jälkeen. Lehmanin kolme ensimmäistä lakia on esitetty jo vuonna 1974. Luetteloa on täydennetty vuosina 1978 ja 1995 käsittämään kahdeksan kohtaa. Tässä yhteydessä esitellään niistä uudistamisen merkityksen kannalta oleellisimmat; siten kolmas ja kahdeksas laki puuttuvat luettelosta. I Jatkuva muutos (Continuing Change), 1974 II Monimutkaistuminen (Increasing Complexity), 1974 IV Säännönmukaisuus (Conservation of Organisational Stability), 1978 V Muutosmäärän vakiintuminen (Conservation of Familiarity), 1978 VI Jatkuva kehitys (Continuing Growth), 1978 VII Laadun heikkeneminen (Declining Quality), 1994 Lehmanin ensimmäinen laki väittää, että toteutettuja tietokonesovelluksia täytyy jatkuvasti muuttaa. Muutoin sovellukset eivät enää vastaa niille asetettuihin odotuksiin ja ne jäävät pois käytöstä. Kuudes laki täydentää ensimmäistä lakia esittämällä, että sovellukseen täytyy tuoda koko ohjelman elinkaaren ajan uusia toiminnallisia ominaisuuksia, jotta käyttäjät pysyisivät tyytyväisinä. Yhdessä nämä lait väittävät, ettei ole tarkoituksenmukaista yrittää suunnitella sovellusta ja sen kaikkia mahdollisia käyttötarpeita yhdellä kerralla, sillä muutoksia joudutaan väistämättä tekemään. Toinen laki huomauttaa, että kun järjestelmään tehdään muutoksia, sen rakenne monimutkaistuu. Monimutkaistuminen voidaan estää vain panostamalla erikseen sovelluksen rakenteen yksinkertaistamiseen. Seitsemäs laki täsmentää, että ellei tätä panostusta tehdä säännöllisesti, koko järjestelmän laatu heikkenee. Uudistaminen on osa rakennetta yksinkertaistavaa toimintaa ja pyrkii siten nostamaan järjestelmän laatua. Lehmanin neljäs ja viides laki esittävät, että järjestelmän kehitysvauhti pysyy samana, esimerkiksi järjestelmässä tehdyt muutokset pysyvät vakiokokoisina tai pienenevät. Tämä selittyy sillä, että muutosten tekeminen suurissa järjestelmissä on aina hyvin riskialtista: toiminnan muuttaminen voi kumuloida niin paljon virheitä, 9
ettei niiden korjaaminen olisi mahdollista normaalissa kehitysvauhdissa. Tämän vuoksi järjestelmiin ei voida tehdä kovin isoja muutoksia. Lehmanin lait on koottu kuluneiden vuosikymmenten aikana sovellusten ylläpidosta saadun kokemuksen nojalla. Ne vaikuttavat pitävän paikkaansa: ainakin ne kuvaavat hyvin luvussa 7 esitettävän Korppi-järjestelmän kehitystä. Lehmanin lait auttavat myös ymmärtämään, miksi perinteisten ohjelmien ylläpito on niin vaikeaa. Koska sovellukset on koettu tärkeiksi, niitä on kehitetty käytettävissä olevien resurssien puitteissa. Kehitystyössä on kuitenkin usein ollut mukana lukuisia ohjelmoijia. Siten yhtenäistä ohjelmointityyliä on ollut vaikea säilyttää. Vanhoissa järjestelmissä käytettyjä ohjelmointikieliä ja -työkalujakaan ei välttämättä ole enää saatavilla, jolloin sovellus on pakko kääntää toiselle kielelle, jos siihen halutaan tehdä täydennyksiä. Pitkään kehitettyjen järjestelmien dokumentit eivät pysy ajan tasalla. Tämä tekee sovelluksen rakenteen hahmottamisen vaikeaksi uusille kehittäjille. Toisaalta tehtyjen muutosten myötä sovelluksen rakenne voi olla hyvinkin kirjava erilaisista ohjelmointityyleistä johtuen. Koodin optimointi puolestaan vaikeuttaa sekä lähdekoodin luettavuutta että ylläpidettävyyttä. Suurissa järjestelmissä esiintyy usein myös tietorakenteiden ja toiminnan päällekkäisyyttä. 3.3 Uudistamisen riskit Kuten kaikkiin sovellusten tuotantoprosesseihin, myös sovellusten uudistamiseen liittyy riskejä. Arnold [2, s. 15] on koonnut riskeistä luettelon, josta esitellään muutamia. Suurin osa riskeistä liittyy resurssienhallintaan, sillä ohjelmistotuotannossa ja erityisesti ohjelmien ylläpidossa resurssit ovat rajallisia. Valitettavan usein raha ratkaisee. Uudistamisprosessin alkuvaiheen eli takaisinmallinnuksen tukemiseen on kehitetty työkaluja, mutta itse muokkausvaiheeseen ei: sovelluksen ongelmakohtia tunnistavia automaatteja on tosin yritetty kehittää, mutta niiden toimintaan liittyy vielä liikaa ratkaisemattomia kysymyksiä. Muokkausten soveltamiseen on kuitenkin olemassa uudelleenrakentamistyökaluja. Jos uudistustyö joudutaan tekemään sovelluskohteessa kokonaan käsin, voi työ tulla todella kalliiksi. Käsin muokattaessa myös virheiden todennäköisyys lisääntyy. Päteviä uudistamisen asiantuntijoita voikin olla vaikeaa löytää. Uusien ohjelmien kehittäminen on huomattavasti trendikkäämpää kuin vanhojen ohjelmien uudistaminen. Lisäksi uudistaminen ei tuota juurikaan näkyviä tuloksia, vaan vain parantaa entisen ohjelmiston rakennetta vaikuttamatta suoranaisesti edes sovelluksen suorituskykyyn tai muihin käyttäjälle näkyviin osa-alueisiin. 10
Näistä syistä projektin johtoa voi olla vaikea saada sitoutumaan uudistamisprosessiin. Mikäli prosessin tukeminen lopetetaan kesken, voi uudistaminen jäädä vain sovelluksesta tuotettujen dokumenttien tasolle, mutta konkreettiset tulokset jäävät puuttumaan, mikä voi vähentää halukkuutta käyttää uudistamista muissa kohteissa. Uudistamiseen ryhdyttäessä pitäisi olla selkeä näkemys siitä, mihin uudistamisella pyritään kyseisessä sovelluksessa. Mikäli työn tekijöillä ei ole riittävän laajaa perspektiiviä, voivat tuloksetkin olla heikkoja. Rahgozar ja Oroumchian [21] ovat havainneet, että uudistamisessa pyritään liian usein pikaisiin tuloksiin esimerkiksi käärimällä vanhoja ohjelmanosia uusien rajapintojen taakse. Tämä ei kuitenkaan poista ohjelman rakenteellisia ongelmia. Väärillä uudistamistoimilla saatetaan jopa hankaloittaa sovelluksen kehittämistä. Lisäksi Harsu [12] varoittaa, että uudistamiseen varataan usein aivan liian vähän aikaa. Uudistamisprosessille voidaan asettaa liikaa vaatimuksia, ja uutta toiminnallisuutta yritetään lisätä ilman selkeitä välitavoitteita. Tekninen uudistaminen käsittää sovelluksen rakenteen selkeyttämisen. Toiminnallinen uudistaminen puolestaan liittyy sovellukseen liitettäviin uusiin ominaisuuksiin. Sneed [22] varoittaa, ettei uudistamisessa tule sekoittaa näitä kahta uudistamisen osa-aluetta. Yleensä tekninen uudistaminen täytyy tehdä ennen toiminnallisia muutoksia, jotta toiminnallisille muutoksille saadaan riittävän vakaa perusta. Mikäli mahdollista, toiminnalliset muutokset tulisi jättää seuraavaan versioon, jotta teknisen muutoksen mahdollisesti aiheuttamat ongelmat ehditään havaita. Rahgozar et al. [21] esittävät teknisille muutoksille vielä yksityiskohtaisempia vaatimuksia, kuten että sovelluksiin liittyviin asetus- tai data-tiedostoihin ei saa tehdä muutoksia, uudelleenmuokattaessa ei saa jäljitellä vanhoja ratkaisuja tai tietomalleja eikä prosessissa saa tuottaa uutta, tarpeetonta dataa. Rahgozarin vaatimuksista kuitenkin tärkein on se, ettei uudistaminen saisi muuttaa sovelluksen toimintalogiikkaa. Tämä korostaa sitä, että uudistamisen tehtävänä ei ole tuottaa uutta toiminnallisuutta sovellukseen. Toisaalta voi olla aiheellista kysyä, ovatko uudistamiselle esitetyt riskit yhtään sen suuremmat kuin perinteisessä ohjelmistotuotantoprosessissa. Täysin riskitöntä menetelmää ei liene olemassakaan. Ylittyvä budjetti, ammattitaitoisen henkilökunnan löytäminen, projektijohdon suostuttelu ja ylittyvät aikataulut liittyvät yhtä oleellisina riskeinä myös uuden ohjelman tuotantoon. Lisäksi uuden sovelluksen tuottaminen vaatii paljon aikaa ennen kuin sovelluksesta saadaan näkyviä tuloksia. Lähdekoodin muokkaaminen sisältää kuitenkin sellaisia ongelmia, joita puhtaalta pöydältä kirjoitettaessa ei esiinny. Harsu [13] huomauttaa, että esimerkiksi olio- 11
ohjelmissa olioiden muokkaaminen automaattisesti on vaikeaa. Tehdyt muutokset heijastuvat moneen paikkaan. Rakenteellinen muutos lähdekoodissa, esimerkiksi tietotyypin tai muuttujan näkyvyyden muuttaminen, vaikuttaa koko ohjelmaan. Ongelma on toki tekninen mutta osoittaa, ettei uudistaminen ole missään nimessä helppo prosessi. 3.4 Uudistamisen etuja Mikäli sovelluksen uudistaminen tehdään hallitusti, ohjelman rakenne on prosessin jälkeen selkeämpi ja helpommin muokattavissa. Ennen kaikkea sovelluksen rakenne on saatu visualisoitua ja sovelluksen kehittäjäjoukko on sisäistänyt sovelluksen rakenteen. Voidaankin olettaa, että muokattu rakenne kestää jonkin aikaa tuleviakin muutoksia ja sovellus pysyy käytössä vähintään yhtä kauan kuin puhtaalta pöydältä kirjoitettu versio. Parantunut ohjelman rakenne ja rakenteen dokumentoituminen ovat uudistamisen näkyvimpiä tuloksia. Prosessista voidaan kuitenkin saada muitakin kuin suoraan tavoiteltuja hyötyjä. Arnold [2, s. 9 11] korostaa, että uudistamisen soveltamisesta saadaan arvokasta kokemusta. Saadun kokemuksen kautta voidaan myöhemmin rakentaa ohjelmia, jotka automaattisesti päättelevät uudistettavien ohjelmien ongelmakohdat. Sitä ennen pienenä parannuksena voidaan kehittää työvälineitä, jotka tukevat ongelmien paikantamisen ja korjaamisen prosessia. Uudistamisen läpikäyminen voi kohentaa myös työhön osallistuneiden ohjelmoijien ammattitaitoa. Jos heidän olisi annettu kirjoittaa sama ohjelma kokonaan uusiksi, osa sovelluksen virheistä olisi voinut huomaamatta siirtyä uuteen koodiin viimeistään toisissa projekteissa. Vanhan koodin kehittäminen pakottaa ohjelmoijat ajattelemaan ongelmia eri näkökulmista. He saavat mahdollisuuden korjata aiemmin tehdyt virheet. Tämän jälkeen he luultavasti käyttävät uudistamisprosessissa saamaansa kokemusta ja osaavat tehdä paremman vaihtoehdon mukaisen ratkaisun. Siten uudistaminen vahvistaa ohjelmoijien ammattitaitoa ja samalla koko yrityksen kilpailukykyä. 3.5 Uudistamisen suhteesta ylläpitoon Pressman [20, s. 18 21] ja Harsu [12] jakavat ohjelman ylläpidon neljään eri tyyppiin toiminnan tavoitteiden mukaan: Vaikka sovelluksista yritetään rakentaa mahdollisimman virheettömiä, jää niihin 12
väistämättä virheitä (bug, defect), jotka huomataan vasta myöhemmissä testaus- ja käyttövaiheissa. Korjaavalla ylläpidolla (corrective maintenance) pyritään paikkaamaan löytyneitä virheitä ja tätä kautta parantamaan ohjelman laatua. Virheen laadusta riippuen sen korjaaminen voi olla joko hyvin yksinkertaista tai melko vaikeaa; joskus virheen korjaaminen voi kumuloida lisää virheitä sovellukseen. Korjaavan ylläpidon osuus kaikesta ylläpidosta on noin viidennes. Tekniikan kehittyessä laiteympäristöjä päivitetään. Siten ohjelma joutuu toimimaan erilaisessa ympäristössä kuin jossa sitä on kehitettiin ja testattiin. Laiteympäristön muuttamisen yhteydessä voidaan tarvita ohjelman mukauttavaa ylläpitoa (adaptive maintenance) Esimerkiksi ohjelmasta suoritettujen käyttöjärjestelmäkutsujen rajapinta saattaa muuttua, mikäli laitteiston käyttöjärjestelmää muutetaan. Tällä hetkellä noin neljännes ylläpidon ajasta kuluu ympäristön muutoksen aiheuttamien ongelmien ratkaisemiseen. Sovelluksen rakenteen uudistaminen etukäteen voisi helpottaa mukauttamisen onnistumista. Kun käyttäjät esittävät ohjelmalle uusia toiminnallisia vaatimuksia, niiden toteuttamiseen tarvitaan täydellistävää ylläpitoa (perfective maintenance). Tämä ylläpidon muoto esiintyy luvussa 3.2 esitettyjen Lehmanin lakien ensimmäisenä ja kuudentena kohtana ja on näiden perusteella välttämätöntä ohjelmien selviämistaistelussa. Tehtyjen tutkimusten perusteella täydellistävä ylläpito viekin puolet [20, s. 18 21] kaikesta ylläpitoon käytetystä ajasta. Tämän ylläpidon muodon suurin ongelma on siinä, että se muuttaa ohjelman toimintaa. Toiminnalliset muutokset edellyttävät usein myös rakenteellisia muutoksia, jotka puolestaan lisäävät virheiden syntymahdollisuutta. Uudistaminen on ehkäisevää ylläpitoa (preventive maintenance). Sen tarkoituksena on helpottaa tulevia ylläpitotehtäviä. Ehkäisevään ylläpitoon käytetään kuitenkin vain kymmenes kaikesta ylläpidon ajasta. Tämä vaikuttaa olevan aivan liian vähän. Jos alkuoletuksena ohjelmalla on ollut suhteellisen hyvä rakenne mutta ylläpidon seurauksena sen rakenne on rapautunut, täytyy kolmen ensimmäisen ylläpidon muodon heikentää sovelluksen rakennetta nopeammin kuin ehkäisevällä ylläpidolla pystytään paikkaamaan. Toisaalta järjestelmän rakenteen rapautuminen saatetaan hyväksyä, sillä sovellukselle hahmotetaan vain rajallinen elinkaari. Tämän vuoksi rakenteen parantamiseen ei haluta haskata niitä resursseja, jotka on varattu laadun ja toiminnan kehittämiseen. Lopulta näin lyhytnäköinen ajattelutapa voi kostautua sovelluksen kehittämisessä: liian monimutkaista järjestelmää ei voida enää ylläpitää käytettävissä olevilla resurseilla. Ohjelman ylläpidettävyydellä tarkoitetaan sitä helppoutta, jolla halutut muutok- 13
muutettavuus ylläpidä hylkää jatkokehitä uudista liiketaloudellinen arvo Kuva 3.2: Ohjelman ylläpito- ja uudistamispäätöksiin vaikuttavat sovelluksen muutettavuus ja sen liiketaloudellinen arvo [15]. set voidaan tehdä korjaavassa, mukauttavassa tai täydellistävässä ylläpidon tyypissä. Ehkäisevä ylläpito on keino parantaa ylläpidettävyyttä. Aina siihen ei kuitenkaan kannata uhrata resursseja. Jacobson ja Lindström [15] ovat arvioineet kuvan 3.2 mukaisesti, kuinka sovelluksen muutettavuus ja liiketaloudellinen arvo vaikuttavat ylläpitoratkaisuihin. Jos ohjelma on helposti muutettavissa, sitä kannattaa ylläpitää täydellistävän ylläpidon keinoin. Jos ohjelman muuttaminen on vaikeaa mutta sovelluksen liiketaloudellinen arvo on kuitenkin suuri, sovellus kannattaa uudistaa. Luvussa 7 esitetty Korppi-sovellus sijoittuu erinomaisesti tähän matriisiin. Joiltain osin sen rakenne on hieman heikko, mutta järjestelmä kokonaisuutena on liian laajassa käytössä, jotta sen voisi hylätä ja korvata uudella. Toisaalta järjestelmään kohdistuu niin paljon kehittäviä muutostoiveita, että sitä on pakko ylläpitää. Siten järjestelmän osien uudistaminen on järkevä vaihtoehto. Sovelluksen ylläpidettävyyttä voidaan mitata myös laskemalla sovellukselle SMI (software maturity index)-arvo. Arvo määräytyy sovelluksen sisältämien moduulien sekä viimeisimmän julkaisun jälkeen lisättyjen, muutettujen ja poistettujen moduulien lukumäärän mukaan. Mitä vähemmän järjestelmässä on muuttuneita osia, sitä vakaammaksi SMI:n antama arvo luokittelee tarkasteltavan järjestelmän. Pressman [20, s. 518] ehdottaa, että ylläpitotoimia tulisi suunnitella siten, että sovelluksen SMI saadaan mahdollisimman vakaaksi. Tämä tosin voi vääristää sovelluksen luonnollista kehittymistä, jos muutosten määrää aletaan tietoisesti pienentämään. Arnold [2] huomauttaa, että ylläpidettävyyden saavuttaminen uudistamisen kautta ei vielä riitä, koska ohjelman kehitys jatkuu vielä uudistamisen jälkeenkin. Tämän vuoksi ohjelman tulee säilyttää ylläpidettävyytensä myös tulevaisuudessa. Viimeistään uudistamisen jälkeen tarvitaan käänteistekniikoita lähdekoodin visualisoimiseen esimerkiksi UML-kaavioina. Tulevat muunnokset tulisikin suunnitella tällä abstraktiolla jo ennen kuin muutokset tehdään sovelluksen lähdekoodiin, jotta 14
kokonaiskuva sovelluksesta säilyisi paremmin. Käänteistekniikoiden automaation ansiosta abstraktit kuvaukset on helppo pitää ajan tasalla myös muutosten jälkeen. 3.6 Rapautumisen ennaltaehkäisy Luvussa 3.2 lueteltujen Lehmanin lakien valossa uudistaminen vaikuttaa sellaiselta prosessilta, johon väistämättä ajaudutaan jossain vaiheessa pitkäikäisen ohjelman elinkaarta. Onko tämän kehityksen estämiseksi mitään keinoja? XP (Extreme Programming)-ohjelmoinnin [25] perusideana on tehdä työtä mahdollisimman pienissä paloissa. Jokainen muutos suunnitellaan etukäteen ja muutoksen on oltava niin pieni, että sen suunnittelu, toteutus ja testaus voidaan suorittaa lyhyen ajanjakson, yleensä yhden työviikon, aikana. Alkuoletuksena muutettava ohjelma on täydellisesti toimiva, ja sellainen sen tulisi olla myös jokaisen muutoksen jälkeen. Muutosvaiheessa kaksi kehittäjää koodaavat muutosta samanaikaisesti: yksi keskittyy muutoksen syntaktiseen toteutukseen ja toinen pitää huolen siitä, että toteutus tehdään oikeaan asiayhteyteen järjestelmän kannalta. Tämä auttaa säilyttämään kokonaiskuvan ohjelmasta koko muutosprosessin ajan. XP rikkoo perinteisen ohjelmoinnin rajoja myös siinä suhteessa, että se ei kannusta kehittäjiä ottamaan vastuuta sovelluksen yksittäistä moduuleista. XP-ohjelmoinnissa jokainen ohjelmoija on vastuussa koko sovelluksen toiminnasta, ja siten jokaisella kehittäjällä säilyy kokonaiskuva sovelluksen toiminnasta hyvinkin yksityiskohtaisella tasolla. Tämä vähentää riskejä myös henkilöstön vaihdoksissa, sillä kriittisten toimintojen ylläpito ei perustu vain yhden kehittäjän tietämykseen. XP:n mukainen toimintatapa voisikin olla keino ehkäistä uudistamisen tarvetta, sillä uudistamisprosessi elää pienessä mittakaavassa XP-kehitysprosessin sisällä. Tietyssä mielessä ohjelman uudistaminen on XP:tä jälkikäteen sovellettuna, sillä uudistamisen tarkoituksena on palauttaa kehittäjien tekemät muutokset siihen kontekstiin, johon ne alunperin olisi pitänyt tehdä. 15