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

Compare with Current View Page History

« Previous Version 2 Next »

Oppgave a)

 Hva er hensikten med innkapsling?

Innkapsling skal sikre et objekt starter og forblir i en gyldig tilstand og at innholdet kan leses og endres uten å avdekke den interne representasjonen og implementasjonen. Mekanismen er bruk av synlighetsmodifikatorer, som reduserer muligheten (andre) klasser har til å referere til felt og metoder.

Det gis 4 poeng for noe om tilstand og konsistens, 3 poeng for noe om intern representasjon og implementasjon og 5 poeng for begge. Det gis 2 poeng for noe om å beskytte felt.

Oppgave b)

Lag en Date-klasse med metoder for å lese og endre informasjon om dag, måned og år, slik at denne informasjonen blir ordentlig innkapslet og validert. Velg selv konstruktør(er) og metoder som inngår i innkapslingen, egnet intern representasjon og evt. interne hjelpemetoder. Du kan anta det finnes en hjelpemetode som sier om et år er et skuddår. Gjør kort rede for dine valg og husk at det finnes flere fullgode løsninger. 

 

Den enkleste (naive) løsningen er ett int-felt (privat) for hhv. dag, måned og år og get/set-metoder (public) for hver av disse. I hver set-metode bør en validere om endringen vil gi en ugyldig dato, før selve endringen skjer. Denne valideringen er lik for alle set-metodene og bør legges i en egen valideringsmetode (public). Ved feil, bør en bruke en IllegalArgumentException eller RuntimeException, eller en egendefinert subklasse av en av disse. Det er ryddig å ha en egen metode som returnerer antall dager i en måned, gitt året, som kan brukes i valideringsmetoden og i c).

Det kan argumenteres for at det er uheldig å teste for gyldighet av hele tilstanden, når hvert setter kun endrer en bit. Da bør det være en begrunnelse, og valideringsmetoden må være public, slik at ekstern kode kan validere selv. Problemstillingen kan unngås ved å velge én set-metode for all informasjonen, slik at hele tilstanden settes (og valideres) på en gang.

Det trekkes for forenklende antagelser om at alle måneder har 30/31 antall dager e.l. Oppgaven handler ikke bare om innkapsling, men også om kontrollflyt (forgreininger).

Det gis 10 poeng: 2 poeng for get-metoder og set-metode(r), 2 for bruk av valideringskode i set-metode(r), 2 for bruk av unntak, 4 for selve valideringskoden (i egne metoder).

Viser her det første alternativet.

 
public class Date {
	
	private int day, month, year;
	
	public Date(int day, int month, int year) {
		check(day, month, year);
		this.day = day;
		this.month = month;
		this.year = year;
	}
	private boolean isLeapYear(int year) {
		return (year % 4 == 0 && (year % 400 == 0 || year % 100 != 0));
	}
	
	private int numberOfDays(int month, int year) {
		switch (month) {
		case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31;
		case 4: case 6: case 9: case 11: return 30;
		case 2: return (isLeapYear(year) ? 29 : 28);
		}
		return -1;
	}
	private void check(int day, int month, int year) {
		if (day < 1 || day > numberOfDays(month, year)) {
			throw new IllegalArgumentException("day is illegal: " + day);
		}
		if (month < 1 || month > 12) {
			throw new IllegalArgumentException("month is illegal: " + day);
		}
	}
	public int getDay() {
		return day;
	}
	public void setDay(int day) {
		check(day, month, year);
		this.day = day;
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {
		check(day, month, year);
		this.month = month;
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		check(day, month, year);
		this.year = year;
	}
}
Oppgave c)

 Implementer metoder for å endre datoen til neste og forrige dag. Merk at disse metodene skal endre Date-objektet selv, ikke lage nye Date-objekter.

 Det er mest snakk om å holde tunga rett i munnen.

public void nextDay() {
	day++;
	if (day > numberOfDays(month, year)) {
		day = 1;
		month++;
		if (month > 12) {
			month = 1;
			year++;
		}
	}
}
public void previousDay() {
	day--;
	if (day < 1) {
		month--;
		if (month < 1) {
			month = 12;
			year--;
		}
		day = numberOfDays(month, year);
	}
}
Oppgave a)

 

 

Oppgave b)

 

 
Oppgave c)

 

 
Oppgave d)

 

 
Oppgave e)

 

 
Oppgave f)

 

 
Oppgave a)

 

 

Oppgave b)

 

 
Oppgave c)

 

 
Oppgave d)

 

 
Oppgave e)

 

 
Oppgave f)

 

 

 

 

  • No labels