Mielestäni on parempi viedä konfiguraatiota erillisiin tiedostoihin mieluummin enemmän kuin liian vähän. Joidenkin mielestä kuitenkin erilliset konfiguraatiotiedostot ovat jopa turhia, koska heidän ajatusmallinsa mukaan koodi voidaan aina kääntää ja asentaa uudelleen, kun lähdekoodissa oleviin asetuksiin tehdään muutoksia. Ylenmääräisestä konfiguroitavuudesta on kyllä haittaakin ja parasta on, jos melkein kaikille konfiguroitaville asioille voi antaa järkevän oletusarvon joko suoraan sovelluksen lähdekoodissa tai sitten erillisissä oletusarvoja sisältävissä konfiguraatiotiedostoissa.
Nähdäkseni on olemassa neljä eri tapaa tehdä sovelluksen konfiguraatiota.
- Lähdekoodissa olevat vakiot, joiden muuttaminen vaatii lähdekoodin uudelleenkääntämisen
- Konfigurointi erillisiin tiedostoihin (Javassa esimerkiksi properties-tiedostot), joiden sisältö kiinnitetään käännösaikaisesti esimerkiksi Maven filttereillä.
- Konfiguraatiotiedostot, jotka eivät mene binääripakettien (JAR, WAR, EAR ja vastaavat eri kielissä) sisään ja joita voidaan muutella kääntämisen jälkeen vapaasti. Muutosten käyttöönotto vaatii prosessin uudelleenkäynnistyksen
- Prosessin ajoaikainen konfiguraatio eli asetusten muuttaminen ilman prosessin uudelleenkäynnistystä. Tämä tapa on käytössä melkein kaikissa graafisen käyttöliittymän sisältävissä sovelluksissa, mutta erittäin harvoin taustaprosesseissa
Esittämäni konfiguroitavuuden tasot ja niiden järkevä käyttö projektissa riippuu täysin projektin koosta ja tavoitteista.
Jos koodailee itsekseen tai hyvin pienellä ryhmällä sovellusta, jonka ajoympäristö on yksinkertainen ja build-prosessin sekä kehittäjäryhmän hallitsema, voidaan rajoittaa konfiguroitavuus tapaan 1. Tällöin vaatimuksena on se, että kehittäjän on äärimmäisen helppo viedä pienetkin mutokset suoraan tuotantoon ja erillisiä testiympäristöjä ei juurikaan käytetä. On huomattava, että mikäli käytössä on yksikin ympäristö tuotannon lisäksi, se näkyy aina lähdekoodissa. Jokainen tuettava lisäympäristö ja poikkeama konfiguraatiossa vaatii muutoksia lähdekoodiin.
Tapa 2 on käyttökelposuudeltaan hyvin lähellä tapaa 1. Näillä on kuitenkin se merkittävä ero, että uudet ympäristöt tai erilaiset konfiguroinnit eivät enää vaadikaan välttämättä lähdekooditason muutoksia. Toki sovelluksen pitää osata hakea asetukset koodista erillään olevista tiedostoista. Yleensä tavassa 2 erilliset konfiguraatiotiedostot leivotaan binääripakettien sisään ja niiden buildin jälkeinen muuttaminen vaatii pakettien avaamista ja uudelleen paketointia käsipelillä. Tapa 2 soveltuu pieniin projekteihin, joiden ajoympäristö on projektien kehittäjien täydellisessä hallinnassa ja jossa kehittäjän on äärimmäisen helppo viedä pienetkin muutokset suoraan eri testi- ja tuotantoympäristöihin.
Tavassa 3 konfiguraatiomuutokset eivät koskaan vaadi lähdekoodin muutoksia tai binääripaketin uudelleen kasaamista. Kaikki konfiguraatio on erillään varsinaisesta binääristä ja binäärille vain kerrotaan mistä päin sen tulisi käynnistyksen yhteydessä hakea konfiguraationsa. Tämä tapa soveltuu lähes kaikkiin projekteihin eikä ole juurikaan monimutkaisempi toteuttaa kuin tapa 2.
Tapa 4 on käytössä yleensä vain graafisen käyttöliittymän sisältävissä sovelluksissa. Joskus tosin taustaprosessejakaan ei saa niin vaan käynnistellä uudelleen ja niiden konfiguraatiota pitää pystyä muuttamaan ajonaikaisesti. Vaikka tapa 4 kuulostaa parhaalta ja joustavimmalta tavalta sovelluskonfiguraatioon, on sen toteuttaminen kaikelle konfiguraatiolle useimmiten haastavaa ja aivan liian työlästä saavutettuun hyötyyn nähden.
Olen ollut huomaavinani, että Maven filteröintiä käytetään vähän liian innokkaasti sovelluskonfiguraatioon, jossa tavoitteena on tavan 3 joustavuus, mutta sitä yritetään tehdä tavan 2 välinein. Vaikka Mavenin filteröinnillä saadaan helposti tehtyä erilaisia profiilikohtaisia konfiguraatioita, ei filteröintiä voi soveltaa järkevästi kaikelle konfiguraatiolle kuin hyvin suppeissa projekteissa. Esimerkiksi projektissa, jossa varsinaisesta ajoympäristöstä vastaa muu kuin kehitysporukka, täytyisi ajoympäristön ylläpitäjien jatkuvasti kertoa ajoympäristön muutoksista (vaikkapa uusi tietokantasalasana), jotta ne saataisiin sovelluksen konfiguraatioon Maven buildin yhteydessä. Vaikka kehitysporukka vastaisikin kokonaan eri ajoympäristöistä ja asennukset voitaisiin tehdä uudestaan konfiguraatiomuutoksia sisältävän Maven buildin jälkeen, joudutaan joka ajoympäristölle ajamaan erillinen build eri profiililla. Uusi build eri profiililla sisältää riskin siitä, että eri build-tuloksissa on muitakin eroja kuin vain erilaisia filtteröitäviä konfiguraatioita (Mavenin kanssa on helppo mokata tällaisessa erityisesti release-pluginia käyttäessä).
Kun itse lähden tekemään taustaprosessina pyörivää sovellusta (eli suurin osa esimerkiksi selaimella käytettävistä sovelluksista, jotka pyörivät sovelluspalvelimen sisällä), lähden toteutuksessa aina siitä, että konfiguraatioon voi käyttää tapoja 1, 2 ja 3. Jos teen graafisella käyttöliittymällä varustettua sovellusta, otan lähtökohtaisesti tavat 1, 2, 3 ja 4 käyttöön. Yleensä tavan 3 tukeminen on helppo toteuttaa, joten ei ole mitään mieltä jättää sitä pois ja tyytyä vain tapohin 1 ja 2 edes ihan pienimmissä projekteissa. Hyödylliset pienet projektit yleensä kasvavat isommiksi projekteiksi ja tavat 1 ja 2 eivät skaalaudu projektin koon kasvaessa. On kuitenkin huomattava, että mikään esitetyistä tavoista ei yksistään ole yleensä paras tapa. Paras lähestymistapa on tukea ainakin kolmea ensimmäistä tapaa ja tehdä niiden käyttö sovelluskehittäjälle yhtä helpoksi. Näin sovelluskehittäjän on helppo tehdä tekemästään ominaisuudesta halutulla tasolla konfiguroitava.
Ei kommentteja:
Lähetä kommentti