Skip to content

Latest commit

 

History

History
502 lines (362 loc) · 28.4 KB

File metadata and controls

502 lines (362 loc) · 28.4 KB
Tehtävien palautuksen deadline su 12.11. klo 23.59

Ohjausta tehtävien tekoon to ja pe klo 14-16 salissa B221

palautetaan GitHubin kautta

  • osa githubtehtävistä (4-6) tehdään paikalliseen repositorioon, eli ne eivät näy palautuksessa mitenkään
  • tehtävät 2 ja 3 palautetaan viikon 1 repositorioon
  • tee muiden tehtävien palautusta varten uusi repositorio, esim. ohtu-viikko2
  • palautusrepositorion nimi ilmoitetaan tehtävien lopussa olevalla palautuslomakkeella

Typokorjauksia & vinkkejä

Typot

Jos huomaat tehtävissä tai muussa materiaalissa kirjoitusvirheitä, paina sivulla olevaa kynä-symbolia:

korjaa virhe ja ehdota muutosta (nappi sivun alalaidassa):

luo pullrequest:

ja varmista vielä:

Korjausehdotuksesta tulee nyt pullrequest ja se päivittyy siinä vaiheessa sivulle kun joku kurssihenkilökunnasta hyväksyy sen.

Vinkit

Joskus ohtun laskareissa tulee vastaan kaikkea sekalaista ongelmaa joiden kanssa taisteleminen ei välttämättä ole parasta ajankäyttöä oppimiselle. Tätä varten kerätään opiskelijoilla vastaantulleita ongelmia ja ratkaisuja. Jos törmäät ongelmaan niin tarkista mahdolliset vinkit tai lisää oma vinkkisi tiedostoon 2-tips.md! Ongelman ei tarvitse olla vaikea eikä haittaa, jos ratkaisu tuntuikin ilmiselvältä.

Jos ongelma on pahempi, niin siihen liittyvän vinkin voi lisätä typo-korjauksen tapaan myös suoraan tähän laskarisivuun.

huomio gradleen liittyen

Käytämme tälläkin viikolla gradle-muotoisia projekteja. Jos gradle-koodi lukee syötteitä komentoriviltä, tulee määrittelytiedostojen loppuun liittää seuraava

run {
    standardInput = System.in
}

Ilman tätä määrittelyä ohjelmaa gradlella suorittaessa, eli komennolla gradle run, ohjelma ei pääse käsiksi syötevirtaan ja scannerin luominen epäonnistuu.

Tämän viikon tehtäviin liittyviin projekteihin määrittely on jo lisätty.

Jos käytät komentorivisyötettä, kannattaa ohjelma suorittaa komennolla gradle -q run, jolloin gradle jättää omat tulostuksensa tekemättä.

1. gradlen perusteita

Olemme jo käyttäneet gradlea hyvällä menestyksellä parin viikon ajan. Tutustutaan nyt gradleen hieman tarkemmin tekemällä sivulla https://github.com/mluukkai/ohtu2017/blob/master/web/gradle.md oleva interaktiivinen "tutoriaali".

2. lisää gradlea: koodin staattinen analyysi

Mene nyt viikon 1 tehtävien 7-16 tehtävän, eli Ohtuvaraston palautusrepositorioosi.

Lisää projektiin checkstyle-plugin ja suorita komento gradle checkstyleMain

Suoritus epäonnistuu, virheilmoitus kertoo mistä kyse:

* What went wrong:
Execution failed for task ':checkstyleMain'.
> Unable to create a Checker: unable to find /Users/mluukkai/opetus/koodit/ohtuvarasto/config/checkstyle/checkstyle.xml

Eli kuten manuaalikin kertoo, Gradle olettaa että projektista löytyy checkstylen toiminnan määrittelevä konfiguraatiotiedosto.

Luo tiedosto ja hae sille sisältö täältä

Huomaa, että tiedoston tulee olla oikeassa paikassa. Virheilmoitus ja manuaali kertovat oikean sijainnin.

Kun nyt suoritat komennon gradle checkstyleMain, tulee jälleen virhe, mutta nyt virheen syynä on se, että koodi rikkoo konfiguraatiotiedostossa määriteltyjä tyylisääntöjä. Virheilmoitus kertoo raportin sijainnin:

* What went wrong:
Execution failed for task ':checkstyleMain'.
> Checkstyle rule violations were found. See the report at: file:///Users/mluukkai/opetus/koodit/ohtuvarasto/build/reports/checkstyle/main.html

Avaa raportti selaimella. Huomaat, että tuloksena on suuri määrä virheitä. Valitettavasti virheraportti keroo ainoastaan sen koodirivin, mistä virhe löytyy. Joudut katsomaan vastaavan kohdan koodistasi esim NetBeansista.

Toimi nyt seuraavasti

  • poista kaikki elementin tree walker sisällä olevat tarkistukset

  • suorita gradle checkstyleMain ja varmista, että tarkastus menee läpi

  • määrittele nyt tiedostoon seuraavat säännöt (ks. kohta checks checkstylen sivuilta:

    • metodien pituus max 15 riviä (tämä ja seuraavat säännöt määritellään moduulin tree walker sisälle)

    • ei yli yhtä sisäkkäisiä if:iä

    • ei sisäkkäisiä for:eja, seuraavan siis pitäisi aiheuttaa virhe:

        for( int i=0; i<1; i++ ) {
          for( int j=0; i<j; j++ ) {
            System.out.println("virhe");
          } 
        }
    • koodi on oikein sisennettyä

    • lohkon avaava aaltosulku on aina rivin lopussa, eli esim. ehtolauseissa aaltosulku tulee merkitä

        if ( ehto ) 
        {
          System.out.println("virhe");
        }

      sijaan seuraavasti:

        if ( ehto ) {
          System.out.println("virhe");
        }
    • syklomaattinen koodikompleksisuus korkeinaan 3 (selvitä mitä tarkoittaa!)

    • koodi ei sisällä taikanumeroita (magic numbers)

  • muuta koodiasi siten, että saat jokaisen määritellyistä checkstyle-säännöistä rikkoutumaan

  • korjaa koodisi ja varmista, että se noudattaa kaikkia sääntöjä

    • pääohjelman koodin voi poistaa tarvittaessa kokonaan, jotta saat koodin säännönmukaiseksi

3. codacy

Viime viikon tehtävässä 12 konfiguroimme https://codecov.io-palvelun tarkkailemaan koodin testauskattavuutta.

Codacy on palvelu, jonka avulla voimme suorittaa helposti staattista analyysiä githubissa olevalle koodille. Java-koodille codacy tekee tarkastukset checksylen lisäksi pmd:llä.

Mene codacyn sivulle ja klikkaa signup with github. Lisää edellisen tehtävän koodin sisältävä repositoriosi codacyn tarkkailtavaksi:

Mene sitten projektin "dashboardiin". Kun analyysi on valmis avautuu seuraava näkymä:

Tutki koodissasi olevia codacyn raportoimia ongelmia. Korjaa jokin ongelma ja pushaa koodista uusi versio githubiin.

Näet uuden commitin välilehdellä "commits":

Odota että sen analyysi valmistuu ja katso miltä "dashboard" näyttää (selain saattaa kannattaa reloadata jos analyysi ei näytä valmistuvan).

Välilehdellä "code patterns" on mahdollista määritellä projektikohtaisesti, mitä tarkastuksia codacy koodille suorittaa. Klikkaamalla oikean yläkulman pudotusvalikosta "your accounts" on mahdollista määritellä kaikkien projektien käyttämät oletusarvoiset tarkastukset.

Lisää vielä joku muu projektisi, esim. ohjelmoinnin harjoitustyö codacyn tarkkailtavaksi ja katso mitä ongelmia koodista löytyy.

Code Climate on codacya vastaava, hieman kauemmin markkinoilla ollut koodin staattisen analyysin verkossa toimiva palvelu. Code Climate ei tue Javaa, mutta on muuten erittäin hyväksi havaittu palvelu.

4. git: branchit

lue brancheja käsittelevät osuudet seuraavasta http://www.ralfebert.de/tutorials/git/

  • jos haluat lukea hieman perusteellisemman selityksen asiasta, lue http://git-scm.com/book:n luku kolme
  • tee samalla kaikki tekstien esimerkit

Kannattaa huomioida myös erittäin hyvä brancheja käsittelevä visuaalinen materiaali osoitteessa http://pcottle.github.com/learnGitBranching/

Varsin selkeältä vaikuttaa myös https://www.atlassian.com/git/tutorials/using-branches

huom: kun liikut branchien välillä kannattaa pitää working tree ja staging -alue tyhjinä!

tee seuraavat paikalliseen git-repositorioosi (kyseessä ei siis tarvitse olla tehtävien palautusrepositorio)

  • luo repositorio ja committaa masteriin tiedosto masteri1.txt
  • luo branch eka, siirry branchiin, luo sinne tiedosto eka.txt ja committaa
  • siirry takaisin master-branchiin, tiedoston eka.txt ei pitäisi nyt näkyä
    • huom: muistutus vielä siitä, että kun siirryt branchista toiseen varmista aina komennolla git status että kaikki muutokset on committoitu
  • lisää ja committaa masteriin tiedosto masteri2.txt
  • mene branchiin eka ja tarkasta, että masteriin lisätty tiedosto ei ole branchissa
  • lisää branchiin tavaraa, esim. tiedosto eka2.txt ja committaa
  • siirry takaisin master-branchiin
  • tarkasta että eka-branchiin lisätyt muutokset eivät ole masterissa
  • tarkastele komennolla gitk --all miltä repositorio ja branchit näyttävät (gitk toimii windowsilla ainakin Github for Windowsin Git Shellissä.)
    • jos käytät Macia voit halutessasi asentaa gitx:n joka on modernisoitu versio gitk-ohjelmasta
    • gitx ei toimi ilmeisesti joissain uusimmissa maceissa, hyvä korvaaja sille on sourcetree
  • mergeä branchin eka sisältö masteriin
  • katso jälleen miltä näyttää gitk --all

5. git: branchit ja staging-alue

  • olet nyt repositoriosi master-haarassa
  • luo uusi tiedosto uusi_tiedosto.txt, älä kuitenkaan lisää ja commitoi tiedostoa
  • komennon git status tulostuksen pitäisi olla seuraava
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	uusi_tiedosto.txt

nothing added to commit but untracked files present (use "git add" to track)
  • siirry nyt branchiin eka
  • suorita uudelleen komento git status
  • huomaat, että tulostus on edelleen sama, tiedosto ei edelleenkään ole versionhallinnan alla
  • eli vaikka olit master-haarassa kun loit tiedoston, ei master-haara eikä koko git tiedä tiedostosta vielä mitään ennen kuin lisäät sen versionhallinnan alaisuuteen komennolla git add
  • lisää tiedosto nyt versionhallinnan alaisuuteen ja commitoi se
  • tiedosto menee nykyiseen branchiisi, eli branchiin eka, master ei edelleenkään tiedä tiedostosta mitään
  • luo uusi tiedosto uusi_tiedosto2.txt ja lisää se versionhallintaan, älä kuitenkaan commitoi
  • tarkasta että komennon git status tulos on
On branch eka
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   uusi_tiedosto2.txt
  • olet siis branchissa eka ja uusi_tiedosto2.txt on lisätty staging-alueelle, sitä ei kuitenkaan ole vielä committoitu
  • siirry nyt branchiin master
  • komennon git status tulos on edelleen sama, uusi_tiedosto2.txt on edelleen staging-alueella mutta committoimattomana
  • staging-alue ei kuulu mihinkään branchiin, eli jos staging-alueella on committoimattomia muutoksia ja vaihdat branchia, säilyvät samat asiat stagingissa
  • muutokset siirtyvät stagingista branchiin ainoastaan komennolla git commit
  • committoi nyt staging-alueen muutokset eli uusi_tiedosto2.txt masteriin
  • komennon git status tulos kertoo nyt että staging-alue on tyhjä:
On branch master
nothing to commit, working tree clean
  • siirry jälleen branchiin eka ja huomaat, että uusi_tiedosto2.txt ei ole olemassa
  • mergeä master branchiin eka
  • siirry nyt masteriin ja tuhoa branchi eka
  • tämän tehtävän ideana oli siis havainnollistaa, että working tree (muutokset joista git ei ole tietoinen) ja staging (gitiin lisättyihin tiedostoihin tehdyt committoimattomat muutokset) eivät liity mihinkään branchiin, muutokset siirtyvät staging-alueelta branchiin ainoastaan komennon git commit suorituksen seurauksena

6. git: konflikti!

tee paikalliseen git-repoon seuraavat

  • lisää master-branchiin tiedosto tarkea.txt, kirjota sinne muutama rivi tekstiä ja committaa
  • tee uusi branchi toka, mene branchiin ja editoi tiedoston tarkea.txt loppua (lisää esim loppuun muutama uusi rivi) ja committaa
  • mene takaisin master-branchiin, editoi tiedoston tarkea.txt alkua (lisää alkuun muutama rivi) ja committaa
  • mergeä branchin toka sisältö masteriin
    • mergeäminen aiheuttaa ns merge-commitin, ja avaa tekstieditorin mihin joudut kirjoittamaan commit-viestin
      • jos et ole määritellyt gitille editoria viime viikon tehtävän 2 ohjeiden mukaan avautuu ehkä gitin oletusarvoinen editori vim
      • vimistä poistuminen saattaa osoittautua ensikertalaiselle hankalaksi, google auttaa tarvittaessa
    • katso tiedoston tarkea.txt-sisältöä, sen pitäisi sisältää nyt molemmissa brancheissa tehdyt muutokset
    • huom: jo tässä vaiheessa saattaa syntyä konflikti jos olet vahingossa muuttanut merkkejä väärästä kohtaa tiedostoa! Toimi tällöin ao. ohjeen mukaan.
  • lisää jotain tiedoston loppuun ja committaa
  • siirry branchiin toka
  • lisää jotain tiedoston tarkea.txt loppuun ja committaa
  • mergeä branchin master sisältö branchiin toka
    • nyt pitäisi aiheutua konflikti, komento aiheuttaa tulostuksen
Auto-merging tarkea.txt
CONFLICT (content): Merge conflict in tarkea.txt
Automatic merge failed; fix conflicts and then commit the result.
  • ratkaise konflikti:
    • editoi tiedoston tarkea.txt sisältö haluamaksesi
    • ja toimi em. artikkelien ohjeen mukaan eli lisää konfliktoinut tiedosto staging-alueelle ja committoi

Jotkut editorit, esim visual studio code sisältävät sisäänrakennetusti ns. merge toolin, joka osaa jossain määrin helpottaa konfliktien ratkaisua:

7. git: branchit ja GitHub

aloita lukemalla ProGit kirjasta luku Remote Branches

branch githubiin:

  • lisää tehtävien palauttamiseen käyttämäsi GitHub-reposition paikalliseen kopioon branchit haara1 ja haara2
  • mene branchiin haara1, lisää sinne tiedosto haara1.txt ja committaa
  • mene branchiin haara2, lisää sinne tiedosto haara2.txt ja committaa
  • pushaa uudet branchit GitHubiin
  • tarkastele GitHub-repositoria selaimella, varmista että branchit syntyvät ja niillä on haluttu sisältö

kloonaa GitHub-repositoriosta koneellesi toinen kopio

  • kuten huomaat, eivät branchit tule kloonattuun kopioon
  • tee paikalliseen kopioon branch joka "träkkää" GitHub:issa olevan projektisi branchia haara1 (ks. http://git-scm.com/book/en/Git-Branching-Remote-Branches kohta Tracking Branches)
  • lisää "träkkäävään" branchiin joku tiedosto, committaa ja pushaa branchi GitHubiin
  • tarkastele GitHub-repositoria selaimella, varmista että branchi päivittyy

mene GitHub-repon alkuperäiseen paikalliseen kopioon

  • mene branchiin haara1 ja pullaa muutokset GitHub:in vastaavasta branchista
    • huom: koska kyseessä ei ole "träkkäävä" branchi, joudut pullaamaan komennolla git pull origin haara1
  • mene branchiin haara2, lisää sitten tiedosto, committaa ja pushaa branchi GitHubiin
    • uudemmilla gitin versioilla pushaus onnistuu suoraan
    • koska kyseessä ei ole "träkkäävä" branchi, ei vanhemmilla gitin versiolla komento git push riitä vaan joudut määrittelemään branchin jonne push kohdistuu eli antamaan komennon git push origin haara2

mene jälleen toiseen kopioon

  • suorita komento git remote show origin
    • komento kertoo 'origin':issa eli githubissa olevien branchien ja paikallisten branchien suhteen
  • tee sinne GitHub:issa olevan projektisi branchia haara2 träkkäävä branch
  • suorita jälleen git remote show origin, mitä muutoksia huomaat?
  • tee branchiin muutoksia ja pushaa ne githubiin
    • huom: koska kyseessä träkkäävä branch, riittää git push
  • tarkastele GitHub-repositoria selaimella, varmista että branchi päivittyy

palaa vielä alkuperäiseen lokaaliin repositorioon

  • suorita komento git remote show origin
  • tulostus kertoo, että lokaaleista haaroista ainoastaan master on konfiguroitu komennon git pull osalta, eli on träkkäävä branchi:
* remote origin
  Fetch URL: git@github.com:mluukkai/ohtu-s2017-v1.git
  Push  URL: git@github.com:mluukkai/ohtu-s2017-v1.git
  HEAD branch: master
  Remote branches:
    haara1 tracked
    haara2 tracked
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local refs configured for 'git push':
    haara1 pushes to haara1 (local out of date)
    haara2 pushes to haara2 (up to date)
    master pushes to master (up to date) 
  • suorita git pull branchissä haara1
  • komennon tuloste antaa ohjeen, miten saat konfiguroitua haara1:n träkkäämään githubissa olevaa haaraa:
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> haara1
 
  • Kun annat komennon, sen jälkeen haara träkkää githubissa olevaa haaraa ja komento git pull voidaan antaa ilman parametreja

Branchien kanssa työskentely voi aluksi tuntua sekavalta varsinkin jos GitHub:issa on myös useita brancheja.

mihin brancheja käytetään?

Ohjelmistotiimi voi käyttää Gitiä hyvin monella eri tyylillä. Artikkeli https://de.atlassian.com/git/tutorials/comparing-workflows esittelee muutamia erilaisia tapoja järjestellä tiimin gitin käyttöön liittyvä workflow. Yksi yleinen tapa branchien käyttöön ovat ns. featurebranchit:

The core idea behind the Feature Branch Workflow is that all feature development should take place in a dedicated branch instead of the master branch. This encapsulation makes it easy for multiple developers to work on a particular feature without disturbing the main codebase. It also means the master branch will never contain broken code, which is a huge advantage for continuous integration environments.

Jos kiinnostaa, lue lisää yo. dokumentista. Tai tästä https://www.javacodegeeks.com/2015/11/git-branching-strategies.html

8. git: epäajantasaisen kopion pushaaminen

Demonstroidaan usein esiintyvää tilannetta, jossa epäajantasaisen repositorion pushaaminen githubissa olevaan etärepositorioon epäonnistuu.

  • mene alkuperäiseen repositorion alkuperäisen kopion master haaraan, tee joku muutos, commitoi ja pushaa se githubiin
  • mene toisen kopion master-haaraan ja tee sinne joku muutos
  • commitoi ja pushaa muutos githubiin
  • kaikki ei kuitenkaan mene hyvin, seurauksena on seuraavantyylinen virheilmoitus:
mbp-18:ohtu-viikko1-2017 mluukkai$ git push
To git@github.com:mluukkai/ohtu-viikko1-2017.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@github.com:mluukkai/ohtu-viikko1-2017.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first merge the remote changes (e.g.,
hint: 'git pull') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
mbp-18:ohtu-viikko1-2017 mluukkai$ 

Virheen syynä on se, että githubissa oleva master-haara oli edellä paikallisen repositorion master-haaraa. Ongelma korjaantuu tekemällä ensin git pull, ratkaisemalla mahdolliset konfliktit ja pushaamalla sitten uudelleen

  • komennon git pull yhteydessä syntyy merge-commit, ja avautuu tekstieditorin mihin joudut kirjoittamaan commit-viestin
  • eli toimi näin ja varmista, että tekemäsi muutokset menevät githubiin

9. riippuvuuksien injektointi osa 3: Verkkokauppa

Tutustuimme viime viikon tehtävissä 14-16 riippuvuuksien injektointiin ja sovelsimme sitä testauksen helpottamiseen.

Jos asia on päässyt unohtumaan, lue uudelleen https://github.com/mluukkai/ohtu2017/blob/master/web/riippuvuuksien_injektointi.md

Kurssirepositorion hakemistossa koodi/viikko2/Verkkokauppa1 on yksinkertaisen verkkokaupan ohjelmakoodi

  • hae esimerkkiprojekti kurssirepositoriosta

    • järkevintä lienee että kloonaat kurssirepositorion paikalliselle koneellesi jos et ole sitä jo tehnyt, jos olet, niin pullaa repositorio ajantasalle
    • tämän jälkeen kannattaa kopioida projekti tehtävien palautukseen käyttämäsi repositorion sisälle
  • tutustu koodiin, piirrä luokkakaavio ohjelman rakenteesta

  • ohjelman luokista Pankki, Varasto, Viitegeneraattori ja Kirjanpito ovat sellaisia, että niistä on tarkoitus olla olemassa vain yksi olio. Tälläisiä ainutkertaisia olioita sanotaan singletoneiksi. Koodissa singletonit ovat toteutettu "klassisella tavalla"

    • Singleton on GoF-kirjan yksi alkuperäisistä suunnittelumalleista, lue lisää singletoneista esim. täältä
    • Singleton ei ole erinäisistä syistä enää oikein muodissa, ja korvaamme sen seuraavassa tehtävässä
  • kuten huomaamme, on koodissa toivottoman paljon konkreettisia riippuvuuksia:

    • Varasto --> Kirjanpito
    • Pankki --> Kirjanpito
    • Kauppa --> Pankki
    • Kauppa --> Viitegeneraatori
    • Kauppa --> Varasto
  • Pura luokan Kauppa konkreettiset riippuvuudet yllämainittuihin luokkiin rajapintojen avulla

    • Riippuvuus luokkaan Ostoskori voi jäädä sillä se on ainoastaan luokan Kauppa sisäisesti käyttämä luokka ja täten varsin harmiton
    • HUOM: NetBeansissa on automaattinen refaktorointiominaisuus, jonka avulla luokasta saa helposti generoitua rajapinnan, jolla on samat metodit kuin luokalla. Klikkaa luokan kohdalla hiiren oikeaa nappia, valitse refactor ja "extract interface"
    • muut riippuvuudet jätetään vielä
  • Määrittele luokalle sopiva konstruktori, jotta voit injektoida riippuvuudet, konstruktorin parametrien tulee olla tyypiltään rajapintoja

  • Älä käytä luokan Kauppa sisällä enää konkreettisia luokkia Varasto, Viitegeneraattori ja Pankki vaan ainoastaan niitä vastaavia rajapintoja!

  • Muokkaa pääohjelmasi, siten että se luo kaupan seuraavasti:

Kauppa kauppa = new Kauppa(Varasto.getInstance(), Pankki.getInstance(), Viitegeneraattori.getInstance() );
  • varmista ohjelman toimivuus suorittamalla se komentoriviltä komennolla gradle run

10. riippuvuuksien injektointi osa 4: ei enää singletoneja verkkokaupassa

  • singleton-suunnittelumallia pidetään osittain ongelmallisena, poistammekin edellisestä tehtävästä singletonit
  • poista kaikista luokista getInstance-metodit ja staattinen instance-muuttuja
    • joudut muuttamaan luokilla olevat private-konstruktorit julkisiksi
  • poista rajapintojen ja dependency injektionin avulla edellisen tehtävän jäljiltä jääneet riippuvuudet, eli
    • Varasto --> Kirjanpito
    • Pankki --> Kirjanpito
  • Muokkaa pääohjelmasi vastaamaan uutta tilannetta, eli suunnilleen muotoon:
Kirjanpito kirjanpito      = new Kirjanpito();
Varasto varasto            = new Varasto(kirjanpito);
Pankki pankki              = new Pankki(kirjanpito);
Viitegeneraattori viitegen = new Viitegeneraattori();
Kauppa kauppa              = new Kauppa(varasto, pankki, viitegen);

Kuten huomaamme, alkaa kaupan konfigurointi olla aika vaivalloista...

11 Spring osa 1: riippuvuuksien injektointi

Spring tarjoaa pelastuksen käsillä olevaan tilanteeseen.

Lue nyt https://github.com/mluukkai/ohjelmistotuotanto2017/blob/master/web/riippuvuuksien_injektointi_spring.md

Tulet todennäköisesti saamaan Springiä käyttäessäsi pitkiä ja kryptiseltä vaikuttavia virheilmoituksia. Lue virheilmoitusten stack trace huolellisesti läpi, yleensä se antaa viheitä siitä, missä vika on. Virheilmoitusten tulkitseminen ja virheiden etsiminen on yksi tärkeimpiä taitoja ohjelmistoalalla, se voi tuntua ikävältä, mutta oikoteitä ei ole. Usein googlailu ja stack owerflow auttavat, mutta kaikesta ei selviä pelkällä trial and error -menetelmällä. Usein käytettävän kirjaston toimintaa on ymmärrettävä jollain tasolla, jotta virheiden jäljitys onnistuu.

Itse käytän virheiden jäljityksessä ns. paranoidimoodia. Jos olen epävarma siitä mitä teen (liittyen koodiin tai konfigurointiin), testaan lähes jokaisen rivin jälkeen, että toiminnallisuus on halutun kaltainen. Varmin keino aiheuttaa paljon kriptisiä virheitä on se, että testaa koodia mahdollisimman harvoin. Tällöin virheiden jäljitys on vaikeaa, sillä lisättyjä rivejä saattaa olla paljon ja virheen aiheuttaja ei välttämättä ole ilmeinen. Tälläisissä tilanteissa kannattaa esim. kommentoida lisätty koodi pois ja palauttaa lisäykset rivi kerrallaan.

12 Spring osa 2: Verkkokauppa siistiksi

Palataan sitten verkkokaupan pariin.

  • projektiin on konfiguroitu valmiiksi springin tarvitsemat riippuvuudet, konfiguraatiotiedosto spring-context.xml löytyy hakemiston src/main/resources alta (NetBeansissa tämä löytyy kohdan Other Sources -alta)
  • HUOM mahdolliset virheilmoitukset "org.springframework... package does not exist" katoavat kun buildaat projektin ensimmäisen kerran!
  • ota mallia yllä olevan linkin ohjeesta ja konfiguroi verkkokauppa Springin xml-muotoista konfiguraatiota siten, että kauppa-olion luominen onnistuu Springin avulla seuraavasti:
public static void main(String[] args) {
    ApplicationContext ctx = new FileSystemXmlApplicationContext("src/main/resources/spring-context.xml");
 
    Kauppa kauppa = ctx.getBean(Kauppa.class);
    //...
}

Kannattanee edetä tehtävässä pienin askelin siirtäen yksi luokka kerrallaan Springin hallinnoinnin alle.

13. Spring osa 3: Verkkokauppa siistiksi annotaatioilla

HUOM tee tämän tehtävän muutokset branchiin nimeltään annotaatio, pushaa branchi githubiin

  • muuta edellistä tehtävää siten, että konfigurointi tapahtuu annotaatioiden @Component ja @Autowired avulla
  • huom:
    • tehtävää ei välttämättä kannata tehdä yhtenä isona askeleena, saattaa olla viisasta muuttaa luokka kerrallaan xml-konfiguraatiosta annotaatiokonfiguroiduksi
    • virheilmoitukset eivät ole noviisille selkeimpiä mahdollisa
    • muista määritellä @Component kaikkiin edellisessä tehtävässä xml:ssä määriteltyihin luokkiin
    • muista laittaa @Autowired jokaiseen luokkaan, jolla on riippuvuuksia

tehtävien kirjaaminen palautetuksi

tehtävien kirjaus:

palaute tehtävistä:

  • tee viikon 1 viimeisessä forkaamasi repositorioon jokin muutos
  • tee viime viikon tehtävän tapaan pull-request
    • anna tehtävistä palautetta avautuvaan lomakkeeseen
    • huom: jos teeh tehtävät alkuviikosta, voi olla, että edellistä pull-requestiasi ei ole vielä ehditty hyväksyä ja et pääse vielä tekemään uutta requestia