Styxxy schreef op dinsdag 27 april 2010 @ 18:06:
[...]
Je kan ook gewoon programmeren volgens contract (je verwacht dus correcte data in een klasse). Het nadeel is dan weer wel dat je je controles van de data ergens anders moet gaan doen. Nu ja, op zich, als het om interne data gaat, dwing je sowieso al een goede vorm af... het probleem zit 'em dan enkel om user input (dus files, GUI input, etc) juist af te handelen.
Ja, zo zou het wel in een ideale situatie zijn. Helaas werk ik in dit geval met een library van de ontwikkelaars van het CMS die nogal vaak de neiging hebben om null terug te geven. Die EntityManager.find() zijn implementatie bijvoorbeeld, stukje daaruit (geknipt en wat namen veranderd, ik denk niet dat het officieel toegestaan is om zo gedecompliede code te copy / pasten):
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| /* */ public Object find(SomeId primaryKey, SomeObject context)
/* */ {
/* 98 */ Object entityFromCache = getEntityCache().getEntityFromCache(primaryKey);
/* 99 */ if (entityFromCache != null) { // null check. Niet eens heel erg verkeerd hier, maar zou ook vervangen kunnen worden met een hasKey() oid.
/* 100 */ return entityFromCache;
/* */ }
/* */
/* 104 */ EntityDomain entityDomain = getEntityDomain(primaryKey.getClass().getName());
/* 105 */ if (entityDomain == null) { // null controle, getEntityDomain geeft dus ook null terug
/* 106 */ LOG.log(Level.WARNING, "No EntityDomain known id class " + primaryKey.getClass().getName());
/* 107 */ return null; // return null -_-
/* */ }
/* */
/* 111 */ Object entity = entityDomain.find(primaryKey, context);
/* */
/* 114 */ if (entity != null) { // nog een null controle
/* 115 */ getEntityCache().addEntityToCache(entity);
/* */ }
/* */
/* 120 */ return entity; // entity kan ook null zijn als entityDomain.find null teruggeeft
/* */ } |
Eerder in dit topic had ik het over NullObject, nu zal dat misschien niet echt een goed en bruikbaar design pattern zijn... maar ik wordt toch lichtelijk onpasselijk door al die null controles.
Edit: Bijgewerkt zoals ik het liever zou willen zien.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| public Object find(SomeId primaryKey, SomeObject context) {
// controleer of object in cache staat
if (getEntityCache().contains(primaryKey)) {
return getEntityCache.getEntityFromCache(primaryKey);
}
EntityDomain entityDomain = getEntityDomain(primaryKey.getClass().getName());
// neem aan dat getEntityDomain nooit null is. Zo ja, een NullPointerException
// ipv een WARNING, null terugsturen, en een null controle in de aanroeper.
Object entity = entityDomain.find(primaryKey, context);
// addEntityToCache doet niets als entity null is.
getEntityCache().addEntityToCache(entity);
// entity kan hier wel null zijn indien er niks gevonden is.
// Weet nog niet hoe je dat op zou kunnen lossen.
return entity;
} |
En het overdadige gebruik van Integer ipv gewoon int, aangezien er maar knap weinig gebruik gemaakt wordt van de functies die in het Integer object gebruikt worden, én er overal null-controles zijn op het Integer object gevolgd door een >0 check.
Java:
1
2
| Integer ding = doeIets();
if (ding != null && ding > 0) { // doe iets } |
-____-
Nu heb ik zelf een class gemaakt waar helemaal geen nulls teruggegeven worden, die effectief 'dichtgetimmerd' is - nulls komen er niet in (en als die opgestuurd worden, worden ze vervangen met een default waarde) en nulls komen er niet uit. Heel defensief, is ook meer een experiment.
Java:
1
2
3
4
5
6
7
8
9
10
| private void setQuestionAmount(int qamount) {
if (qamount <= 0) {
this.questionAmount = NO_QUESTION_AMOUNT;
} else if (qamount > MAX_QUESTION_AMOUNT) {
LOG.log(Level.WARNING, "Attempted to set question amount > " + qamount + ", defaulted to " + MAX_QUESTION_AMOUNT);
this.setMaxQuestionAmount();
} else {
this.questionAmount = qamount;
}
} |
...en ik praat te veel, ik hou me weer even stil. Of moet ik over dit soort dingen gaan bloggen?
[
Voor 12% gewijzigd door
YopY op 28-04-2010 09:47
]