Ik probeer om de perfecte applicatie te maken.. voor zover die bestaat
, voor een java (SCJD) certificaat. (Ik zal deze taal dan ook gebruiken de voorbeelden hieronder.)
Ik heb het idee dat ik een mooie applicatiestructuur heb gemaakt, maar begin na mijn initiele opzet een beetje tegen problemen aan te lopen met betrekking tot hoeveel kennis classes van elkaar mogen hebben. Waar ik eerder tegen dit soort problemen aanliep loste ik dat wat pragmatisch op door klassen soms wel wat meer kennis van elkaar te laten hebben (law is eigenlijk een iets te zwaar woord).
Nu ik programmeer voor een certificaat, wil ik eigenlijk naar een soort ideaal-oplossing toe. Ik ben me er terdege van bewust dat dat nogal situatie-afhankelijk kan zijn en dat 'ideaal' een moeilijk te definieerbaar begrip is, dat hangt tussen verschillende belangen, maar wil toch zoveel mogelijk 'algemene' waarheden op tafel krijgen. Om die reden heb ik er ook voor gekozen om niet eerst 500 woorden te verspillen aan mijn specifieke situatie, maar een leuk algemeen probleem brengen.
compleet uit de lucht gegrepen voorbeeld
Stel, je bent als farao een piramide aan het bouwen en alles gaat prima. Op een zeker dag wil je graag een lijst maken van de voor en achternaam van alles slaven die je onder je hebt werken en je weet dat dat er een archivaris is die die gegevens in een handomdraai op een tabletje kan beitelen. De normale flow naar deze archivaris toe, zou zijn:
farao > generaal > aannemer > onderaannemer voor archieven > personeelsafdeling > archivaris > personeelsLijst.
Als al deze personen meteen ook classes, met getters zijn, breekt dat de 'law of demeter', die kan worden beschreven als 'een class mag geen kennis hebben van een class waarmee geen directe relatie is' (of anders gezegt, je mag niet meer dan 1 getter achter elkaar gebruiken. Eea staat hier prachtig uitgelegt.
oplossing(?)
De enige -een beetje- nette oplossing die ik dan kan verzinnen is door iedereen een functie te geven waarmee die gegevens opgehaald kunnen worden:
• bij de farao:
• bij de generaal:
• bij de ..
geeft wel heeeel veel overhead. Ik probeer juist het aantal klassen wat te beperken. Als we vervolgens naast de personeelslijst ook nog een overzicht willen hebben van gewerkte uren, bij een administratie-gedeelte en daarna nog een overzicht waarin staat wat er nog nodig is om de piramide af te krijgen, dan heb je zo een handvol klassen die stampvol staan met dit soort functies. Als je nu de functie aan wilt passen en je bijvoorbeeld getPersoneelsLijst hernoemt naar getPersoneelSet, dan moet je dat op 6 plaatsen aanpassen.. Granted, het wordt makkelijker als je bv op een of ander niveau een management laag wilt toevoegen of verwijderen, maar nog steeds: Het voelt.. vies.
Een stapje verder
Ik heb in mijn applicatie alle functies die het equivalent van de generaal nodig hebben in een service-class gezet. Nou moet ik echter in mijn farao-class overal zeggen:
(tegen de regels van demeter, maar duidelijk en je hoeft maar op 1 plaats aanpassingen te doen)
of in de service-class
waarnbij ik dus alle requests direct doorstuur naar de generaal class. Vooral als je voor al je public classes weer documentatie moet gaan maken (javadoc), voelt dat heel onpraktisch.
Ik heb de neiging om de 'law of demeter' te blijven zien als een richtlijn en te gebruiken waar deze praktisch is (en dat ook uitgebreid documenteren), maar omdat ik ook graag een (nog!
) betere programmeur wil worden, hoop ik hierin iets van jullie te leren. Hoe gebruiken jullie de law of demeter?
Ik heb het idee dat ik een mooie applicatiestructuur heb gemaakt, maar begin na mijn initiele opzet een beetje tegen problemen aan te lopen met betrekking tot hoeveel kennis classes van elkaar mogen hebben. Waar ik eerder tegen dit soort problemen aanliep loste ik dat wat pragmatisch op door klassen soms wel wat meer kennis van elkaar te laten hebben (law is eigenlijk een iets te zwaar woord).
Nu ik programmeer voor een certificaat, wil ik eigenlijk naar een soort ideaal-oplossing toe. Ik ben me er terdege van bewust dat dat nogal situatie-afhankelijk kan zijn en dat 'ideaal' een moeilijk te definieerbaar begrip is, dat hangt tussen verschillende belangen, maar wil toch zoveel mogelijk 'algemene' waarheden op tafel krijgen. Om die reden heb ik er ook voor gekozen om niet eerst 500 woorden te verspillen aan mijn specifieke situatie, maar een leuk algemeen probleem brengen.
compleet uit de lucht gegrepen voorbeeld
Stel, je bent als farao een piramide aan het bouwen en alles gaat prima. Op een zeker dag wil je graag een lijst maken van de voor en achternaam van alles slaven die je onder je hebt werken en je weet dat dat er een archivaris is die die gegevens in een handomdraai op een tabletje kan beitelen. De normale flow naar deze archivaris toe, zou zijn:
farao > generaal > aannemer > onderaannemer voor archieven > personeelsafdeling > archivaris > personeelsLijst.
Als al deze personen meteen ook classes, met getters zijn, breekt dat de 'law of demeter', die kan worden beschreven als 'een class mag geen kennis hebben van een class waarmee geen directe relatie is' (of anders gezegt, je mag niet meer dan 1 getter achter elkaar gebruiken. Eea staat hier prachtig uitgelegt.
oplossing(?)
De enige -een beetje- nette oplossing die ik dan kan verzinnen is door iedereen een functie te geven waarmee die gegevens opgehaald kunnen worden:
• bij de farao:
Java:
1
| public List<Persoon> getPersoneelsLijst() { generaal.getPersoneelsLijst(); } |
• bij de generaal:
Java:
1
| public List<Persoon> getPersoneelsLijst() { aannemer.getPersoneelsLijst(); } |
• bij de ..
geeft wel heeeel veel overhead. Ik probeer juist het aantal klassen wat te beperken. Als we vervolgens naast de personeelslijst ook nog een overzicht willen hebben van gewerkte uren, bij een administratie-gedeelte en daarna nog een overzicht waarin staat wat er nog nodig is om de piramide af te krijgen, dan heb je zo een handvol klassen die stampvol staan met dit soort functies. Als je nu de functie aan wilt passen en je bijvoorbeeld getPersoneelsLijst hernoemt naar getPersoneelSet, dan moet je dat op 6 plaatsen aanpassen.. Granted, het wordt makkelijker als je bv op een of ander niveau een management laag wilt toevoegen of verwijderen, maar nog steeds: Het voelt.. vies.
Een stapje verder
Ik heb in mijn applicatie alle functies die het equivalent van de generaal nodig hebben in een service-class gezet. Nou moet ik echter in mijn farao-class overal zeggen:
Java:
1
2
3
| service.getGeneraal().getPersoneelsLijst(); service.getGeneraal().getGewerkteUren(); service.getGeneraal().getMateriaalLijst(); |
(tegen de regels van demeter, maar duidelijk en je hoeft maar op 1 plaats aanpassingen te doen)
of in de service-class
Java:
1
2
3
| public void getPersoneelsLijst() { generaal.getPersoneelsLijst(); } public void getGewerkteUren() { generaal.getGewerkteUren(); } public void getMateriaalLijst() { generaal.getMateriaalLijst(); } |
waarnbij ik dus alle requests direct doorstuur naar de generaal class. Vooral als je voor al je public classes weer documentatie moet gaan maken (javadoc), voelt dat heel onpraktisch.
Ik heb de neiging om de 'law of demeter' te blijven zien als een richtlijn en te gebruiken waar deze praktisch is (en dat ook uitgebreid documenteren), maar omdat ik ook graag een (nog!
Localhost is where the heart is