Java specifiek, uitwerking naar aanleiding van de posters in dit topic:
1. Gebruik getypeerde enumeraties ipv integers.
//TODO
2. Maak niet constante variabelen nooit public.
Hiermee zondig je tegen een belangrijke regel van het OO princiepe: encapsulation. Je ontneemt je immers alle mogelijkheden op controle van de variabele en daarmee op consistentie en geldigheid van je object.
Als je je object naar buiten beschikbaar wil maken, doe dit dan via zogenaamde get/set methodes.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| public class MyClass {
// Deze variabele willen we naar buiten beschikbaar maken
//
private String _theString;
public MyClass( String theString ) {
// Gebruik de setMehode ook intern
//
setTheString( theString );
}
/**
* Met deze methode bieden wij een manier aan om de private
* variabele _theString te kunnen veranderen
*/
public void setTheString( String theString ) {
// Hiermee controleren we het object of het wel
// aan onze eisen voldoet. Anders gooien we een
// Exception.
//
if( theString == null )
throw new NullPointerException( "TheString cannot be null" );
_theString = theString;
}
/**
* Met deze methode bieden wij een manier aan om de private
* variabele _theString te kunnen opvragen
*/
public String getTheString( ) {
return _theString( );
}
} |
Voorbeeld 1
In voorbeeld 1 kun je zien dat we volledig in eigen hand houden welke eisen we stellen aan onze String, maar dat hij toch voor iedereen beschikbaar is

Persoonlijk maar ik voor _elke_ private variabele in een classe die ik heb zowel een get als een set methode, en spreek de variabele alleen zo aan binnen de classe. Als je dan niet wilt dat de variabele buiten de classe te benaderen is, dan maak je de get/set methodes gewoon private
Het voordeel hiervan is dat je controles op je variabele maar op 1 plek hebt. Nadeel hiervan is de overhead die de extra methodes opleveren.
3. Geef een methode parameter nooit een nieuwe waarde.
Java kent twee type parameters; by value en by reference.
By value betekend het meegeven van een kopie en met by reference geef je een verwijzing naar de parameter mee.
Standaard worden primitieven by value meegegeven en objecten en array's by reference.
Parameters die dus by reference doorgegeven worden kunnen naar hartelust veranderd en gemuteerd worden.
Wil je dat? Eigenlijk is het antwoord altijd nee. Want waar dient een parameter eigenlijk voor?
Een parameter parameteriseerd een methode. Dat wil dus zeggen dat de methode gespecificeerd wordt door de parameter die meegegeven wordt. Als je dan nog gaat rommelen in je parameter, dan zit je eigenlijk binnen je methode je eigen methode te parameteriseren
4. Gebruik altijd code-blocks bij if, while, for etc.
If, else, while, for werken op expressies. Eigenlijk zouden ze dan ook alleen werken op één enkele opdracht, zoals in het volgende voorbeeld
Java:
1
2
3
| if( thisExpression < thatExpression )
theFirstExpression();
theSecondExpression(); |
Voorbeeld 2
Hierin zal alleen theFirstExpression() bewaakt worden door de if, theSecondExpression zal altijd uitgevoerd worden.
Daarom moet je er voor zorgen dat je de twee expressies kan samenvoegen tot 1. Daarvoor zijn de { } uitgevonden.
Java:
1
2
3
4
| if( thisExpression < thatExpression ) {
theFirstExpression();
theSecondExpression();
} |
Voorbeeld 3
Redelijk basic, maar vaak fout gedaan hier op GoT. Wen jezelf er dus aan altijd { } te gebruiken bij een if/else/where etc. expressie want dan gaat het altijd goed en extra regels code maakt helemaal niets uit bij code

Als je meer programmeer ervaring krijgt, kun je het weg gaan laten als je zeker weet dat je toch maar een expressie gaat (en blijft!) bewaken
5. Vermijd het gebruik van de ... ? ... : ... constructie.
mbravenboer schreef hierover:
Met het afraden van de "expr ? expr : expr" constructie, wil ik absoluut niet het nut van een conditionele expressie bestrijden. Dat nut is er zeker. De syntax die hier voor is gekozen past echter niet in een taal als Java. Het zorgt voor vrijwel de meeste obscure expressies door de plaatsing van het vraagteken achter de eerste expressie en de niet opvallende : tussen de twee mogelijke waarden. Deze onduidelijke syntax zorgt ervoor dat veel mensen het gebruiken van de conditionele expressie afraden, hoe makkelijk deze inderdaad ook is.
Als dit maar genoeg gedaan wordt, komt er misschien iemand langs die zich niet laat meeslepen door de keuzen die gemaakt zijn in klassieke talen. Er is geen enkele reden waarom niet de normale if-then-else syntax gebruikt zou kunnen worden voor conditionele expressies, net zoals deze dus al wordt gebruikt bij conditionele statements.
Hierbij moet ik nog opmerken dat het in het bijzonder gaat om deze syntax in de taal Java: in andere talen zou deze syntax wellicht heel goed passen. In Stratego is er bijvoorbeeld ook een syntax voor conditionele toepassing van een herschrijving: "cs < s1 + s2". Zoals je ziet is het vraagteken hier dus de < en de : de +. Hier zijn redenen voor: Stratego is een heel andere taal is dan de bekende imperatieve talen. Het punt is echter dat ik in Stratego deze constructie niet als obscuur beschouw: hij past goed binnen de andere constructies in Stratego. Bij de ?: in Java ligt dat heel anders, maar ik moet toegeven dat dit allemaal nogal subjectief is.
Mjah.... dat vind ik dus ook
6. Overweeg het gebruik Engelse namen om de code er homogeen uit te laten zien in combinatie met standaard API gebruik.
Enige kanttekening die ik hierbij kan plaatsen is, dat je dat ook alleen moet doen als je wel wat engelse vaardigheden hebt. Door bijv foutieve variabelen namen wordt dan de boel alleen maar onduidelijker. Dan is het misschien slimmer om het toch maar Nederlands te houden
7. Overweeg het gebruik van _ voor klasse variabelen, om een duidelijk onderscheid te maken tussen lokale en klasse variabelen.
8. Vermijd het gebruik van static.
Static wordt gebruikt bij methodes/variabelen die eigenlijk geen verband met een object hebben, maar met een klasse. Denk bijvoorbeeld aan variabelen die gedeeld moeten worden over alle objecten van een classe.
Nu zijn daar natuurlijke fantastische mogelijkheden voor: denk bijvoorbeeld aan constanten of het singleton design pattern:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| public class DatabaseSingleton {
// De unieke databaseinstantie
//
private static DatabaseSingleton _instance = null;
private DatabaseSingleton( ) {
// Initialiseer de database
//
}
/**
* Als er nog geen unieke instantie geinitialiseerd is, doe dat dan
* en return deze instantie
*/
public static DatabaseSingleton getInstance( ) {
if( _instance = null )
_instance = new DatabaseSingleton( );
return _instance;
}
// Meer vrolijke methodes
//
} |
Echter zorgvuldig gebruik van static is wel geboden: static variabelen/methodes horen ook echt alleen bij die classes, bij subclasses zul je ze _niet_ meer terugvinden.
9. Gebruik een Iterator ipv een Enumeration, ArrayList ipv Vector, HashMap ipv Hashtable
Ik hoor veel mensen altijd maar roepen dat ze niet begrijpen wat nou het verschil is tussen Vector en ArrayList. Hiervoor moet ik een klein stukje geschiedenis oprakelen.
In de tijd voor Java 1.2 ( heeeeeel erg vroeger ) programmeerde je Java met allerlei losse datastructuren. Al deze datastructuren hadden weinig gemeen en waren dus totaal niet uitwisselbaar. Als jij in je class een Vector had staan en je wou toch een LinkedList gaan gebruiken, dan mocht jij mooi op verschillende punten in je code gaan hakken met alle risico's vandien.
Toen kwam Java 1.2 en Sun had het licht gezien. Er kwamen opeens gezamelijke interfaces waar een datastructuur aan moest voldoen. Bijvoorbeeld de List voor DataLijsten, Set voor DataLijsten waar geen duplicaten in zitten. Sun had zelfs een overkoepelende interface gemaakt waar alle datastructuren zich aan moeten houden. De 'Collections' waren geboren.
Omdat Vector en HashTable bestonden voordat de Collection interface bestond, zijn deze classes aangepast om te voldoen aan deze interface. Vector implementeert List en HashTable implementeert de interface Map. Echter er waren eerst ook vervangers voor deze classes gemaakt, nl. ArrayList en HashMap (welke qua naam beter beschrijven dan Vector en HashTable) Eigenlijk zijn Vector en HashMap toen om 'legacy' redenen blijven hangen toen.
Het enige verschil wat nog overbleef was dat Vector en HashTable beide syncronized (en dus thread safe waren) en de 'nieuwe' implementaties ArrayList en HashMap niet, net als alle andere collection classes.
Waarom nu HashMap en ArrayList gebruiken?
• Consitentie met de rest van de rest van de collections
• Beter uitwisselbaar met de rest van de collections ( door synchronisatie 'oude' )
• Ontbreken legacy methodes
Door het gebruik van Collection classes ben je eigenlijk ook verplicht Enummeration te laten vallen en Iterator te gaan gebruiken. Simpelweg omdat Collections Iteratoren geven ipv Enummerations. (Gebruik die ook, om je los te koppelen van de implementatie!)
Wat is er enorm verbeterd aan Enummeraties in Iteratoren dan?
Sun zegt er dit over.
An iterator over a collection. Iterator takes the place of Enumeration in the Java collections framework. Iterators differ from enumerations in two ways:
• Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
• Method names have been improved.
Feitelijk komt het neer op een optie om Objecten uit een Collection te verwijderen, zodat je niet alleen de Collectie kan lezen zonder de implementatie te kennen, maar ook kan wijzigen.
10. Gebruik een StringBuffer als je over meerdere statements een String moet opbouwen. Als je een String in 1 statement optelt, wordt dit automatisch gedaan.
Strings zijn immutable. Als je er eenmaal een aantal characters ingestopt hebt, kun je dat niet meer wijzigen.
//TODO: Hier nog ff een mooi voorbeeldloopje zetten
11. Gebruik zoveel mogelijk maar 1 return statement in een methode.
12. Schrijf korte methoden. Als een methode duidelijk meerdere taken verricht, moet je overwegen om dit op te splitsen.
13. Eet je exceptions nooit op door ze simpel naar de System.out te schrijven. Gooi ze zover door als noodzakelijk is.
14. Roep altijd de super constructor aan.
[
Voor 39% gewijzigd door
Glimi op 31-01-2003 22:50
]