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

Compare with Current View Page History

« Previous Version 13 Next »

En valideringsmetode har som formål å sjekke om en eller flere verdier er gyldige, slik at dette kan sjekkes av f.eks. setter-metoder før tilsvarende attributter evt. settes.

Det finnes en rekke ulike måter å kode disse på, med ulike fordeler og ulemper.

Ta som eksempel et attributt for et person-navn, som skal være på minst 2 tegn og bare skal kunne inneholde bokstaver, mellomrom og bindestreker (eng: hyphen). Dette kan sjekkes med en valideringsmetode som returnerer en logisk verdi, true for gyldige verdier og false for ugyldige:

Valideringsmetode som returnerer en logisk verdi
String name;

boolean isValidName(String name) {
	// no name can be less than two characters
	if (name.length < 2) {
		return false;
	}
	// a name can only contain letters, spaces and hyphens
	for (int i = 0; i < name.length(); i++) {
		char c = name.charAt(i);
		if (! (Character.isLetter(c) || c == ' ' || c == '-')) {
			return false;
		}
	}
	return true;
}

void setName(String name) throws IllegalArgumentException {
	if (! isValidName(name)) {
		throw new IllegalArgumentException("A name must be at least two characters and can only contain letters, space or hyphens, but was " + name);
	}
	this.name = name;
}
PersonString nameboolean isValidName(String)void setName(String) throws IllegalArgumentException

 

Problemet med validering er altså delt i to: Valideringsmetoden sjekker gydlighet og setteren kaller valideringsmetoden og utløser et evt. unntaket. Ulempen med denne arbeidsfordelingen er at setteren må angi en melding til unntaksobjektet uten spesifikk kunnskap om hvorfor valideringsmetoden returnerte false. Dermed må feilmelding være generell istedenfor spesfikk for feilen. Et alternativ er derfor å utløse unntaket i valideringsmetoden, istedenfor å returnere true eller false:

String name;

void checkName(String name) throws IllegalArgumentException {
	// no name can be less than two characters
	if (name.length < 2) {
		throw new IllegalArgumentException("The name is too short, it must be at least two characters");
	}
	// a name can only contain letters, spaces and hyphens
	for (int i = 0; i < name.length(); i++) {
		char c = name.charAt(i);
		if (! (Character.isLetter(c) || c == ' ' || c == '-')) {
			throw new IllegalArgumentException("'" + c + "' is an illegal character, a name can only contain letters, space or hyphens");
		}
	}
}

void setName(String name) {
	checkName(name);
	this.name = name;
}
PersonString namevoid checkName(String) throws IllegalArgumentExceptionvoid setName(String)

 

Siden valideringsmetoden ikke lenger returnerer boolean, har vi endre navnet fra å begynne med "is", så nå heter den checkName. Og siden den utløser unntaket, kan setteren forenkles: If'en er unødvendig, dersom checkName utløser unntaket vil ikke tilordningen bli utført og vi trenger ingen if-setning. Ulempen med denne varianten er at det kompliserer andre klasser, siden de ikke kan sjekke verdien gyldigheten av et navn uten å måtte bruke try/catch. Under vises to varianter som løser dette problemet. Den venstre varianten lar valideringsmetoden returnere en meldingstekst eller null, dersom alt er ok. Den høyre varianten lar valideringsmetoden ta et ekstra argument som angir om true/false skal returneres istedenfor å utløse et unntak.

String validateName(String name) {
	// no name can be less than two characters
	if (name.length < 2) {
		return "The name is too short, it must be at least two characters";
	}
	// a name can only contain letters, spaces and hyphens
	for (int i = 0; i < name.length(); i++) {
		char c = name.charAt(i);
		if (! (Character.isLetter(c) || c == ' ' || c == '-')) {
			return "'" + c + "' is an illegal character, a name can only contain letters, space or hyphens";
		}
	}
}

void setName(String name) {
	String message = validateName(name);
	if (message != null) {
		throw new IllegalArgumentException(message);
	}
	this.name = name;
}

Kode som kaller valideringsmetoden må huske meldingen, siden den skal brukes hvis den ikke er null.

boolean validateName(String name, boolean throwException) {
	// no name can be less than two characters
	if (name.length < 2) {
		if (throwException) {
			throw new IllegalArgumentException("The name is too short, it must be at least two characters");
		}
		return false;
	}
	// a name can only contain letters, spaces and hyphens
	for (int i = 0; i < name.length(); i++) {
		char c = name.charAt(i);
		if (! (Character.isLetter(c) || c == ' ' || c == '-')) {
			if (throwException) {
				throw new IllegalArgumentException("'" + c + "' is an illegal character, a name can only contain letters, space or hyphens");
			}
			return false;
		}
	return true;
}

void setName(String name) {
	validateName(name, true);
	this.name = name;
}

Setteren blir enkel, og koden utenfor klassen som ikke ønsker at unntak skal utløses, kaller valideringsmetoden med false som andre argument.

  • No labels