You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Denne oppgaven handler om en Person-klasse med en 1-n-assosiasjon med rollene children og mother/father til samme klasse (altså barn-mor/far-forhold) og det å sikre konsistens, slik at foreldre og barn er korrekt knyttet sammen.

En viktig del av det å implementere assosiasjoner er å sikre konsistens, dvs. at objekter i hver ende av en kobling refererer korrekt til hverandre. Et eksempel på dette for 1-n-assosiasjoner er foreldreskap, hvor foreldre og barn er koblet til samme i et slektstre. I denne oppgaven skal en Person-klasse implementeres og de å legge til (og fjerne) barn håndteres korrekt, som illustrert nedenfor.

Person-klassen skal inneholde informasjon om navn (en String) og kjønn (en char, 'F' eller 'M'), som bare skal kunne settes i konstruktøren, og mor, far og barn, som er andre Person-objekter. Navnet er ikke viktig for oppførselen, men er grei å ha med i en toString()-metode, for å skille Person-objektene fra hverandre. Person-klassen skal ha følgende metoder for å lese tilstanden:

  • getName() - returnerer navnet knyttet til dette Person-objektet
  • getGender() - returnerer tegnet som representerer kjønnet, enten 'F' eller 'M'
  • getMother() - returnerer Person-objektet som er moren, evt. null
  • getFather() - returnerer Person-objektet som er faren, evt. null
  • getChildCount() - returnerer antall barn dette Person-objektet har
  • getChild(int n) - returnerer barn nr. n (altså et Person-objekt), evt. utløser (et passende) unntak om n er for stor (eller liten)

Person-klassen har to sett med endringsmetoder, knyttet til de to rollene i hver ende av children-mother/father-assosiasjonen.

Fra children-perspektivet har vi følgende to metoder:

  • addChlid(Person) - oppretter en kobling til et barn (et annet Person-objekt). Dersom Person-objektet som metoden kalles på, er en kvinne, så skal denne bli barnets mor, og motsatt, dersom Person-objektet som metoden kalles på, er en mann, så skal denne bli barnets far.
  • removeChild(Person) - fjerner en kobling til et barn (et annet Person-objekt). Dersom Person-objektet som metoden kalles på, er moren til argumentet, så skal mother-koblingen fjernes, og motsatt, dersom Person-objektet som metoden kalles på, er argumentets far, så skal father-koblingen fjernes.

Fra mother/father-perspektivet har vi følgende to metoder:

  • setMother(Person) - setter argumentet (en kvinne) som moren til Person-objektet som metoden kalles på. Argumentet får samtidig registrert Person-objektet som metoden kalles på, som sitt barn.
  • setFather(Person) - setter argumentet (en mann) som faren til Person-objektet som metoden kalles på. Argumentet får samtidig registrert Person-objektet som metoden kalles på, som sitt barn.

Det som er verd å merke seg er at begge sett med metoder, addChild/removeChild og setMother/setFather, må ha logikk som håndterer koblingen den andre veien, så addChild/removeChild må kalle setMother/setFather og omvendt, eller ha kode med tilsvarende effekt. Dette kan være nokså fiklete, fordi en både må sikre konsistens og unngå uendelig nøstede kall (inntil du får StackOverflowException).

Figurene under illustrerer tilfellene som må kunne håndteres, og som testes av testene det er lenket til.

hallvard: Personmarit: Personjens: Person

 

 

marit.addChild(jens)

hallvard.addChild(jens)

hallvard: Personmarit: Personjens: Personp12childrenmotherchildrenfather

Opprettelse av koblinger med addChild.

(Samme effekt som under)

hallvard: Personmarit: Personjens: Person

 

 

jens.setMother(marit)

jens.setFather(hallvard)

hallvard: Personmarit: Personjens: Personchildrenmotherchildrenfather 

Opprettelse av koblinger med setMother og setFather.

(Samme effekt som over)

hallvard: Personmarit: Personjens: Personchildrenmotherchildrenfather

 

 

marit.removeChild(jens)

hallvard.removeChild(jens)


hallvard: Personmarit: Personjens: Person

 

 

Fjerning av koblinger med addChild.

(Samme effekt som under)

hallvard: Personmarit: Personjens: Personmaritjenshallvardchildrenmotherchildrenfather  

jens.setMother(null)

jens.setFather(null)

hallvard: Personmarit: Personjens: Person

Fjerning av koblinger med setMother og setFather.

(Samme effekt som over)

Oppgaven er delt i to trinn, den første håndterer children- og mother/father-rollen isolert og uten krav om konsistens, mens det andre skal sikre konsistens.

Trinn 1

  • Implementer addChild- og removeChild-metodene slik at getChildCount- og getChild-metodene virker som forventet. Disse metodene håndterer altså kun children-rollen.
  • Implementer setMother- og setFather-metodene slik at getMother- og getFather-metodene virker som forventet. Disse metodene håndteres altså kun mother/father-rollen.

Test metodene ved å koble opp Person-objekter tilsvarende din egen familie. Du blir nødt til å bruke de tre metodene addChild, setMother og setFather. Prøv å få med minst tre generasjoner.

Trinn 2

Utvid metodene til å sikre konsistens. Test at det fortsatt virker å koble opp din egen familie, denne gangen ved å bare bruke addChild og ved å bare bruke setMother og setFather.

 

JExercise-testkode for denne oppgaven finner du her: objectstructures/PersonTest.java.


JExercise lar deg sjekke din egen kode vha. forhåndslagde JUnit-tester og JExercise-panelet

Bruk av JExercise:

  1. Sørg for at jexercise-standalone.jar er lagt til i ditt prosjekts Build Path. Dette må gjøres hver gang du oppretter et nytt prosjekt, og det er derfor lurt å gjenbruke samme prosjekt til alle oppgaver.
  2. JExercise-tillegget må være installert. Installer tillegget fra følgende oppdateringsadresse: http://folk.ntnu.no/hal/dev/updatesite.
  3. Åpne JExercise-panelet via Window -> Show View -> Other, og navigere deg fram til JExercise i vinduet som kommer opp, velge det og klikke OK.
  4. Klikke og dra oppgavens testklasse, <oppgavenavn>Test.java fra pakkeoversikten og slippe den i JExercise panelet. 
  5. Testene kan så kjøres ved å dobbeltklikke på testen som ønskes kjørt.

Ved trøbbel, se først om du finner løsningen i Løsninger på trøbbel med JExercise.

Unknown macro: {html}

Twitre gjerne om oppgaven når du er ferdig: <a href="https://twitter.com/share" class="twitter-share-button" data-hashtags="jexercise">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>

  • No labels