Regels Aggregates
Een aggregate is een groep objecten die allen als geheel aangepast mag worden. Hiermee garandeer je dat de data in deze groep altijd aan bepaalde regels voldoet. Deze regels drukken we uit in één of meerdere invarianten. De invarianten volgen uit kennis over het domein.
Maak een aggregate van objecten die kunnen veranderen, maar samen wel altijd één of meerdere invarianten moeten bewaken.
Een aggregate heeft altijd één object waarmee objecten buiten de aggregate data binnen de aggregate kunnen aanpassen. Dit object noemen we de aggregate root.
Als een aggregate uit één klasse bestaat, is deze klasse automatisch de aggregate root.
Objecten buiten een aggregate mogen alleen een verwijzing hebben naar de aggregate root en niet naar andere objecten binnen de aggregate.
Alle objecten binnen een aggregate mogen wel een verwijzing hebben naar aggregate roots van andere aggregates
Een app-object haalt altijd in één keer de hele aggregate (dus aggregate root en alle andere objecten waar deze gebruikt van maakt) op uit een Store en slaat deze ook in één keer op.
Een app-object kan alleen aggregate roots ophalen en persisteren (=opslaan). Andere objecten binnen een aggregate kunnen niet los opgehaald of opgeslagen worden.
Een aggregate root moet altijd een id hebben dat gebruik kan worden om de betreffende aggregate op te halen uit een Store. Deze id moet uniek zijn binnen de hele aggregate.
Andere objecten binnen een aggregate hoeven geen id te hebben, maar dat mag wel. Dit id hoeft dan alleen uniek te zijn binnen de aggregate.
Over het algemeen geldt dat hoe meer objecten er in een aggregate zitten, hoe trager een applicatie kan worden omdat er meer objecten uit de Store in het geheugen van de applicatie geladen moeten worden.
Het kiezen van geschikte aggregate heeft ook veel invloed op een applicatie waar meerdere gebruikers tegelijkertijd gebruik van maken (zoals bijna elke web applicatie). Komende week gaan we hier dieper op in.
Er zijn geen geneste aggregates. Dat betekent dat er geen aggregates binnen aggregates gemaakt kunnen worden.
Voorbeeld
Een voorbeeld voor een casus van een Open dag op het HBO waar de bezoekers (aspirant HBO-studenten) zich kunnen inschrijven* voor een aantal workshops, gegeven door HBO docenten. Als er voldoende aanmeldingen zijn start wat later de workshop, maar als aanmeldingen uitblijven wordt de workshop geannuleerd. De entiteit 'Docent' is bewust buiten de applicatie en opdracht gehouden, omdat dit via een 'papieren' systeem gaat (in ieder geval voorlopig ;) ).
We bespreken 3 mogelijke 'aggregate groeperingen' met in het hoofd dat er drie mogelijke aggregates: Bezoeker, Workshop en Aanmelding.
*Merk op dat de uitwerkingen hieronder 'aanmelden' gebruikt i.p.v. 'inschrijven'. Dit is een potentiele bron van verwarring en schending van de 'ubiquitous language'. In sommige domeinen is 'inschrijven' wat je online doet, en 'aanmelden' wat je op de dag zelf doet (o.b.v. een inschrijfbevestiging in je mail bijvoorbeeld). In deze casus zijn het twee synoniemen en hoeven studenten zich terplekke niet meer te identificeren, dus maakt het nu niet uit, maar dit ter illustratie van belang van precieze woordgebruik en hoe snel dit misgaat.
Optie A: Aanmelding bij Bezoeker
Optie B: Aanmelding bij Workshop
Een andere optie is deze groepering, met eigen voor- en nadelen afhankelijk van de wensen voor de beoogde applicatie (de invarianten die bewaakt moeten wo).
Optie C: Apart Object AanmeldingsManager
Als je meerdere invarianten wilt bewaken voor verschillende entiteiten kun je soms een centraal nieuw object instellen.
Dit heeft echter ook nadelen qua performance en complexiteit.
❓ Maak de quiz om te kijken of je de regels van een Aggregate begrijpt en kan herkennen in bovenstaand voorbeeld.