Domein Model, glossary naar DDD, Design thinking en meer

DatumWijziging
18-11-2025Uitbreiding met subset relatie tussen probleem- en oplossingsdomein, privacy by design en koppeling aan DDD/Design Thinking. Toevoeging van leeswijzer, sectienummers, opdrachten voor eigen casus, korte uitwijding over ethische aspecten en uitleg over doelgroep (niet-technische stakeholders).

Deze pagina behandelt het opstellen van een domein model en een glossary bij de start van een software development project. Het domein model past goed bij methoden als Domain-Driven Design (DDD), maar sluit ook aan bij Design Thinking, die Product en Media Design professionals ook gebruiken. Beide benadrukken het belang van eerst het probleem goed te begrijpen voordat je naar oplossingen kijkt. Je leert het onderscheid tussen probleemdomein en oplossingsdomein, en hoe je een domein model kunt vertalen naar software-architectuur. De pagina bevat een uitgebreide casus over een bibliotheeksysteem met verschillende varianten van domeinmodellen als voorbeeld. Belangrijk: Pas deze theorie toe op je eigen projectcasus. Sectie 1 behandelt het conceptuele onderscheid tussen probleem- en oplossingsdomein, sectie 2 gaat over datatypes en terminologie, sectie 3 behandelt subdomeinen en bounded contexts, en sectie 4 bevat concrete voorbeelden van domeinmodellen voor de bibliotheek casus.

Bij de start van het project (kick-off en eerste sprint) is het belangrijk om het domein goed te begrijpen. Daarom wordt er in de eerste sprint een domein model opgesteld, samen met een glossary (woordenlijst).

Een domein model is een visuele representatie van de belangrijkste concepten, entiteiten en hun relaties binnen het probleemdomein. Het is primair een communicatiemiddel, niet een tussenstap in het ontwerp. Larman (2004) noemt het ook wel een "visual dictionary". Het helpt het team om een gedeeld begrip te ontwikkelen van de businesslogica. Na validatie met niet-technische stakeholders vormt het de basis voor de software-architectuur. De glossary is een tabel met belangrijke termen uit het domein en hun uitleg, wat helpt om ambiguïteit te voorkomen en een gemeenschappelijke taal te ontwikkelen.

Belangrijk: Domeinmodellen moeten klein en overzichtelijk blijven. In Larman's boek staan alleen maar kleine diagrammen - dit is bewust, niet omdat Larman niet kan modelleren. Modellen zijn ook voor mensen met beperkte (cognitieve) capaciteit.

Als het model te groot wordt, kun je het opsplitsen in subdomeinen volgens Domain-Driven Design (DDD) principes. Studenten die DDD patterns zoals Aggregate hebben gehad, kunnen hier ook naar vooruit denken bij het opsplitsen in subdomeinen. Een domein model ter grootte van een A4-vel is de maximale grootte om te lezen en te bespreken.

DDD Strategic Design Patterns

Figuur 0: Domain-Driven Design (DDD) Strategic Design Patterns - Ubiquitous Language, Bounded Context en Context Mapping (Lambrych, 2024). Zie ook sectie 3 voor uitleg over subdomeinen en bounded contexts, en criterium DM-6 voor meer informatie over Context Mapping.

Figuur 0: Domain-Driven Design (DDD) Strategic Design Patterns - Ubiquitous Language, Bounded Context en Context Mapping (Lambrych, 2024). Zie ook sectie 3 voor uitleg over subdomeinen en bounded contexts, en criterium DM-6 voor meer informatie over Context Mapping.

Let op: Het domein model bevindt zich in het probleemdomein, niet in het oplossingsdomein. Het gaat om de concepten en relaties in de business/wereld, niet om software classes of models in de code. Het domein model helpt om het probleem te begrijpen voordat je naar de oplossing (software) kijkt. Uiteraard is er wel een relatie tussen het probleemdomein en het oplossingsdomein te maken. In de Realisatie fase kun je nog wel een domain layer met models/entities maken en een DB datamodel opstellen (bijvoorbeeld in je Software Guidebook), waarin stukken uit het domein model terug te vinden zijn.

1. Probleemdomein vs. Oplossingsdomein - Subset relatie

Het oplossingsdomein is vaak een subset van het probleemdomein (zie verzamelingenleer: een subset is een deelverzameling waarbij alle elementen van de subset ook in de oorspronkelijke verzameling zitten). Dit betekent dat niet alle concepten en attributen uit het probleemdomein automatisch in het oplossingsdomein terechtkomen.

Voorbeeld: Klant entiteit

Bijvoorbeeld, een Klant in het probleemdomein heeft mogelijk veel meer eigenschappen dan nodig zijn voor de software:

  • Naam en klantnummer → wel nodig in oplossingsdomein
  • Favoriet boekentype (bijvoorbeeld "science fiction" of "thriller") → mogelijk niet nodig voor MVP, maar kan later worden toegevoegd voor personalisatie
  • Speelcomputer type (bijvoorbeeld "Nintendo", "PlayStation" of "PC") → bepaalt welk type games de klant typisch leent, maar mogelijk niet nodig voor eerste versie
  • Geslacht (hij/zij/anders) → niet nodig voor functionaliteit, en vanuit privacy by design principe slaan we dit niet op tenzij er een goede reden is (bijvoorbeeld voor gepersonaliseerde aanhef in brieven/e-mails bij overschreden leenlimiet)

Deze "kandidaatvelden" kunnen in latere sprints/releases worden toegevoegd via extra features, maar worden bewust weggelaten in de eerste versie om het model simpel te houden en privacy te beschermen.

Ethische overwegingen:

Bij het kiezen wat je wel of niet implementeert, speelt niet alleen technische haalbaarheid of functionele noodzaak een rol, maar ook ethische overwegingen. Dit sluit aan bij de HAN speerpunten slim, schoon en sociaal:

  • Slim: Technisch gezien kun je veel data verzamelen en analyseren, maar dat betekent niet dat je dat ook moet doen
  • Schoon: Door alleen noodzakelijke data op te slaan, voorkom je onnodige complexiteit en potentieel misbruik
  • Sociaal: Het beschermen van privacy en voorkomen van discriminatie en profilering is een maatschappelijke verantwoordelijkheid

Niet alles wat je kunt meten, moet je ook willen opslaan. Denk kritisch na over de gevolgen van het verzamelen en gebruiken van data, vooral wanneer dit kan leiden tot profilering of discriminatie van gebruikers.

Klant - Probleemdomein vs Oplossingsdomein

📋 PlantUML Code - Klant Probleemdomein vs Oplossingsdomein
@startuml
!theme plain
skinparam classAttributeIconSize 0

' Probleemdomein (volledig)
class Klant_Probleemdomein {
  - naam
  - klantnummer
  - favorietBoekentype
  - speelcomputerType
  - geslacht
}

' Oplossingsdomein (subset)
class Klant_Oplossingsdomein {
  - id: Long
  - naam: String
  - klantnummer: String
}

note right of Klant_Probleemdomein
  **Probleemdomein - Volledige Klant:**
  
  - naam: nodig voor identificatie
  - klantnummer: nodig voor identificatie
  - favorietBoekentype: niet nodig voor MVP,
    kan later worden toegevoegd voor
    personalisatie features
  - speelcomputerType: bepaalt welk type
    games klant leent, maar niet nodig
    voor eerste versie
  - geslacht: niet nodig voor functionaliteit,
    privacy by design - slaan we niet op
    tenzij nodig voor gepersonaliseerde
    aanhef in communicatie
end note

note right of Klant_Oplossingsdomein
  **Oplossingsdomein - Subset:**
  
  Alleen attributen die nodig zijn
  voor de functionaliteit van de MVP.
  
  Kandidaatvelden kunnen in latere
  sprints/releases worden toegevoegd.
end note

Klant_Probleemdomein ..|> Klant_Oplossingsdomein : subset
@enduml

Opdracht: Identificeer voor je eigen projectcasus minimaal drie entiteiten uit het probleemdomein. Voor elke entiteit, maak een lijst van attributen die:

  • Wel nodig zijn in het oplossingsdomein (voor de MVP)
  • Mogelijk niet nodig zijn voor de MVP, maar later kunnen worden toegevoegd
  • Ethisch niet wenselijk zijn om op te slaan (bijvoorbeeld vanwege privacy by design)

Design Thinking en Double Diamond

Dit onderscheid tussen probleemdomein en oplossingsdomein komt overeen met het Double Diamond model uit design thinking. Dit model beschrijft twee fasen van divergeren (verbreden) en convergeren (vernauwen):

  1. Probleemdomein (Problem Space):

    • Discover (divergeren): Verken het probleem breed, verzamel informatie
    • Define (convergeren): Definieer het kernprobleem
  2. Oplossingsdomein (Solution Space):

    • Develop (divergeren): Verzin verschillende oplossingen
    • Deliver (convergeren): Kies en implementeer de beste oplossing

Let op: Er zijn verschillende varianten van design thinking. De Double Diamond gebruikt 4 fasen (Discover, Define, Develop, Deliver), terwijl andere modellen zoals die van Stanford d.school 5 fasen gebruiken: Empathize, Define, Ideate, Prototype en Test. Beide modellen hebben hetzelfde doel: eerst het probleem goed begrijpen voordat je naar oplossingen kijkt.

De double diamond

Figuur 1: Double Diamond model - Probleemdomein (Problem Space) en Oplossingsdomein (Solution Space) (Gupta, z.d.)

De take away van dit verhaal is dat je bij het maken van software een goede balans moet vinden tussen het probleem voldoende goed begrijpen (zodat je niet een ander probleem oplost dan de opdrachtgever bedoelde) en pragmatisch een zo simpel mogelijke oplossing realiseren (zodat je niet strandt in analysis paralysis of accidental complexity).

"Everything should be made as simple as it can be, but not simpler." — Albert Einstein

Opdracht: Verzin voor deze casus nog enkele velden uit het probleemgebied die wel in het probleemdomein voorkomen maar niet in het oplossingsdomein.

💡 Tip: Denk eerst zelf na voordat je de antwoorden bekijkt! Sleep met je muis over het blok hieronder (of tik en houd ingedrukt op mobiel) om de voorbeelden te zien.

Voorbeelden voor verschillende entiteiten

Klant:

  • Leeftijd → niet nodig voor MVP, mogelijk later voor leeftijdsrestricties bij games
  • Postcode → niet nodig voor MVP, mogelijk later voor statistieken of lokale promoties
  • Email voorkeur (wel/niet nieuwsbrief) → niet nodig voor MVP, mogelijk later voor marketing
  • Aantal kinderen → bepaalt mogelijk welke boeken klant leent, maar niet nodig voor eerste versie

Uitleenitem:

  • BoekBeschadigScore (per klant) → een bibliotheek zou kunnen denken aan het bijhouden van een score per klant van hoeveel beschadigde boeken hij/zij inlevert, om bij inleveren meer te controleren. Dit is echter een vorm van profilering die kan leiden tot verkeerde conclusies en discriminatie (denk aan de misstanden bij de toeslagaffaire bij de Nederlandse belastingdienst). Zelfs al zou je dit technisch kunnen meten, is het ethisch niet wenselijk om dit te implementeren. Dit illustreert dat niet alles wat je kunt meten ook moet worden opgeslagen.
  • Aantal pagina's → fysieke eigenschap die bestaat, maar niet nodig voor uitleenfunctionaliteit
  • Taal (Nederlands, Engels, etc.) → bestaat in echte wereld, maar mogelijk niet nodig voor eerste versie
  • Uitgever → bestaat in echte wereld, maar niet nodig voor uitleenfunctionaliteit

Exemplaar:

  • Locatie in bibliotheek (bijv. "Rij 3, Plank B") → bestaat fysiek, maar mogelijk niet nodig voor eerste versie als alle exemplaren op één plek staan
  • Aanschafprijs → financieel gegeven dat bestaat, maar niet nodig voor uitleenfunctionaliteit
  • Laatste schoonmaakdatum → onderhoudsinformatie die bestaat, maar niet nodig voor MVP

Reservering:

  • Reden voor reservering (bijv. "voor schoolproject") → bestaat mogelijk in gesprekken, maar niet nodig voor MVP
  • Voorkeursdatum (wanneer klant het graag wil hebben) → bestaat mogelijk in gesprekken, maar niet nodig voor eerste versie

2. Datatypes in domeinmodellen

Datatypes (zoals String, Date) zijn optioneel in een domeinmodel. Als je twijfelt of iets een object (klasse/entiteit) moet worden of een attribuut, kies dan bij twijfel voor een klasse/entiteit. Dit maakt het model expliciet en voorkomt dat je later belangrijke concepten mist.

Opdracht: Voor je eigen projectcasus: kies één entiteit uit je domein model en bepaal of je datatypes wilt toevoegen. Bedenk ook of er concepten zijn waar je twijfelt of het een entiteit of attribuut moet zijn - kies dan voor een entiteit en leg uit waarom.

3. Subdomein vs. Bounded Context vs. Microservice

Volgens Evans (2003):

  • Een subdomein is een deel van het probleemdomein (bijvoorbeeld "Orderbeheer" of "Voorraadbeheer").
  • Een bounded context is een conceptueel/architecturaal concept in het oplossingsdomein - het is een context waarin een bepaald domeinmodel geldig is. Een bounded context kan worden geïmplementeerd als een microservice, maar dat hoeft niet (het kan ook een module in een monolith zijn, of zelfs meerdere microservices).
  • Een microservice is een deployment/technisch concept - een zelfstandig deploybare service. Een bounded context kan worden geïmplementeerd als één of meerdere microservices, maar een microservice kan ook meerdere bounded contexts bevatten (hoewel dit niet ideaal is).

De relatie tussen subdomeinen en bounded contexts is dat een subdomein vaak wordt gemapped naar een bounded context in de oplossing, maar dit is geen 1-op-1 relatie - één bounded context kan meerdere subdomeinen bevatten, of één subdomein kan over meerdere bounded contexts worden verdeeld.

Opdracht: Voor je eigen projectcasus: bepaal of je domein model groot genoeg is om op te splitsen in subdomeinen. Als je model klein is (past op één A4), hoef je dit niet te doen. Als je model groter wordt, identificeer dan minimaal twee subdomeinen en leg uit waarom je deze splitsing maakt.

4. Voorbeeld domein model - Bibliotheek casus

Hieronder staan twee varianten van een domein model voor een bibliotheeksysteem: een initiële (eenvoudige) versie en een uitgebreide versie. Je kunt deze visualiseren met de PlantUML Online Server of met de VS Code PlantUML Extension.

Initiële versie (eenvoudig)

Deze versie bevat alleen de basisconcepten en is geschikt om te starten met het domeinmodel.

Initiële domein model - Bibliotheeksysteem

📋 PlantUML Code - Initiële Domein Model
@startuml
!theme plain
skinparam classAttributeIconSize 0

class Klant {
  - naam
  - klantnummer
}

class Reservering {
  - reserveringsnummer
  - reserveringsdatum
}

class Uitleenitem {
  - titel
  - auteur
  - isbn
  - jaar van uitgifte
}

class Categorie {
  - naam
}

Klant "1" --> "*" Reservering : maakt
Reservering "1" --> "*" Uitleenitem : bevat
Uitleenitem "*" --> "1" Categorie : heeft

note right of Klant
  Een klant kan meerdere
  reserveringen maken
end note

note right of Reservering
  Een reservering kan
  meerdere items bevatten
end note

note right of Uitleenitem
  Beschrijving van een item
  (bijv. "Harry Potter deel 1").
  ISBN en jaar alleen voor boeken.
end note

note right of Categorie
  Voorbeelden: boek, game,
  stripboek
end note
@enduml

Glossary - Initiële versie

TermDefinitie
KlantEen persoon die items kan reserveren en lenen bij de bibliotheek. Heeft een uniek klantnummer.
ReserveringEen verzoek van een klant om een of meerdere items te reserveren. Heeft een reserveringsnummer en reserveringsdatum.
UitleenitemEen beschrijving van een item dat uitgeleend kan worden (bijvoorbeeld een boek, game of stripboek). Bevat titel, auteur, ISBN (voor boeken, bijvoorbeeld "978-90-1234-567-8") en jaar van uitgifte.
CategorieEen classificatie van uitleenitems, zoals "boek", "game" of "stripboek".

Uitgebreide versie

Deze versie bevat meer detail en maakt onderscheid tussen beschrijvingen en fysieke exemplaren, en voegt entiteiten toe voor Auteur en Conditie.

Uitgebreide domein model - Bibliotheeksysteem

📋 PlantUML Code - Uitgebreide Domein Model
@startuml
!theme plain
skinparam classAttributeIconSize 0

class Klant {
  - naam
  - klantnummer
}

class Reservering {
  - reserveringsnummer
  - reserveringsdatum
  - ophaaldatum
  - inleverdatum
}

class Uitleenitem {
  - titel
  - isbn
  - jaar van uitgifte
}

class Auteur {
  - naam
}

class Exemplaar {
  - exemplaarnummer
  - aanschafdatum
}

class Conditie {
  - naam
}

class Categorie {
  - naam
}

Klant "1" --> "*" Reservering : maakt
Reservering "1" --> "1" Exemplaar : bevat
Exemplaar "1" --> "1" Uitleenitem : is van
Exemplaar "1" --> "1" Conditie : heeft
Uitleenitem "*" --> "1" Categorie : heeft
Uitleenitem "1" --> "*" Exemplaar : heeft
Uitleenitem "*" --> "*" Auteur : geschreven door

note right of Klant
  Een klant kan meerdere
  reserveringen maken
end note

note right of Reservering
  Een reservering verwijst
  naar een specifiek exemplaar.
  Reserveringsdatum: wanneer gemaakt.
  Ophaaldatum: deadline voor ophalen.
  Inleverdatum: wanneer ingeleverd.
end note

note right of Uitleenitem
  Beschrijving van een item
  (bijv. "Harry Potter deel 1").
  Kan meerdere exemplaren hebben.
  ISBN en jaar alleen voor boeken.
end note

note right of Exemplaar
  Fysiek exemplaar dat
  daadwerkelijk uitgeleend wordt
end note

note right of Conditie
  Voorbeelden: als nieuw,
  veelgebruikt, beschadigd
end note

note right of Categorie
  Voorbeelden: boek, game,
  stripboek
end note
@enduml

Glossary - Uitgebreide versie

TermDefinitie
KlantEen persoon die items kan reserveren en lenen bij de bibliotheek. Heeft een uniek klantnummer.
ReserveringEen verzoek van een klant om een specifiek exemplaar te reserveren. Heeft een reserveringsnummer, reserveringsdatum (wanneer gemaakt), ophaaldatum (deadline voor ophalen) en inleverdatum (wanneer ingeleverd).
UitleenitemEen beschrijving van een item dat uitgeleend kan worden (bijvoorbeeld "Harry Potter deel 1"). Bevat titel, ISBN (alleen voor boeken, bijvoorbeeld "978-90-1234-567-8") en jaar van uitgifte. Een uitleenitem kan meerdere fysieke exemplaren hebben.
ExemplaarEen fysiek exemplaar van een uitleenitem dat daadwerkelijk uitgeleend kan worden. Heeft een uniek exemplaarnummer en aanschafdatum. Elke uitleenitem kan meerdere exemplaren hebben.
AuteurDe schrijver of maker van een uitleenitem. Een uitleenitem kan meerdere auteurs hebben (co-auteurs), en een auteur kan meerdere items geschreven hebben.
ConditieDe fysieke staat van een exemplaar, zoals "als nieuw", "veelgebruikt" of "beschadigd".
CategorieEen classificatie van uitleenitems, zoals "boek", "game" of "stripboek".

Dataklassen in het oplossingsdomein

Het domeinmodel hierboven bevindt zich in het probleemdomein - het gaat om de concepten en relaties in de business/wereld. Larman's domeinmodel is statisch en bevat meestal geen methodes. In het oplossingsdomein (de software) worden deze concepten geïmplementeerd als OO classes met specifieke datatypes en methodes. Martin Fowler's domain model bevindt zich in het oplossingsdomein en bevat wel methodes die dynamisch gedrag representeren (hoewel een class diagram nog steeds een statisch UML diagram is - binnen de UML diagram is een UML sequence diagram voor het dynamische gedrag tonen (een bepaalde sequentie van methode aanroepen op runtime)).

Terminologie: In het oplossingsdomein worden de classes soms ook wel "Business Class Diagram" genoemd, maar de term "Domein" is generieker en omvat ook organisaties die niet per se tot het bedrijfsleven worden gerekend, zoals overheid, non-profit organisaties, of educatieve instellingen. Daarom gebruiken we liever de term "Domein".

Let op: Dit is een voorbeeld van hoe je het probleemdomein kunt vertalen naar het oplossingsdomein. In de praktijk kunnen er nog extra technische attributen bijkomen (zoals id, createdAt, updatedAt) en kunnen relaties worden geïmplementeerd als foreign keys of referenties. Ook komen er in het oplossingsdomein classes zoals Controllers en Repositories bij, maar deze vallen in een andere laag dan de Domein laag (bijvoorbeeld de Application laag of Infrastructure laag volgens layered architecture).

Dataklassen oplossingsdomein - Bibliotheeksysteem

📋 PlantUML Code - Dataklassen Oplossingsdomein
@startuml
!theme plain
skinparam classAttributeIconSize 0

class Klant {
  - id: Long
  - naam: String
  - klantnummer: String
  + maakReservering(exemplaar: Exemplaar): Reservering
  + getActieveReserveringen(): List<Reservering>
}

class Reservering {
  - id: Long
  - reserveringsnummer: String
  - reserveringsdatum: LocalDate
  - ophaaldatum: LocalDate
  - inleverdatum: LocalDate
  - klantId: Long
  - exemplaarId: Long
  + isOpgehaald(): Boolean
  + isIngeleverd(): Boolean
  + haalOp(): void
  + leverIn(): void
}

class Uitleenitem {
  - id: Long
  - titel: String
  - isbn: String?
  - jaarVanUitgifte: Integer?
  - categorieId: Long
  + getBeschikbareExemplaren(): List<Exemplaar>
  + heeftBeschikbaarExemplaar(): Boolean
  + voegAuteurToe(auteur: Auteur): void
}

class Auteur {
  - id: Long
  - naam: String
  + getGeschrevenItems(): List<Uitleenitem>
}

class Exemplaar {
  - id: Long
  - exemplaarnummer: String
  - aanschafdatum: LocalDate
  - uitleenitemId: Long
  - conditieId: Long
  + isBeschikbaar(): Boolean
  + updateConditie(conditie: Conditie): void
  + getLeeftijd(): int
}

class Conditie {
  - id: Long
  - naam: String
}

class Categorie {
  - id: Long
  - naam: String
  + getItems(): List<Uitleenitem>
}

Klant "1" --> "*" Reservering
Reservering "1" --> "1" Exemplaar
Exemplaar "1" --> "1" Uitleenitem
Exemplaar "1" --> "1" Conditie
Uitleenitem "*" --> "1" Categorie
Uitleenitem "1" --> "*" Exemplaar
Uitleenitem "*" --> "*" Auteur : many-to-many

note right of Reservering
  Foreign keys: klantId, exemplaarId
end note

note right of Uitleenitem
  isbn en jaarVanUitgifte
  zijn nullable (alleen voor boeken)
end note

note right of Exemplaar
  Foreign keys: uitleenitemId, conditieId
end note
@enduml

Subdomeinen: Uitlenen en Collectie onderhoud

Wanneer een domeinmodel te groot wordt, kun je het opsplitsen in subdomeinen volgens Domain-Driven Design (DDD) principes. Hieronder wordt het bibliotheeksysteem opgesplitst in twee subdomeinen: Uitlenen en Collectie onderhoud.

Subdomein: Uitlenen

Dit subdomein bevat alle concepten die nodig zijn voor het uitlenen van items aan klanten.

Subdomein Uitlenen - Bibliotheeksysteem

📋 PlantUML Code - Subdomein Uitlenen
@startuml
!theme plain
skinparam classAttributeIconSize 0

class Klant {
  - naam
  - klantnummer
}

class Reservering {
  - reserveringsnummer
  - reserveringsdatum
  - ophaaldatum
  - inleverdatum
}

class Uitleenitem {
  - titel
  - isbn
  - jaar van uitgifte
}

class Auteur {
  - naam
}

class Exemplaar {
  - exemplaarnummer
  - aanschafdatum
}

class Conditie {
  - naam
}

class Categorie {
  - naam
}

Klant "1" --> "*" Reservering : maakt
Reservering "1" --> "1" Exemplaar : bevat
Exemplaar "1" --> "1" Uitleenitem : is van
Exemplaar "1" --> "1" Conditie : heeft
Uitleenitem "*" --> "1" Categorie : heeft
Uitleenitem "1" --> "*" Exemplaar : heeft
Uitleenitem "*" --> "*" Auteur : geschreven door

note right of Klant
  Een klant kan meerdere
  reserveringen maken
end note

note right of Reservering
  Een reservering verwijst
  naar een specifiek exemplaar.
  Reserveringsdatum: wanneer gemaakt.
  Ophaaldatum: deadline voor ophalen.
  Inleverdatum: wanneer ingeleverd.
end note

note right of Conditie
  In dit subdomein is conditie
  statisch - wordt niet bijgewerkt
  tijdens het uitlenen
end note
@enduml

Subdomein: Collectie onderhoud

Dit subdomein bevat alle concepten die nodig zijn voor het beheren en onderhouden van de collectie. In dit subdomein heeft een exemplaar een status 'Uitgeleend' (boolean) en is conditie dynamisch - het kan worden bijgewerkt door een boekkeurder. Klanten komen niet voor in dit subdomein.

Subdomein Collectie onderhoud - Bibliotheeksysteem

📋 PlantUML Code - Subdomein Collectie onderhoud
@startuml
!theme plain
skinparam classAttributeIconSize 0

class Boekkeurder {
  - naam
  - medewerkernummer
  + keurAf(exemplaar: Exemplaar): void
  + bestelBij(uitleenitem: Uitleenitem): void
}

class Uitleenitem {
  - titel
  - isbn
  - jaar van uitgifte
  - aantalUitleningen
}

class Exemplaar {
  - exemplaarnummer
  - aanschafdatum
  - uitgeleend: Boolean
}

class Conditie {
  - naam
}

class ConditieInspectie {
  - inspectiedatum
  - opmerkingen
}

class CollectieUitwisseling {
  - uitwisselingsdatum
  - andereBibliotheek
  - aantalItems
}

class AndereBibliotheek {
  - naam
  - locatie
}

Boekkeurder "1" --> "*" ConditieInspectie : voert uit
ConditieInspectie "1" --> "1" Exemplaar : inspecteert
ConditieInspectie "1" --> "1" Conditie : bepaalt
Boekkeurder "*" --> "*" Uitleenitem : bestelt
Exemplaar "1" --> "*" ConditieInspectie : heeft
Exemplaar "1" --> "1" Uitleenitem : is van
Uitleenitem "1" --> "*" Exemplaar : heeft
Exemplaar "1" --> "1" Conditie : heeft
Boekkeurder "1" --> "*" CollectieUitwisseling : beheert
CollectieUitwisseling "*" --> "1" AndereBibliotheek : met
CollectieUitwisseling "*" --> "*" Uitleenitem : betreft

note right of Boekkeurder
  Boekkeurder gaat boeken en
  andere artikelen langs en:
  - Voert conditie inspecties uit
  - Keurt boeken af (methode)
  - Bestelt bij (methode)
end note

note right of ConditieInspectie
  Een boekkeurder voert een
  conditie inspectie uit op een
  exemplaar en bepaalt de conditie.
  Bevat inspectiedatum en opmerkingen.
end note

note right of Exemplaar
  In dit subdomein heeft exemplaar
  een status 'uitgeleend' (boolean).
  Geen relatie met klanten/reserveringen.
end note

note right of Conditie
  Conditie is dynamisch in dit
  subdomein - kan worden bijgewerkt
  door boekkeurder
end note

note right of CollectieUitwisseling
  Uitwisseling van collecties
  met andere bibliotheken
  voor diversiteit.
  
  Dit kan leiden tot een 3e subdomein
  "Boekdistributie": vrachtwagen voor
  honderden boeken over grote afstand
  (tussen steden), of fiets/kar voor
  kleine afstand (twee bibliotheken in
  één stad, maandelijks 20 boeken).
  Vragen: rijduur, aantal uitladers, etc.
  Dit diagram werken we NIET uit.
end note

note right of Uitleenitem
  aantalUitleningen helpt bij
  beslissingen over vervanging
  (populaire vs. weinig uitgeleende items)
end note
@enduml

Glossary - Subdomein Collectie onderhoud

TermDefinitie
BoekkeurderEen medewerker die boeken en andere artikelen in de bibliotheek langsgaat. Voert conditie inspecties uit, keurt boeken af en bestelt bij.
ConditieInspectieEen inspectie door een boekkeurder van een exemplaar om de conditie te bepalen. Bevat inspectiedatum en opmerkingen.
ExemplaarIn dit subdomein heeft een exemplaar een status 'uitgeleend' (boolean) in plaats van een relatie met klanten/reserveringen. De conditie wordt bepaald via conditie inspecties.
ConditieDe fysieke staat van een exemplaar. In dit subdomein wordt conditie bepaald via conditie inspecties door een boekkeurder (in tegenstelling tot het Uitlenen subdomein waar conditie statisch is).
CollectieUitwisselingHet uitwisselen van items tussen bibliotheken om de collectie diverser te maken of weinig uitgeleende items te vervangen door populairdere items.
AndereBibliotheekEen andere bibliotheek waarmee collecties kunnen worden uitgewisseld.
UitleenitemBevat aantalUitleningen om te helpen bij beslissingen over welke items populair zijn en welke vervangen kunnen worden.

Shared Kernel: In de praktijk zouden deze subdomeinen mogelijk verschillende bounded contexts worden in het oplossingsdomein. Concepten zoals Uitleenitem en Exemplaar komen in beide subdomeinen voor. Volgens Evans (2003) kun je hiervoor een Shared Kernel patroon gebruiken: een expliciet gedeeld model tussen bounded contexts. Dit moet zorgvuldig worden beheerd, omdat wijzigingen in de shared kernel beide bounded contexts beïnvloeden. Alternatief is om deze concepten te dupliceren per bounded context (Conformist of Separate Ways), maar dan moet je wel synchronisatie regelen.

Opdracht: Maak voor je eigen projectcasus een domein model en glossary. Begin met een initiële (eenvoudige) versie met alleen de belangrijkste concepten. Zorg dat het model klein blijft (past op één A4). Maak het model met Mermaid of PlantUML (via de PlantUML Online Server of de VS Code PlantUML Extension) en voeg een glossary tabel toe met definities van alle termen. Valideer je domein model met niet-technische stakeholders (bijvoorbeeld je opdrachtgever of product owner) om te controleren of je het probleem goed hebt begrepen.

Kwaliteitscriteria voor domein model

Doelgroep: (ook) niet-technische stakeholders

Het domein model is primair bedoeld voor communicatie met niet-technische stakeholders, zoals opdrachtgevers, product owners, en andere belanghebbenden, om te valideren of je het probleem goed hebt begrepen. Na validatie kun je het domein model gebruiken als basis voor je implementatie, maar je hoeft niet alle entiteiten uit het domein model te implementeren in je OO domain layer - kies alleen wat nodig is voor je MVP.

Belangrijk: Omdat het domein model bedoeld is voor niet-technische stakeholders, moet je in het domein model geen technische OO-concepten gebruiken zoals:

  • Overerving (inheritance)
  • Interfaces of abstracte classes
  • Polymorfie
  • Entities vs. Value Objects (DDD concepten)

Ook DDD-concepten zoals Entities en Value Objects horen niet in het domein model thuis. Deze concepten zeggen een opdrachtgever meestal niets en geven het gevoel dat "dit diagram niet voor mij is maar voor developers", waardoor ze er niet goed naar kijken.

In de oplossingsfase (bijvoorbeeld in je Software Guidebook of domain layer) kun je wel kijken naar het onderscheid tussen Entities en Value Objects uit DDD, en object-georiënteerde concepten zoals overerving, interfaces en polymorfie gebruiken. Maar dit hoort niet in het domein model zelf, omdat dat model bedoeld is om het probleem te begrijpen en te communiceren, niet om de oplossing te ontwerpen.

Let op: Als je toch OO-concepten zoals overerving, compositie of aggregatie in een diagram wilt gebruiken (bijvoorbeeld in een technisch diagram voor developers), voeg dan altijd een legenda en goed beschrijvende labels toe. Zoals Simon Brown aangeeft in zijn presentatie "The lost art of Software Design" (26 oktober 2022): zonder legenda en duidelijke labels zijn diagrammen moeilijk te begrijpen, zelfs voor technische stakeholders. Dit geldt echter niet voor het domein model zelf, dat bedoeld is voor niet-technische stakeholders.

Checklist

Gebruik deze criteria om te controleren of je domein model en glossary voldoen aan de kwaliteitseisen. Druk op Ctrl+D om aanvullende details te tonen.

  • DM-1: Maak het domein model begrijpelijk voor de opdrachtgever: Je gebruikt entiteitnamen die herkenbaar zijn voor de opdrachtgever en je gebruikt Ubiquitous Language (de taal die stakeholders in het domein gebruiken). Je gebruikt domeintermen zoals "Boeklener" in plaats van generieke termen zoals "Klant" of "Gebruiker". Je vermijdt OO "weasel words" zoals "UitleenInstantie" of "LeenCategorie" — je gebruikt liever concrete domeintermen zoals "Bibliotheek" of "Uitleenperiode".
  • DM-2: Je richt het domein model niet al op een oplossing: Je beschrijft het probleemdomein, niet het oplossingsdomein. Je vraagt je niet af 'gaat ons systeem dit opslaan?' (dat is het datamodel i.p.v. domein model), maar 'zijn alle relevante entiteiten uit probleemdomein aanwezig?'.
  • DM-3: Je voegt een legenda toe aan het domein model: Als je relaties of pijlen gebruikt, voeg je een legenda toe die uitlegt wat de verschillende soorten relaties betekenen. Je gebruikt niet teveel verschillende soorten pijlen en je bewaart technische OO-concepten zoals overerving, interfaces of polymorfie voor latere uitwerking van de oplossing, zodat je nu op het probleem focust.
  • DM-4: Je voegt beschrijving en voorbeeldwaarden toe aan de glossary: Naast definities bevat je glossary ook typische voorbeeldwaarden van attributen, zodat bijvoorbeeld datumformaten, ISBN-nummers of andere gestructureerde data herleidbaar zijn.
  • DM-5: Je voegt een toelichting toe aan het domein model: Je vergezelt het model van een toelichting die contextinformatie toevoegt over het domein, bijvoorbeeld waarom bepaalde keuzes zijn gemaakt of welke assumpties er zijn. Je denkt niet alleen aan notes in het diagram, maar je zorgt er ook voor dat het diagram in een tekst staat, en niet is weggestopt in een bijlage 'omdat het zo groot is' (zie criterium DM-6).
  • DM-6: Je houdt het domein model klein en overzichtelijk: Je zorgt dat het model past op één A4-vel en in één oogopslag te begrijpen is. Als het model te groot wordt, kijk je naar mogelijkheden om het op te splitsen in subdomeinen volgens Domain-Driven Design (DDD) principes. Een te groot model is moeilijk te lezen, te bespreken en te valideren met stakeholders.
  • DM-7: Je plaatst het domein model correct in de documentatie: Je plaatst het domein model in je documentatie niet in een hoofdstuk/sectie genaamd "Domein model", maar — samen met toelichting (zie DM-5) — in een sectie "Domein" of liever nog een concrete naam van het domein zoals "Bibliotheek uitleensysteem" of "Orderbeheer". Je plaatst het ook NIET in de Bijlagen (zie DM-9).
  • DM-8: Je gebruikt terminologie consistent in het domein model: Je gebruikt terminologie consistent in het diagram, de glossary en de toelichting. Je gebruikt dezelfde entiteit overal met dezelfde naam, en je definieert relaties duidelijk en eenduidig.
  • DM-9: Je maakt het domein model volledig voor het MVP: Je neemt alle belangrijke concepten en relaties op die nodig zijn voor het Minimum Viable Product (MVP). Het model hoeft niet alle mogelijke edge cases te bevatten, maar moet wel alle kernfunctionaliteit dekken. Deze eis botst vaak met criterium DM-6; blijf op zoek naar de middenweg.

Opdracht: Bedenk zelf minimaal twee aanvullende kwaliteitscriteria voor een domein model die hierboven nog niet genoemd zijn. Denk bijvoorbeeld aan aspecten zoals: validatie met stakeholders, onderhoudbaarheid, of andere aspecten die belangrijk zijn voor een goed domein model. Leg uit waarom deze criteria belangrijk zijn en hoe je ze zou kunnen controleren.

Verder lezen/verdiepen?

Subdomeinen en Context Mapping

Als je het domein model opsplitst in subdomeinen (zie criterium DM-6), maak je meerdere domeinmodellen, elk met een eigen toelichting. Je voegt ook een algemene introductie toe waarin je de subdomeinen introduceert. Zorg dat je de subdomeinen een korte maar beschrijvende naam geeft, zoals 'Uitleensysteem' en 'Collectie beheer' uit het voorbeeld in sectie 4.

Als je echt richting 'Software Architect' niveau wilt stijgen, kun je ook nadenken over en verdiepen in de Context Mapping techniek uit DDD. Dit is het derde strategische pattern uit DDD naast de 'Ubiquitous Language' en 'Bounded Context' patterns. Context mapping gaat over welke relatie subdomeinen onderling hebben, wie is client (upstream) en wie is server (downstream), zijn er 'generic subdomains' (zoals authenticatie), of shared kernels. Zie voor meer informatie de video "The Ultimate Guide to Context Mapping in Domain Driven Design" (Master AWS with Yan, 27-11-2024).

Bronnen

Last change: 2025-12-05