Tehtävien palautuksen deadline su 3.12. klo 23.59 ohjausta tehtävien tekoon to ja pe klo 14-16 salissa B221
- palautusta varten voit käyttää samaa repoa kuin aiemman viikon palautuksissasi
- palautusrepositorion nimi ilmoitetaan tehtävien lopussa olevalla palautuslomakkeella
Jos huomaat tehtävissä tai muussa materiaalissa kirjoitusvirheitä, toimi ohjeen mukaan.
Kannattaa myös lukea ja tarvittaessa täydentää viikon tehtäviin liittyviä vihjeitä
Ennen tehtävien 1 ja 2 tekemistä, lue oliosuunnittelun itseopiskelumateriaalia alusta osan koheesio metoditasolla loppuun. Enempää et tarvitse tämän viikon tehtäviin. Materiaaliin palataan tarkemmin ensi viikon laskareissa.
- Hae kurssirepositorion hakemistossa koodi/viikko5/IntJoukkoSovellus
aloittelevan ohjelmoijan ratkaisu syksyn 2011 Ohjelmoinnin Jatkokurssin viikon 2 tehtävään 3 (ks. http://www.cs.helsinki.fi/u/wikla/ohjelmointi/jatko/s2011/harjoitukset/2/
- ratkaisussa joukko-operaatiot on toteutettu suoraan luokkaan IntJoukko staattisina metodeina
- koodi jättää hieman toivomisen varaa ylläpidettävyyden suhteen
- refaktoroi luokan IntJoukko koodi mahdollisimman siistiksi
- copypaste pois
- muuttujille selkeät nimet
- ei pitkiä (yli 10 rivisiä) metodeja
- koodissa on refaktorointia helpottamaan joukko yksikkötestejä
HUOM refaktoroi mahdollisimman pienin askelin ja pidä koodi koko ajan toimivana. Suorita testit aina jokaisen refaktorointiaskeleen jälkeen! Järkevä refaktorointiaskeleen koko pieni muutos yhteen metodiin.
Kurssirepositorion hakemistossa koodi/viikko5/Tennis, löytyy ohjelma joka on tarkoitettu tenniksen pisteenlaskentaan.
Pisteenlaskennan rajapinta on yksinkertainen. Metodi void getScore()
kertoo voimassa olevan tilanteen tennispisteenlaskennan määrittelemän tavan mukaan. Sitä mukaa kun jompi kumpi pelaajista voittaa palloja, kutsutaan metodia void wonPoint(String player)
jossa parametrina on pallon voittanut pelaaja.
Esim. käytettäessä pisteenlaskentaa seuraavasti:
public static void main(String[] args) {
TennisGame game = new TennisGame("player1", "player2");
System.out.println(game.getScore());
game.wonPoint("player1");
System.out.println(game.getScore());
game.wonPoint("player1");
System.out.println(game.getScore());
game.wonPoint("player2");
System.out.println(game.getScore());
game.wonPoint("player1");
System.out.println(game.getScore());
game.wonPoint("player1");
System.out.println(game.getScore());
}
tulostuu
Love-All
Fifteen-Love
Thirty-Love
Thirty-Fifteen
Forty-Fifteen
Win for player1
Tulostuksessa siis kerrotaan mikä on pelitilanne kunkin pallon jälkeen kun player1 voittaa ensimmäiset 2 palloa, player2 kolmannen pallon ja player1 loput 2 palloa.
Pisteenlaskentaohjelman koodi toimii ja sillä on erittäin kattavat testit. Koodi on kuitenkin luettavuudeltaan erittäin huonossa kunnossa.
Tehtävänä on refaktoroida koodi luettavuudeltaan mahdollisimman ymmärrettäväksi. Koodissa tulee välttää "taikanumeroita" ja huonosti nimettyjä muuttujia. Koodi kannattaa jakaa moniin pieniin metodeihin, jotka nimennällään paljastavat oman toimintalogiikkansa.
Etene refaktoroinnissa todella pienin askelin. Aja testejä mahdollisimman usein. Yritä pitää ohjelma koko ajan toimintakunnossa.
Jos haluat käyttää jotain muuta kieltä kuin Javaa, löytyy koodista ja testeistä versioita useilla eri kielillä osoitteesta https://github.com/emilybache/Tennis-Refactoring-Kata
Tehtävä on kenties hauskinta tehdä pariohjelmoiden. Itse tutustuin tehtävään kesällä 2013 Extreme Programming -konferenssissa järjestetyssä Coding Dojossa, jossa tehtävä tehtiin satunnaisesti valitun parin kanssa pariohjelmoiden.
Lisää samantapaisia refaktorointitehtäviä osoitteessa Emily Bachen GitHub-sivulta
tehtävien 3-6 ei tarvitse näkyä palautuksessa, riittää kun teet tehtävät
- viikon 4 tehtävässä 1 palasimme jo menneisyyteen checkouttaamalla tagillä merkittyyn kohtaan
- katsotaan nyt miten voimme palauttaa jonkun menneisyydessä olevan tilanteen uudelleen voimaan
- tee tiedosto xxx, lisää ja committaa se
- poista tiedosto ja committaa
- tee jotain muutoksia johonkin tiedostoon ja committaa
- historiasi näyttää seuraavalta
(1) - (2) - (3)
-
Nykyhetki eli HEAD on (3). Commitissa (1) tiedosto xxx on olemassa, nykyhetkellä ja (2):ssa xxx:ää ei ole.
- huom: komennolla
gitk
voit tutkia historiaa
- huom: komennolla
-
haluamme palauttaa tiedoston
-
selvitä sen commitin id, jossa tiedosto vielä on olemassa, tämä onnistuu gitk:lla tai
git log
-komennolla -
anna komento
git checkout 3290b03cea08af987ee7ea57bb98a4886b97efe0 -- xxx
missä pitkä merkkijono on siis kyseisen commitin id- varmista että tiedosto on ilmestynyt staging-alueelle komennolla
git status
- varmista että tiedosto on ilmestynyt staging-alueelle komennolla
-
tee commit
-
xxx on palannut!
-
HUOM: koko id:tä ei komennossa tarvitse antaa, riittää antaa alusta niin monta merkkiä, että niiden perusteella id voidaan päätellä yksikäsitteisesti repositoriosi historiassa
- "Generally, eight to ten characters are more than enough to be unique within a project. For example, as of October 2017, the Linux kernel (which is a fairly sizable project) has over 700,000 commits and almost six million objects, with no two objects whose SHA-1s are identical in the first 11 characters." 7.1 Git Tools - Revision Selection
-
Täsmälleen samalla tavalla onnistuu olemassaolevan tiedoston vanhan version palauttaminen.
- huomaamme, että juuri tehty commit oli virhe, kumotaan se sanomalla
git revert HEAD --no-edit
- HEAD siis viittaa siihen committiin minkä kohdalla nyt ollaan
- syntyy uusi commit, jossa edellisessä tehdyt muutokset on kumottu
- ilman optiota no-edit pääset editoimaan kumoamiseen liittyvään commitiin tulevaa viestiä
- huom: sanomalla
git checkout HEAD^
pääsemme takaisin kumottuun tilanteeseen, eli mitään ei ole lopullisesti kadotettu
- vastaavalla tavalla voidaan revertata mikä tahansa commit eli:
git revert kumottavancommitinid
- tee repoosi branchi nimeltä haara ja tee masteriin ja haaraan committeja siten että saat aikaan seuraavankaltaisen tilanteen:
/------master -- \---haara
- eli sekä master että haara ovat edenneet muutamien commitien verran haarautumisen tapahduttua
- huom: komennolla
gitk --all
näet kaikki haarat, kokeile!
- huom: komennolla
- yhtäkkiä huomaat, että master:iin tekemäsi asiat eivät olekaan kovin hyviä ja haara:ssa on paljon parempaa tavaraa, haluaisitkin että haara:sta tulisi uusi master
- tämä onnistuu kun menet masteriin ja annat komennon
git reset --hard haara
- varmista että komento toimii oikein
- vanhan master-haarankaan tavarat eivät katoa mihinkään, jos niihin jostain syystä vielä halutaan palata
- vanhaan committiin palaaminen onnistuu jos commitin id on tiedossa, jos ei on olemassa muutamia keinoja sen selvittämiseksi
Lue http://git-scm.com/book/en/Git-Branching-Rebasing ja https://www.atlassian.com/git/tutorials/rewriting-history#git-rebase
Aikaansaa seuraavankaltainen tilanne
------- master \ \--- haara
"rebeissaa" haara masteriin, eli aikaansaa seuraava tilanne:
------- master \ \--- haara
Varmista komennolla gitk --all
että tilanne on haluttu.
"mergeä" master vielä haaraan:
------- \ master \--- haara
Lopputuloksena pitäisi siis olla lineaarinen historia ja master sekä haara samassa. Varmista jälleen komennolla gitk --all
että kaikki on kunnossa.
Poista branch haara. Etsi googlaamalla komento jolla saat tuhottua branchin.
tehtävien kirjaus:
- Kirjaa tekemäsi tehtävät osoitteeseen https://studies.cs.helsinki.fi/ohtustats
- huom: tehtävien palautuksen deadline on su 3.12. klo 23.59
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