Download as pdf or txt
Download as pdf or txt
You are on page 1of 60

Associatie KULeuven

De Nayer instituut
Industrieel ingenieur
Opleiding Elektronica-ICT
3e academisch bachelorjaar

Objectgericht ontwerpen

Academiejaar 2011-12 J. Vennekens


Inhoudsopgave

1 Systeemontwikkeling en systeemanalyse. 3
1.1 Systeemontwikkeling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1 Benaderingswijzen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Software levenscyclus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.1 Het waterval model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2.2 Het spiraal model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Systeemanalyse: verzamelen van gegevens. . . . . . . . . . . . . . . . . . . . . . . . 6

2 Objectgeoriënteerde systeemontwikkeling 9
2.1 Objecttechnologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Verschillen met traditionele ontwikkeling . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.1 Functionele decompositie versus domeinmodellering . . . . . . . . . . . . . 9
2.2.2 Verschillen met data-georiënteerde ontwikkeling . . . . . . . . . . . . . . . . 10
2.3 Unified modeling language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4 Verschillende stadia van de diagrammen . . . . . . . . . . . . . . . . . . . . . . . . 12
2.5 De diagrammen bij een traditionele aanpak . . . . . . . . . . . . . . . . . . . . . . 13

3 Klasse- en objectdiagram (2) 15


3.1 Geavanceerde concepten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.1.1 Afgeleiden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.1.2 Zichtbaarheid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.1.3 Klasse-attributen en -operaties . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1.4 Associatieklasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1.5 Aggregatie en compositie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1.6 Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.1.7 Andere topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.2 Werkwijze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2.1 Identificeer alle mogelijke kandidaatklassen . . . . . . . . . . . . . . . . . . 19
3.2.2 Selecteer de klassen uit de lijst van kandidaten . . . . . . . . . . . . . . . . 20
3.2.3 Maak een modeldictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.4 Identificeer associaties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.5 Identificeer attributen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2.6 Identificeer operaties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2.7 Generaliseer met behulp van overerving . . . . . . . . . . . . . . . . . . . . 23
3.2.8 Voeg bedrijfsregels toe met OCL-constraints . . . . . . . . . . . . . . . . . . 23
3.2.9 Groepeer klassen in packages . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.2.10 Itereer over de gedane stappen . . . . . . . . . . . . . . . . . . . . . . . . . 23

4 Object Constraint Language 25


4.1 Achtergrond . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2 Overzicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2.1 Expressiecontext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

I
INHOUDSOPGAVE 1

4.2.2 Standaardtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2.3 Gebruik van klassen en types . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2.4 Geassocieerde objecten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.2.5 Associaties en verzamelingen van objecten . . . . . . . . . . . . . . . . . . . 27
4.2.6 Klasse-operaties en -attributen . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.2.7 Operaties op alle objecten . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.2.8 Initiële waarden en afleidingsregels . . . . . . . . . . . . . . . . . . . . . . . 29
4.3 Werkwijze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.3.1 Vind de regel voor de constraint . . . . . . . . . . . . . . . . . . . . . . . . 29
4.3.2 Bepaal de context en schrijft de constraint op . . . . . . . . . . . . . . . . . 30

5 Interactie diagrammen 31
5.1 Use-case diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.1.1 Functionele en niet-functionele systeemeisen . . . . . . . . . . . . . . . . . . 31
5.1.2 Actoren en use-cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.1.3 Use-case diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.1.4 Werkwijze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.2 Sequence- en communicatiediagram . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.2.1 Concepten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.2.2 Voorbeelden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.2.3 Werkwijze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.2.4 Gebruik van CRC-kaarten . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

6 Toestands- en activiteitsdiagram 43
6.1 Toestandsdiagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.1.1 Concepten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.1.2 Voorbeeld . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6.1.3 Werkwijze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6.2 Activiteitsdiagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
6.2.1 Concepten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
6.2.2 Werkwijze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

7 Applicatie- en implementatiestadium 51
7.1 Beschrijving . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
7.2 Werkwijze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
7.2.1 Integreer alle informatie in het klassediagram . . . . . . . . . . . . . . . . . 52
7.2.2 Detailleer het klassediagram . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
7.2.3 Voeg nieuwe klassen toe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
7.2.4 Maak dynamische diagrammen . . . . . . . . . . . . . . . . . . . . . . . . . 55
7.2.5 Integreer alle informatie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
7.3 Component- en deployment diagrammen . . . . . . . . . . . . . . . . . . . . . . . . 56
2 INHOUDSOPGAVE
Hoofdstuk 1

Systeemontwikkeling en
systeemanalyse.

1.1 Systeemontwikkeling.
1.1.1 Benaderingswijzen.
Bij het ontwikkelen van systemen kan men essentieel twee verschillende benaderingswijzen volgen,
nl. de top-down approach (van boven af) ofwel de bottom-up approach (van onder op).
Bij de top-down benadering wordt eerst een globaal model van de informatiestroom ontwikkeld.
Pas dan wordt een informatiesysteem ontworpen om aan die informatiestroom te voldoen. Dit in-
formatiesysteem bestaat uit een aantal modules of subsystemen die in een volgorde ontwikkeld
worden die een maximale integratie toelaat. Het voordeel van deze benadering is de grotere inte-
gratiemogelijkheid, omdat onmiddellijk het geheel wordt overzien en dus alles beter gecoördineerd
en gepland kan worden. Nadelig is de moeilijkheid om grote systemen op die manier te benaderen.
In de bottum-up benadering gebeurt de ontwikkeling van het informatiesysteem meer geleidelijk.
Vermits de basiselementen van eender welk verwerkingssysteem een aantal modules (toepassingen)
zijn die transakties uitvoeren of bestanden aanpassen, begint men hier met het operationeel op
punt stellen van deze modules, waarna ze geı̈ntegreerd worden. Naarmate de tijd vordert, kun-
nen overeenkomstig de vraag en de nood, nieuwe modules toegevoegd worden zoals plannings-,
kontrole- en beslissingsmodules. Met andere woorden het informatiesysteem groeit geleidelijk naar
zijn uiteindelijke vorm, waarbij gestreefd wordt naar een geordende integratie en implementatie.
Naarmate het systeem evolueert en volgens de noden van het ogenblik, kunnen nieuwe func-
ties toegevoegd worden die gebruik maken van de reeds bestaande modellen en gegevens of een
aanvulling vereisen.
De voordelen van deze benadering zijn:
• opbouw op basis van reële behoeften en mogelijkheid tot expansie
• de gegevensbestanden worden opgebouwd op basis van de toepassingen
• men verkrijgt een soepel systeem waarbij verschillende functies duidelijk gescheiden blijven.
Nadelig is soms de onmogelijkheid om zover te integreren als nodig. Bepaalde toepassingen
kunnen, door hun aan- of afwezigheid de vereiste integratie tegenwerken of vertragen. Ook zullen
modules na verloop van tijd opnieuw ontwikkeld moeten worden om een verdere integratie toe te
laten.

1.2 Software levenscyclus


Bij het ontwerpen van grote software producten wordt men geconfronteerd met een aantal proble-
men die moeilijk in te schatten zijn door beginnende programmeurs die tijdens hun opleiding in

3
4 HOOFDSTUK 1. SYSTEEMONTWIKKELING EN SYSTEEMANALYSE.

een afgeschermde wereld hebben leren programmeren:


• Alle oefeningen zijn goed-gedefinieerd: er is altijd een antwoord; alhoewel dat er frequent
meerdere mogelijke oplossingen zijn.
• De oefeningen oplossen is een individuele bezigheid, samenwerking is niet nodig (niet toe-
gelaten); de benodigde tijd is nooit meer dan enkele dagen.
• De resulterende programma’s moeten niet onderhouden worden; ze moeten niet aangepast
worden, enkele weken (maanden) nadat ze geschreven zijn.
In de praktijk hebben software ingenieurs wel te maken met niet goed omlijnde opdrachten. Ze
moeten in team werken om deadlines te halen. Achteraf staan ze ook in voor het onderhoud van
de programma’s en moeten ze antwoorden op vragen van de gebruikers. Door deze aanpassingen
ontstaan nieuwe versies die moeten beheerd worden.
Grote software producten ontwikkelen vraagt dus een aangepaste benadering. Er zijn verschil-
lende modellen ontwikkeld voor het software ontwerp proces, bijvoorbeeld het waterval en het
spiraal model.

1.2.1 Het waterval model

Behoefte
analyse

Programma
ontwerp

Implementatie

Testen

Onderhoud

Figuur 1.1: Het waterval model

Het waterval model van de software levenscyclus wordt in figuur 1.1 getoond. Het diagram
heeft 5 blokken:

Behoefte analyse en specificatie: deze fase begint met een opdracht op basis van het LT in-
formaticaplan of op basis van een vooronderzoek. In samenspraak met de klant worden de
vereisten waaraan de software moet voldoen, opgesteld. Nadat de doelstellingen zijn vast-
gelegd, worden een aantal systeemconcepten gemaakt en onderling gewaardeerd (kosten-
batenanalyse).

Ontwerp: identificeren van de belangrijkste data types en bijhorende operaties (data abstractie);
vastleggen van de verschillende interfaces.
• Functioneel ontwerp: Alle functies in het nieuwe systeem worden uitgelegd en duidelijk
beschreven, en waar nodig verder opgesplitst. De informatiebehoefte en de gegevens
die daarvoor nodig zijn worden bestudeerd, beschreven en uitgelegd.
1.2. SOFTWARE LEVENSCYCLUS 5

• Technisch ontwerp: Het technisch ontwerp beschrijft hoe het systeem moet werken,
hoe de functies gerealiseerd kunnen worden. Procedures en programmaspecifikaties
worden nu gemaakt tesamen met formulieren, recordindelingen, e.d.

Implementatie: het schrijven van de programma’s op basis van het ontwerp: normaal is de keuze
van de programmeertaal gebaseerd op dit ontwerp, in de praktijk wordt nogal dikwijls de
voorkeurtaal van de programmeur(s) genomen.
Taakbeschrijvingen worden gemaakt op basis van de ontwikkelde procedures en de hoeveel-
heden uit te voeren werk en verder:
• het ontwerpen van de programmastruktuur
• het schrijven van de programma’s
• het afzonderlijk testen van deze programma’s
• het vervolledigen van de programmadokumentatie.

Testen: nagaan of de programma’s correct werken op het vlak van functionaliteit en algemeen-
heid. De afzonderlijke programma’s worden samengesteld tot jobs en in onderlinge samen-
hang tesamen met de procedures getest.

Konversie en invoering: Hier kan de vraag gesteld worden of men gedurende bepaalde tijd
moet schaduwdraaien.

Systeemgebruik en -beheer: Omdat geen enkel systeem perfekt is, moet het continu onder-
houden worden. Soms moeten de programma’s overgedragen worden naar nieuwe systemen;
de functionaliteit moet verhoogd worden. Verder moet vooral worden gelet op veiligheids-
voorzieningen, herstelprocedures, e.d.

Uit het diagram blijkt dat er een constante stroom is van één blok naar het volgende. Daarnaast
is er voortdurende inschatting of de vorige deeltaak al of niet goed uitgevoerd is; indien nodig wordt
er terug naar het vorige blok gegaan om het aan te passen.

1.2.2 Het spiraal model

Planning
Risico analyse

Communicatie
met klant Engineering

Klant evaluatie
Constructie

Figuur 1.2: Het spiraal model

Het spiraal model (figuur 1.2) bevat de goede delen van het waterval model; daarnaast is
het element risico analyse toegevoegd. Dit model is zeer geschikt voor grote industriële software
projecten en bevat volgende deeltaken:
6 HOOFDSTUK 1. SYSTEEMONTWIKKELING EN SYSTEEMANALYSE.

Communicatie met de klant: zorgen voor een goede, effectieve communicatie tussen ontwer-
per en klant.
Planning: het definiëren van de doelstellingen, de hulpmiddelen en de tijdshorizon.
Risico analyse: het inschatten van technische en management risico’s: het identificeren van
potentiële problemen en het analyseren van alternatieve oplossingen.
Engineering: het ontwerp van de software.
Constructie en release: het bouwen, testen en installeren van de software; voorzieningen voor
gebruikersondersteuning (bijvoorbeeld documentatie en training).
Klant evaluatie: terugkoppeling van de klant omtrent de mogelijkheden van het software pro-
duct.
Elke versie doorloopt deze stappen, voorgesteld door de spiraal vertrekkend vanuit het centrum.
Voor elke nieuwe release zou een risico analyse moeten uitgevoerd worden om na te gaan of de
nieuwe (bijkomende) objectieven kunnen gerealiseerd worden binnen het budget (tijd en kost).
Dit model illustreert ook het evolutionaire aspect: de initiële oplossing kan erg beperkt zijn
(voldoende voor de basisvereisten van de klant); latere versies zijn uitgebreid met nieuwe faciliteiten
en een betere GUI.
Vanzelfsprekend moet bij de systeemanalyse en het systeemontwerp steeds rekening gehouden
worden met de menselijke factoren. Niet zelden gebeurt het dat goed ontworpen systemen falen
door het wantrouwen en misnoegen van de gebruikers. Een faktor die steeds vernoemd wordt, is
de resistance to change, waarbij het eventuele verlies van de job, de angst om overbodig te worden
of de nieuwe werkmethode niet aan te kunnen een belangrijke rol spelen. Deze weerstand kan
teruggebracht worden tot de primaire menselijke behoeften van veiligheid, erkenning, kompetitie
en sociaal kontakt. Vele moeilijkheden ontstaan dus door onzekerheid die gepaard gaan met de
introduktie van een nieuw systeem. Deze onzekerheid wordt echter verminderd door de toekomstige
gebruiker op ieder ogenblik in het ontwerp te betrekken. De gebruikers zijn geneigd om systemen
die ze zelf hielpen ontwerpen vlugger te aanvaarden temeer daar ze op die manier de nood aan het
nieuwe systeem gaan inzien.

1.3 Systeemanalyse: verzamelen van gegevens.


Om een systeem te kunnen analyseren, hebben we gegevens nodig. Deze kunnen verkregen worden
via directe interactie met het systeem (bijv. interview) en door het raadplegen van bestaande
bronnen (bijv. verzendingsbestand). Er bestaan verschillende technieken:
Observatie van het proces: door doorheen het systeem te wandelen kunnen we de belangrijke
informatiestromen en beslissingspunten ontdekken. Deze kunnen dan beschreven worden
d.m.v grafische technieken die verderop beschreven worden.
Interview: in de aanvangsfase van een project is dit een vrij ongestruktureerd gesprek met de
betrokken personen om een algemeen idee te krijgen van het probleem. Wanneer het project
vordert, zullen de interviews ook gestruktureerder worden: de analist stelt dan heel preciese
vragen aan de juiste personen.
Vragenlijst: wanneer er van een groot aantal mensen informatie moet verkregen worden en men
heeft niet de tijd om elke persoon individueel te ondervragen, zullen de vragen op voorhand
ontworpen worden. Dit moet op een zodanige manier gebeuren dat ze kunnen beantwoord
worden zonder dat de analist hoeft aanwezig te zijn.
Het voordeel van een vragenlijst is dat het een vrij goedkope manier is om veel informatie
te verkrijgen van een grote groep mensen. Het legt wel grote beperkingen op wat de vragen
betreft, vermits ze op voorhand vastgelegd zijn. Bij een interview daarentegen kan, wanneer op
1.3. SYSTEEMANALYSE: VERZAMELEN VAN GEGEVENS. 7

één of andere manier een nieuw element ter sprake komt, hierop verder ingegaan worden. Wanneer
de vraag dubbelzinnig is, kan de interviewer ze verduidelijken en uitleggen wat er gewenst wordt.
Vragenlijsten kunnen ook gebruikt worden om feedback te krijgen bij een postimplementatie audit.
8 HOOFDSTUK 1. SYSTEEMONTWIKKELING EN SYSTEEMANALYSE.
Hoofdstuk 2

Objectgeoriënteerde
systeemontwikkeling

2.1 Objecttechnologie
De manier waarop software gestructureerd wordt, is in de loop der jaren zeer verschillend geweest.
Het varieerde van structurering op basis van de functie van een bepaald (deel)programma en het
functionele ontwerpen tot structurering op basis van de benodigde data en het gegevensgerichte
ontwerpen.
Objecttechnologie is een nieuw paradigma (denkraam). Het kenmerk van objecttechnologie
is dat data en functies die deze data bewerken, samengevoegd worden in een eenheid die object
genoemd wordt. Elk object is een zelfstandige entiteit binnen het totale systeem. De structuur
van het systeem bestaat uit objecten die met elkaar verbonden zijn en met elkaar communiceren.
Tijdens de analysefase in de bouw van een softwaresysteem wordt een structuur of een model
geconstrueerd. Ieder object wordt gezien als een afspiegeling van een fysiek ding uit de werke-
lijkheid of van een concept dat gangbaar is in die werkelijkheid. Het resulterende model van een
deel van de werkelijkheid is altijd een vereenvoudiging. Een object verbergt zijn binnenkant (hoe
worden operaties uitgevoerd, wat wordt er precies opgeslagen en hoe, ...) voor andere objecten in
het systeem. Door middel van deze inkapseling is het mogelijk om aanpassingen in de software
in belangrijke mate te lokaliseren. Aanpassen betekent dus minder werk, maar vooral ook minder
kans op het introduceren van fouten door ongewenste neveneffecten. Dit resulteert in een flexibel
systeem dat snel genoeg kan meeveranderen met de behoeften van de organisatie en gebruikers.
Belangrijk bij het structureren van software is een goede verdeling van alle activiteiten of taken
binnen het systeem. Ieder object heeft een duidelijk afgebakende, meestal beperkte verantwoorde-
lijkheid voor het uitvoeren van bepaalde activiteiten in het systeem. Deze verdeel-en-heers tactiek
maakt het mogelijk om fouten gemakkelijker te lokaliseren. Daarnaast zijn ook veranderingen
makkelijker te plaatsen en de consequenties ervan makkelijker te doorgronden.

2.2 Verschillen met traditionele ontwikkeling


2.2.1 Functionele decompositie versus domeinmodellering
Functioneel georiënteerde systeemontwikkeling begint bij de functionaliteit die het systeem moet
gaan bieden. Er gebeurt een functionele decompositie tot op het niveau dat de functies kunnen
geprogrammeerd worden. Het resulterende systeem zal aan de origineel gevraagde functionaliteit
voldoen. Aanpassingen en uitbreidingen zijn vaak moeilijk te realiseren en kosten veel werk.
Een kleine wijziging in een oorspronkelijke hoofdfunctie betekent meestal aanpassingen in vele
subfuncties tot op het laagste niveau. Het toevoegen van een nieuwe functie vraagt het opnieuw
maken van een heleboel bijhorende subfuncties.

9
10 HOOFDSTUK 2. OBJECTGEORIËNTEERDE SYSTEEMONTWIKKELING

Objectgeoriënteerde ontwikkeling gaat uit van domeinmodellering. De werkelijkheid waarin het


systeem een rol speelt (het domein), wordt in kaart gebracht. Het resultaat is een domeinmodel
met daarin de concepten uit het domein met hun kenmerken, gedrag en onderlinge relaties. Dit
model is volledig onafhankelijk van de gevraagde functies. Zo’n systeemfunctie bestaat uit het
in bepaalde volgorde, onder bepaalde omstandigheden gebruiken van al gedefinieerde operaties
van de objecten uit het model. Het toevoegen van nieuwe functies vergt op deze manier weinig
wijzigingen en meestal weinig werk. De functionaliteit zit al in de objecten, maar moet slechts in
de juiste combinatie ingezet worden. Het resultaat is dus een bijzonder flexibel systeem.

2.2.2 Verschillen met data-georiënteerde ontwikkeling


Domeinmodellering wordt toegepast in de traditionele data-georiënteerde systeemontwikkeling.
De nadruk ligt alleen bij de statische aspecten van het systeem. Men kan dus komen tot een
op zich goede datastructuur. Maar een 4GL biedt de mogelijkheid om hieraan zeer snel functies
te koppelen. Er wordt te weinig aandacht besteed aan de structuur van de functies zodat de
onderhoudbaarheid van programmatuur geschreven in een 4GL ronduit slecht te noemen is.
Objecttechnologie besteedt voldoende aandacht aan de dynamiek van een softwaresysteem.
Hiervoor zijn vier diagrammen voorzien. Het op de juiste wijze samenvoegen van functies van
diverse objecten om zo te komen tot de realisatie van een systeemfunctie wordt in deze diagrammen
beschreven.

2.3 Unified modeling language


UML is geen methode, maar een taal. UML standaardiseert geen werkwijze, wel begrippen en
diagrammen waarin die begrippen gebruikt kunnen worden. UML biedt een aantal diagrammen
(figuur 2.1) die gezamenlijk het model van het softwaresysteem vormen.
• Het use-case diagram toont hoe het systeem gebruikt kan worden door externe entiteiten
zoals menselijke gebruikers.
• Het klassediagram toont de statische structuur van het softwaresysteem weergegeven als
klassen en hun relaties.
• Het objectdiagram toont de statische structuur van het softwaresysteem weergegeven als
objecten en hun relaties.
• Het sequence diagram toont de volgorde in tijd van de boodschappen die in het systeem
verstuurd en ontvangen worden.
• Het communicatie diagram toont hoe de objecten samenwerken om een doel te bereiken.
• Het toestandsdiagram toont de toestanden waarin een object zich kan bevinden gedurende
zijn levensloop.
• Het activiteitsdiagram toont de activiteiten die door een deel van het systeem worden uit-
gevoerd, inclusief eventueel parallellisme.
Activiteitsdiagrammen kunnen ook gebruikt worden voor het beschrijven van bedrijfspro-
cessen en de workflow.
• Het component diagram toont de verdeling van het gehele systeem in componenten en de
relaties tussen die componenten.
• Het deployment diagram toont hoe de software componenten in een bepaalde systeemcon-
figuratie worden gebruikt.
Het use-case diagram wordt ook wel een requirementsdiagram genoemd. Het klassediagram
en het objectdiagram vormen samen de statische diagrammen. Het sequence-, communicatie-
, toestands- en activiteits-diagram worden ook wel de dynamische diagrammen genoemd. Het
component- en deployment-diagram zijn de implementatiediagrammen.
2.3. UNIFIED MODELING LANGUAGE 11

Functionele eisen = gedrag Domein kennis = structuur


Activiteitsdiagram
voor workflow en
bedrijfsmodellering

Use-case diagram Klassediagram

Business rules
Sequence en/of
in OCL
communicatie diagram

Klassediagram
plus OCL en operaties

Toestandsdiagram

tweede heeft info


Activiteitsdiagram uit eerste nodig
voor interne werking
softwaresysteem
eerste heeft invloed
op tweede

Compleet
klassendiagram

Figuur 2.1: Samenhang van de diagrammen


De statische view helpt de analist bij de communicatie met de klant.
De dynamische view helpt de analist bij de communicatie met een team
van ontwikkelaars en de ontwikkelaars met het maken van programma’s.
De taak van de use-case is het modelleren van een systeem vanuit het
gezichtspunt van de gebruiker.

UML : ideën van James Rumbaugh, Grady Booch en Ivar Jacobson.


12 HOOFDSTUK 2. OBJECTGEORIËNTEERDE SYSTEEMONTWIKKELING

Figuur 2.1 geeft een overzicht van de samenhang van de verschillende diagrammen. Een pijl van
een diagram naar een ander geeft aan dat het tweede diagram informatie uit het eerste diagram
nodig heeft. Een gestippelde lijn betekent dat het eerste diagram wel invloed heeft op het tweede,
zonder dat delen van het tweede diagram direct uit het eerste voortkomen. Het klassediagram
dat in verschillende stadia langs de dikke pijl wordt ontwikkeld, is het centrale diagram in de
methode. In de figuur wordt ook onderscheid gemaakt tussen structurele en gedragsaspecten
van het softwaresysteem. De structurele aspecten worden weergegeven in het klassediagram. De
gedragsaspecten in de overige diagrammen, met uitzondering van de component en deployment
diagrammen. Uiteindelijk worden beide zijden geı̈ntegreerd in het klassediagram.

2.4 Verschillende stadia van de diagrammen


• Een domeinmodel of -diagram is een model waarin alleen aspecten uit de werkelijkheid
waarin het systeem moet gaan werken (het domein) naar voren komen en geen automatise-
ringsaspecten.
• Een applicatiemodel of -diagram is een model waarin naast de domeinaspecten ook keuzen
naar voren komen die betrekking hebben op hoe de gebruiker met dit specifieke systeem
kan (gaan) werken. Een applicatiemodel kan gezien worden als een uitbreiding op het
domeinmodel, maar in principe zijn beide verschillende ontwikkelstadia van een en hetzelfde
model.
• Een implementatiemodel of -diagram is een model dat exact aangeeft hoe de implemen-
tatie van het systeem eruit ziet. Naast alle aspecten van het domein- en applicatiemodel
bevat een implementatiemodel ook aspecten die alleen betrekking hebben op de gekozen
implementatiewijze, zoals de opslagstructuren.

domein applicatie implementatie


use-casediagram nee ja nee
klassediagram ja ja ja
objectdiagram ja ja ja
sequencediagram beperkt ja ja
communicatiediagram beperkt ja ja
toestandsdiagram ja ja ja
activiteitsdiagram ja, workflow ja ja
deploymentdiagram nee nee ja
componentdiagram nee nee ja

Tabel 2.1: Overzicht van diagrammen in verschillende stadia

Er kan eenzelfde onderscheid gemaakt worden bij de categoriën van klassen:


• Domeinklassen zijn klassen die relevant zijn in de werkelijkheid van de gebruikers en do-
meinexperts.
• Applicatieklassen vertegenwoordigen alle aspecten van een applicatie die zichtbaar zijn voor
de gebruiker. Vanuit het oogpunt van de gebruiker zijn de instanties van de applicatieklassen
de applicatie. Het zijn de enige objecten waarmee hij rechtstreeks interactie heeft.
• Implementatieklassen zijn klassen die niets te maken hebben met het probleemdomein, maar
alleen met de specifieke implementatie in het huidige systeem.
• Hulpklassen zijn algemeen bruikbare klassen, zoals generieke klassen BinaireBoom, Datum,
Hashtabel, ... die in klassebibliotheken terug te vinden zijn.
2.5. DE DIAGRAMMEN BIJ EEN TRADITIONELE AANPAK 13

2.5 De diagrammen bij een traditionele aanpak


Ook in de traditionele waterval projectfasering kunnen de diagrammen gebruikt worden.

1. Conceptualisatie: veelvuldige communicatie met de eindgebruikers en andere betrokkenen


is noodzakelijk om een goed beeld te krijgen van de taken die de eindgebruikers met het
systeem moeten gaan uitvoeren. De use-cases vormen een relatief formele beschrijving van
deze taken in natuurlijke taal.
2. Analyse: het klassediagram en het sequence diagram zijn het belangrijkst. In eerste instan-
tie zullen deze diagrammen nog niet volledig uitgewerkt worden. Alle gebruikte termen
komen uit het domein. Domeinexperts en automatiseerders moeten samen zorgen dat de
diagrammen een goede weergave van het relevante deel van de werkelijkheid zijn.
3. Ontwerp: alle niet-functionele eisen gaan nu een rol spelen. Naast aanpassingen aan het
klassediagram en het sequencediagram zullen nu de communicatie-, toestands- en activiteits-
diagrammen gemaakt worden. Een punt van aandacht tijdens deze fase is de consistentie
tussen de diagrammen.
4. Implementatie: alle objecten die in het ontwerp gespecificeerd zijn, worden geprogrammeerd.
Uitgangspunt hierbij is het klassediagram. Wanneer het softwaresysteem omvangrijk is, kan
het worden opgedeeld in componenten. Het component en het deployment diagram kunnen
deze verdeling weergeven.
14 HOOFDSTUK 2. OBJECTGEORIËNTEERDE SYSTEEMONTWIKKELING
Hoofdstuk 3

Klasse- en objectdiagram (2)

In Deel I van deze cursus werden het klasse- en objectdiagramma al bondig ingeleid. Deze sectie
gaat hier nu wat dieper op in.

3.1 Geavanceerde concepten


3.1.1 Afgeleiden
Een afgeleid attribuut is een attribuut waarvan de waarde afgeleid kan worden uit de waardes
van één of meerdere andere attributen. Een attribuut is dus niet iets dat altijd in het object
opgeslagen wordt. Het is informatie die aan het object kan gevraagd worden. Hoe het object aan
die informatie komt, is voor de klanten van het object van geen belang (voorbeeld van inkapseling).
Een afgeleide associatie kan afgeleid worden uit andere associaties. Afgeleide associaties zijn
van nature redundant en moeten daarom zoveel mogelijk vermeden worden.
Afgeleide attributen en associaties worden in UML aangegeven door een schuine streep (/)
voor de naam te plaatsen.

eigenaar eigenaar
Persoon Computer Persoon Computer
bezit bezit

heeftToegangTot heeftToegangTot

/heeftToegangTot Netwerk /heeftToegangTot Netwerk

Richting van een associatie. Het is niet altijd nodig om een associatie in twee richtingen te im-
plementeren. Wanneer slechts één richting geı̈mplementeerd wordt, kunnen consistentieproblemen
vermeden worden. In een diagram kan de geı̈mplementeerde richting aangegeven worden door de
associatielijn van een pijlpunt te voorzien.

3.1.2 Zichtbaarheid
De zichtbaarheid van een attribuut of operatie geeft aan in hoeverre het attribuut of de operatie
aan de omgeving van het object bekend is. In principe verbergen objecten zoveel mogelijk van
hun attibuten en operaties voor hun omgeving.

privé - compleet verborgen attribuut of operatie


publiek + compleet zichtbaar attribuut of operatie
beschermd # alleen zichtbaar voor instanties van subklassen van de klasse
package ~ zichtbaar voor instanties van klassen van een package

15
16 HOOFDSTUK 3. KLASSE- EN OBJECTDIAGRAM (2)

3.1.3 Klasse-attributen en -operaties


Een klasse-attribuut is een attribuut dat een eigenschap van
een klasse beschrijft, en niet een eigenschap van iedere indi- DoorlopendeRekening
viduele instantie. Een klasse-attribuut heeft dan ook slechts
één waarde, onafhankelijk van het aantal instanties van de
+rentepercentage: Real
klasse. Ook wanneer er geen enkele instantie is, heeft een
+kredietLimiet: Real
klasse-attribuut een waarde.
−opgenomen: Real
Een klasse-operatie is een service die geleverd wordt door de
−/nogOpTeNemen: Real
klasse, en niet door de instanties. Een typisch voorbeeld is
de constructor, de operatie die een nieuwe instantie maakt.
#nieuwRenteperc(real: Real)
Omdat iedere klasse deze specifieke klasse-operatie heeft,
~open()
wordt deze meestal niet opgenomen in het klassediagram.
+losaf(bedrag: Real)
Klasse-attributen en -operaties worden weergegeven door
+neemOp(bedrag: Real)
de naam van het attribuut of de operatie in de klasserecht-
hoek te onderstrepen.

3.1.4 Associatieklasse
Een associatieklasse is een klasse die gekoppeld is aan een associatie: de klasse wordt geı̈dentificeerd
met de associatie. Zodra er een link is tussen twee instanties, is er direct een instantie van de
betreffende associatieklasse. Zodra de link verdwijnt, verdwijnt ook de instantie van de klasse. Een
associatieklasse wordt gebruikt wanneer de associatie attributen en/of operaties heeft en wanneer
de associatie zelf weer associaties heeft met andere klassen.
In UML wordt een associatieklasse aangegeven door het klassesymbool, dat door middel van
een onderbroken lijn gekoppeld is met de bijhorende associatie.

echtgenoot echtgenote
Man Vrouw

Huwelijk

datum
isAfgeslotenIn Gemeente

3.1.5 Aggregatie en compositie


Een aggregatie is een speciaal soort associatie die aangeeft dat een of meer klassen “onderdeel zijn
van” een andere klasse, maar zelf ook een zelfstandig bestaan kunnen hebben. Een duidelijker
gedefinieerde variëteit is een compositie. In een compositierelatie mag een onderdeel altijd maar
tot één geheel behoren, bovendien geldt de restrictie dat de levensduur van een deelobject altijd
kleiner is of gelijk aan de levensduur van het gehele object. Een deelobject kan niet zelfstandig
verder leven wanneer het object waarvan hij deel uitmaakt, verdwijnt (lifetime dependency).
In UML wordt een aggregatie aangegeven door een associatie met een witte ruit aan de kant
van het gehele object; bij een compositie is dit een zwarte ruit.

Fiets Fiets
Aggregatierelatie Compositierelatie

2 2
Wiel Frame Wiel Frame
3.1. GEAVANCEERDE CONCEPTEN 17

3.1.6 Constraints

Een constraint is een beperking op één of meer elementen in het klassediagram. Om constraints
te noteren wordt binnen UML de Object Constraint Language (OCL) gebruikt. Als een OCL-
constraint in een diagram vermeld moet worden, dan wordt de constraint tussen accolades ({}) in
een note-box geplaatst.
Er bestaan ook verschillende voorgedefinieerde constraints die als een symbool in het klassedi-
agram aangegeven kunnen worden:

• {ordered}: het geordend zijn van een verzameling objecten die gedefinieerd wordt door een
associatie met multipliciteit groter dan één;
• {xor} met een stippellijn naar twee of meer associaties geeft aan dat er slechts één van de
associaties geı̈nstantieerd kan zijn.
• ...: het feit dat niet alle subklassen in een generalisatie herkend zijn; waarschijnlijk zijn er
meer dan opgegeven.

* * Persoon
Boek auteurs
Pagina * 1 titel {xor}
{ordered} * 1 Organisatie
ISBN
eigenaar

3.1.7 Andere topics

• Een abstracte klasse is een klasse waarvan geen instanties kunnen bestaan. Een abstracte
klasse is altijd een superklasse van andere klassen en dient om een gezamenlijke interface te
definiëren, door middel van overerving.

Figuur {abstract}
positie: Punt
teken()

Cirkel Rechthoek Driehoek

• Meervoudige overerving: een klasse kan meer dan één superklasse hebben.
18 HOOFDSTUK 3. KLASSE- EN OBJECTDIAGRAM (2)

TelecommunicatieApparaat
beantwoordOproep()

Fax Telefoon
beantwoordOproep() beantwoordOproep()

Telefax
beantwoordOproep()

• Een stereotype is een indeling van modelelementen die niet voort komt uit het conceptuele
domein; maar bijvoorbeeld uit de verdeling op basis van het stadium (domein, applicatie of
implementatie).

<<applicatie>> <<domein>>
⊳ wordtGetoondIn
TextWindow Document

• Een enumeratie is een type waarvoor een vast aantal waarden gedefinieerd is en wordt aange-
geven door het klassesymbool met bovenin het stereotype <<enumeration>>. De mogelijke
waarden van de enumeratie staan in het gedeelte waar normaal de attributen staan.

<<enumeration>> <<enumeration>>
GeslachtType FunctieType
man piloot
vrouw stewardess

• Een interface definieert een aantal services die door een klasse geı̈mplementeerd kunnen
worden. Een interface wordt nooit zelf geı̈nstantieerd. In plaats daarvan worden objecten
geı̈nstantieerd uit klassen die de interface geı̈mplementeerd hebben.

<<interface>>
Verrijdbaar Fiets
Ladenblok
Auto rijden() Verrijdbaar

• Een package is een groepering van modelelementen (zoals klassen, associaties, aggregaties,
generalisaties). Werken met packages is een generiek mechanisme om een opdeling te maken
van een softwaresysteem.
3.2. WERKWIJZE 19

Systeem

DomeinPackage

UserInterfacePackage DatabasePackage

• Een dependency relatie geeft aan dat een bepaald modelelement andere modelelementen
nodig heeft om goed te kunnen functioneren. Een object is bijvoorbeeld van andere objecten
afhankelijk.

• Een geparametriseerde klasse of template is een klasse waarin een aantal zaken afhankelijk
zijn van één of meer parameters.

Type1, max: integer


Lijst

elementen: Type1[max] <<bind>> (Persoon,50)


LijstPersonen

voegToe(elem: Type1)
verwijder(elem: Type1) Lijst<Punt,200>
elemOpPositie(index:integer): Type1

Figuur 3.1 is een aangepaste versie van figuur ??. Er is een associatieklasse Bemanning
toegevoegd die zelf een associatie heeft met de klasse Bemanningslid. Daarnaast is ook de klasse
Passagier toegevoegd met een voorgedefinieerde constraint ({ordered} ). Bij de klasse Vlucht is
een constraint toegevoegd om rondvluchten te verbieden.

3.2 Werkwijze
In de volgende subsecties wordt een stappenplan beschreven waarbij de nadruk ligt op een domein-
versie van het klassediagram. Om een applicatie- of implementatieversie te maken kan hetzelfde
stappenplan gebruikt worden waarbij wel andere accenten gelegd worden.

3.2.1 Identificeer alle mogelijke kandidaatklassen


Om alle mogelijke objecten te vinden kan men beginnen met het onderstrepen van alle zelfstandige
naamwoorden in de tekst van de probleembeschrijving. Een probleem hierbij is dat de probleem-
beschrijving steeds te herformuleren is, wat zou leiden tot een andere lijst van kandidaatklassen.
De kans dat goede kandidaten gemist worden, is levensgroot. De probleembeschrijving is vaak ook
te concreet: de gebruiksaspecten en de functionaliteiten worden te zeer benadrukt; het gaat te
weinig over het domein. De op deze manier gevonden kandidaten zijn niet altijd goede kandidaten
voor domeinklassen.
Daarom is het organiseren van brainstormsessies aan te raden waarbij deze en de volgende
twee stappen uitgevoerd worden. Zowel toekomstige gebruikers, domeinexperts als ontwikkelaars
wonen deze sessie bij. Omdat het de bedoeling van stap 1 is om zoveel mogelijk potentiële objecten
20 HOOFDSTUK 3. KLASSE- EN OBJECTDIAGRAM (2)

Bemanningslid
Luchtvaartmaatschappij
bemanningsleden naam
naam: String
∗ functie: FunctieType
eigenaar

bezit Bemanning
{vertrekpunt <> bestemming}
∗ kisten
Vliegtuig Vlucht
naam: String vluchtnummer: Integer
capaciteit: Integer vertrektijd: Tijd
vluchten
landt() ∗ aankomsttijd: Tijd
voertUit
start() /duur: Tijdsduur
vertrek()

vertrekkende ∗ ∗ binnenkomende
Vluchten Vluchten
Propellervliegtuig Straalvliegtuig ...

{ordered} ∗
Passagier
naam: String
vertrekpunt bestemming
leeftijd: Integer
assistentieNodig: Boolean Luchthaven
geslacht: GeslachtType naam: String
bepaalBelasting(): Real

Figuur 3.1: Een klassediagram met geavanceerde concepten

te benoemen, mag niemand commentaar geven op de kandidaatklassen die door andere deelnemers
aangebracht worden. Er mag wel uitleg over gevraagd worden maar een mening of het wel of niet
een goede klasse is, mag niet te kennen gegeven worden.
Het resultaat van deze stap is een grote lijst van kandidaatklassen. De meeste uit deze lijst
zullen uiteindelijk geen klasse in het systeem worden. Het zijn wel merendeels termen die binnen
het probleemdomein van belang zijn en daarom in een apart deel van de modeldictionary terecht
zullen komen.

3.2.2 Selecteer de klassen uit de lijst van kandidaten


Voor iedere term van de opgestelde lijst wordt een definitie of een beschrijving gemaakt. Er moet
nu bepaald worden of de term al of niet als klasse in het systeem moet opgenomen worden. Dit is zo
wanneer de kandidaatklasse een zelfstandige rol speelt in het probleemdomein: de kandidaat moet
informatie ter beschikking stellen of hij moet iets doen. De kandidaatklasse moet een duidelijke
verantwoordelijkheid hebben in het systeem.
Daarnaast kan ook gekeken worden waarom een kandidaat geen klasse zou zijn. Er zijn ver-
schillende redenen waarom een term geen klasse zal zijn.
1. Redundante klassen: een klasse is redundant wanneer hij exact dezelfde verantwoordelijk-
heden heeft en informatie bevat als een andere klasse. De term die de betekenis het beste
weergeeft, moet als klasse behouden blijven, de andere verdwijnt.
2. Irrelevante klassen: een klasse is irrelevant wanneer hij buiten het probleemdomein ligt.
3.2. WERKWIJZE 21

Dit heeft dus te maken met het bepalen van de grenzen van het probleemdomein. In
twijfelgevallen kan met de term als klasse aannemen: dit betekent meer werk, maar de
aanpasbaarheid van het systeem in de toekomst zal toenemen. Het niet meenemen als
klasse is vaak eenvoudiger, maar het systeem wordt ook minder flexibel.
In dit stadium is het niet zo erg om wat extra klassen te bepalen. In een volgende fase kan
besloten worden om het ontwerp en de implementatie van bepaalde delen van het systeem
uit te stellen.
3. Vage klassen: een klasse moet een duidelijke betekenis hebben. Wanneer het moeilijk blijkt
om een definitie op papier te krijgen, betekent dit meestal dat het om een vage klasse gaat.
4. Niet kwantificeerbare zaken: zaken als water of geld zijn minder vaag, maar kunnen niet
gekwantificeerd worden. “Eén water” of “drie geld” zijn onzinnige uitspraken.
5. Attributen: dingen waarvan alleen de waarde interessant is. Attributen hebben geen eigen
verantwoordelijkheid en zijn dus geen instanties van een klasse. Het is wel zo dat dezelfde
term in de ene context een object kan zijn, maar in een andere context slechts een attribuut.
Hierbij kan ook de vraag gesteld worden of <naam van de kandidaatklasse> een aspect is
van een andere klasse of is de kandidaat een zelfstandig begrip.
6. Operaties: zaken waarvan alleen (het resultaat van) het gedrag interessant is. Soms wordt
een operatie als een zelfstandig naamwoord geschreven en is daardoor een kandidaatklasse.
7. Rollen: worden vaak verward met klassen. Ieder object blijft gedurende zijn gehele levens-
loop van dezelfde klasse. De naam van de klasse moet iets aangeven van een object, dat
altijd zo blijft. Het gaat om de intrinsieke eigenschappen en verantwoordelijkheden die een
object heeft. Vaak speelt een object gedurende een beperkte periode een bepaalde rol. Een
belangrijk hulpmiddel om het onderscheid te maken is om na te gaan of een object gedu-
rende zijn levensloop van klasse zou moeten kunnen veranderen. Is dit het geval, dan is er
sprake van een rol.
8. Constructies uit andere stadia van ontwikkeling: alle termen die niets met het probleemdo-
mein te maken hebben, maar wel met de implementatie van een geautomatiseerd systeem,
zijn in het domeinmodel niet relevant.
Voor iedere term uit de kandidaatklasselijst wordt nagegaan of het een klasse is of niet. De
uiteindelijke beslissing voor iedere term wordt genoteerd. Voor een groot aantal termen is het
snel duidelijk en is weinig discussie nodig. Er blijven bijna altijd een aantal termen over waarvoor
het niet zo evident is om te bepalen of het klasse is of niet. Bij deze termen moet, naast de
definitie, ook alle argumenten voor en tegen opgeschreven worden. Uiteindelijk moet toch een
keuze gemaakt worden; tijdens volgende iteraties over het klassediagram zal dan wel blijken of de
keuze juist was.

3.2.3 Maak een modeldictionary


Alle gevonden termen worden in de modeldictionary opgenomen: gedefinieerde klassen, gevonden
attributen en operaties. Ook andere termen die niet in het klassediagram terugkomen worden in
een apart deel van de modeldictionary opgenomen. Dit deel kan dienen als een referentiekader
voor alle betrokkenen.

3.2.4 Identificeer associaties


Er wordt gezocht naar paren van klassen die iets met elkaar te maken hebben. Dit kan gebeuren
door alle paren van klassen te bekijken. Uit deze lijst van kandidaatassociaties wordt de associaties
in het model bepaald. Dit gebeurt weer door het elimineren van kandidaten.
1. Irrelevante associaties: associaties die buiten het probleemdomein liggen, of die niet inte-
ressant zijn voor de in ontwikkeling zijnde toepassing.
2. Acties: veel relaties zijn slechts tijdelijk, wat wil zeggen op één moment van belang. Een
associatie daarentegen beschrijft een structurele relatie tussen objecten: de relatie moet
22 HOOFDSTUK 3. KLASSE- EN OBJECTDIAGRAM (2)

gedurende langere tijd gelden. Eenmalige relaties worden in het dynamisch model als ac-
ties weergegeven. Eventueel kunnen ze in het klassediagram als een dependency tussen de
betrokken klassen weergegeven worden.
3. Afgeleide associaties: kan beschreven worden als een combinatie van bestaande associaties.
De afgeleide associatie is dus redundant en tijdens analyse wordt gestreefd naar een mini-
maal model dat de werkelijkheid zo goed mogelijk beschrijft. (Er zijn wel allerlei redenen
om redundantie toe te voegen tijdens het ontwerp en de implementatie.)
Een eerste klassediagram met klassen en associaties kan nu getekend worden. Dit diagram zal
in een later stadium waarschijnlijk nog aangepast worden. Belangrijk is dat dit model uitstekend
dienst doet als terugkoppeling naar de gebruikers en/of experts.
Het klassediagram kan nog verder uitgewerkt worden door aan de associaties meer informatie
toe te voegen: rollen en multipliciteiten. Het toevoegen van rollen geeft veel meer informatie over
de betekenis van de associatie. De multipliciteit geeft aan hoeveel instanties aan elkaar gerelateerd
kunnen zijn. Het geeft dus de mogelijkheden, maar ook de beperkingen van het klassediagram
aan.

3.2.5 Identificeer attributen


Iets is een attribuut als het te maken heeft met dingen waarvan een object weet heeft: informatie
die aan een object kan gevraagd worden. Een eerste reeks van attributen is afkomstig uit de lijst
van afgewezen klassen omdat ze daar al als attribuut bestempeld zijn. Ook uit de beschrijving van
de klassen in de modeldictionary kunnen attributen gevonden worden. Speciale aandacht moet
besteed worden aan klasse-attributen.
In een aantal gevallen worden ten onrechte attributen gebruikt:
1. Objecten: een attribuut heeft alleen een waarde en kan niet verwijzen naar een object. Een
attribuut dat toch naar een object verwijst, moet vervangen worden door een associatie
tussen de betreffende klassen.
2. Identifiers: in de traditionele systeemontwikkeling krijgt iedere entiteit een sleutelwaarde,
vaak een kunstmatig attribuut om de entiteit te identificeren. Binnen objectoriëntatie is dit
soort attributen onnodig en ongewenst: ieder object heeft per definitie een unieke identiteit.
3. Interne waardes: afhankelijk van de focus van het diagram. Alleen attributen die kenmerken
aangeven welke voor de klanten van een object van belang zijn, worden tijdens de analyse
in beschouwing genomen. Alle eventuele attributen die alleen intern in het object relevantie
hebben, zijn in de analyse niet van belang, maar worden pas in de ontwerpfase opgenomen.
4. Detail: tijdens domeinanalyse moet een goed inzicht in het domein verkregen worden: dus
alleen de belangrijkste attributen opnemen. Wanneer teveel bijzonder gedetailleerde attri-
buten toegevoegd worden aan alle klassen, dan gaat de aandacht teveel naar het detail en
bestaat het gevaar dat het overzicht verloren wordt. Als het toch nodig is om alle attributen
op te nemen, dan kunnen ze beter per klasse in een aparte klassebeschrijving weergegeven
worden in plaats van op het klassediagram dat totaal onleesbaar zou worden.
De gevonden attributen worden aan het klassediagram toegevoegd. Attributen die in de vol-
gende stappen bijkomend gevonden worden, kunnen gemakkelijk toegevoegd worden zonder de
reeds bestaande structuur te wijzigen.

3.2.6 Identificeer operaties


Een operatie van een object geeft aan wat dat object kan doen: wat de verantwoordelijkheid van
het object is en hoe deze verantwoordelijkheid kan vervuld worden. Een aantal operaties komt uit
de lijst van afgewezen klassen omdat ze daar al als operatie aangemerkt zijn.
Veel operaties komen in een later stadium naar boven in het dynamisch model. Het is dus niet
de bedoeling om in dit stadium al te proberen volledig te zijn.
3.2. WERKWIJZE 23

3.2.7 Generaliseer met behulp van overerving


De uit vorige stappen resulterende eerste versie van het klassemodel wordt bestudeerd om te
zien of er generalisaties van bestaande klassen kunnen gevonden worden (een abstractieproces).
Generaliseren is het vinden van overeenkomsten in verschillende klassen. Dit kunnen attributen
en/of operaties zijn. Deze identieke attributen en operaties worden uit de oorspronkelijke klasse
verplaatst naar de nieuwe superklasse. Daarnaast kunnen verschillende klassen ook identieke
associaties hebben. Ook deze klassen kunnen gegeneraliseerd worden waarbij de associaties uit de
subklassen vervangen worden door één associatie van de superklasse.

3.2.8 Voeg bedrijfsregels toe met OCL-constraints


Het klassediagram wordt meer precies gemaakt door bedrijfsregels en beperkingen die in het domein
gelden, op een exacte manier weer te geven. Daarnaast wordt gecontroleerd of met behulp van het
klassediagram aan de belangrijkste informatiebehoeften voor het systeem voldaan is. Deze vragen
hoeven niet binnen de functionele eisen van het systeem te liggen. Ook vragen die in de toekomst
misschien kunnen gesteld worden, moeten bekeken worden. Deze vragen en/of antwoorden kunnen
met behulp van OCL worden genoteerd.
Wanneer zinvolle vragen niet beantwoord kunnen worden met behulp van het klassediagram,
betekent dit dat het model een te beperkte, en dus ongeschikte weergave van het probleemdomein
is. Het model moet dan aangepast worden zodat het beter aan de werkelijkheid beantwoordt.
Maar, omwille van tijdsdruk, kan het ook zijn dat deze beperkingen van het model voor lief
genomen moeten worden.

3.2.9 Groepeer klassen in packages


Een klassediagram kan zeer groot worden. In dat geval moet het opgedeeld worden in een aantal
overzichtelijke delen. Er zijn veel verschillende manieren om te kiezen voor een bepaalde opdeling.
Vanuit het oogpunt van de domeinanalyse is de enige zinvolle opdeling een logische opdeling die
zijn oorsprong vindt in het probleemdomein.

3.2.10 Itereer over de gedane stappen


Het eerste gemaakte klassediagram zal altijd nog een aantal fouten en/of onvolkomenheden be-
vatten. Bijna niemand is in staat om in één keer het beste model te creëren. Regelmatig zullen
aanpassingen moeten aangebracht worden, telkens een inconsistentie of onvolkomenheid gevonden
wordt. Bijvoorbeeld wanneer een bepaalde noodzakelijke verantwoordelijkheid of operatie gevon-
den wordt, die bij geen enkele klasse kan ondergebracht worden, ontbreekt er meestal een klasse.
Of een constraint niet beschreven kan worden met het bestaande model, geeft vaak aan dat er een
associatie mist of dat er ontbrekende klassen, attributen of operaties zijn.
24 HOOFDSTUK 3. KLASSE- EN OBJECTDIAGRAM (2)
Hoofdstuk 4

Object Constraint Language

4.1 Achtergrond
De Object Constraint Language (OCL) is een tekstuele taal om extra informatie aan UML-
diagrammen toe te voegen. OCL is bedoeld om constraints, allerlei beperkingen, condities en
regels, die gelden in het model weer te geven.
Visuele modellen kunnen veel inzicht geven in de structuur en het gedrag van een software-
systeem, maar ze staan open voor verschillende interpretaties. Constraints voegen precisie en
eenduidigheid toe aan de diagrammen.
De volgende vormen van constraints worden veel gebruikt:
• Een invariant is een constraint op een klasse die altijd waar moet zijn voor alle instanties
van die klasse. Indien dit niet geval is, gedragen objecten uit die klasse zich niet correct.
• Een pre-conditie is een constraint die altijd waar moet zijn direct voor de executie van een
operatie.
• Een post-conditie is een constraint die altijd waar moet zijn direct na de executie van een
operatie.
• Een guard is een constraint op een toestandsovergang van een object.
Elk van deze constraints kan weergegeven worden met een OCL-expressie. In dit hoofdstuk
worden alleen invarianten behandeld. Voorbeelden van pre- en post-condities en guards zijn terug
te vinden in volgende hoofdstukken.
In de UML-standaard is vastgelegd dat OCL-expressies altijd gekoppeld zijn aan een UML-
diagram, bijvoorbeeld een klassediagram of een toestandsdiagram.

4.2 Overzicht
4.2.1 Expressiecontext
Om de onafhankelijke identiteit van elk object in een objectgeoriënteerd softwaresysteem te bena-
drukken, is elke constraint altijd gebonden aan een bepaald object: de expressiecontext. Vanuit
dit object wordt de omgeving bekeken en expressies geschreven voor objecten uit deze omgeving.
In een diagram is de context duidelijk doordat de constraint in een notebox geschreven wordt die
door middel van een onderbroken lijn met het object verbonden is. Constraints kunnen echter ook
in een apart dokument naast het diagram beschreven worden. De context wordt dan aangegeven
door het sleutelwoord context, gevolgd door de naam van de klasse, gevolgd door een aanduidig
van de intentie van de expressie (bijv. inv voor invariant).
Voorbeeld van een invariant op elke instantie van de klasse Passagier:

25
26 HOOFDSTUK 4. OBJECT CONSTRAINT LANGUAGE

context Passagier inv:


leeftijd > 0
of Passagier {leeftijd > 0}
context Passagier inv:
self.leeftijd > 0
In OCL wordt het keyword self gebruikt om de context aan te duiden. Wanneer de context
duidelijk is, mag het woord self weggelaten worden.

4.2.2 Standaardtypes
Normale standaardtypes zoals Integer, Real, Boolean en String kunnen gebruikt worden in OCL-
expressies. Op de types kunnen de klassieke operatoren (+, -, *, and, =, <>) gebruikt worden.
Daarnaast zijn er twee specifieke operatoren op Booleans.
De implies operator combineert twee Boolean-expressies. De resulterende expressie is waar als,
wanneer de eerste expressie waar is, de tweede expressie ook waar is. Wanneer de eerste expressie
niet waar is, dan is het resultaat altijd waar onafhankelijk van de waarde van de tweede expressie.
context Passagier inv:
leeftijd > = 90 implies assistentieNodig = true
Omdat bij het evalueren van een OCL-expressie het type van het resultaat altijd duidelijk moet
zijn, mag het else-deel van een if-then-else expressie nooit weggelaten worden. Bovendien moet
het resulterende type van het then-deel gelijk zijn aan het type van het else-deel.
context Passagier inv:
if geslacht = GeslachtType::man then
naam.substring(1,4) = ’Dhr.’
else
naam.substring(1,3) = ’Mv.’
endif
De constructie “type::waarde” wordt gebruikt om de waarde van een enumeratietype aan te
geven.

4.2.3 Gebruik van klassen en types


Naast de basis OCL-types kunnen vanuit de context van een bepaalde klasse, alle attributen en
query operaties van die klasse in een OCL-expressie gebruikt worden. Een query operatie is een
operatie die geen waarden in het systeem verandert.
In de klasse Vlucht wordt als type van een aantal attributen de klassen Tijd en Tijdsduur
gebruikt. Deze klassen zijn niet weergegeven in het klassediagram, maar maken wel deel uit van
het gehele UML-model. Wanneer Tijd een operatie na heeft, welke twee Tijd objecten met elkaar

Vlucht Tijd
Tijdsduur
aankomsttijd: Tijd sec: Integer
aantalSec: Integer
vertrektijd: Tijd min: Integer
aantalMin: Integer
/duurtijd: Tijdsduur uren: Integer
aantalUren: Integer
nu(): Tijd
+(t: Tijdsduur): Tijdsduur
na(t: Tijd): Boolean
<(t: Tijdsduur): Boolean
voor(t: Tijd): Boolean
>(t: Tijdsduur): Boolean
verschil(t: Tijd): Tijdsduur

Figuur 4.1: De klassen Tijd en Tijdsduur

vergelijkt en de waarde waar terug geeft als het aangeroepen object een tijdstip representeert
4.2. OVERZICHT 27

dat later is dan het parameter object, kan volgende invariant op de Vlucht klasse neergeschreven
worden.

context Vlucht inv:


aankomsttijd.na(vertrektijd)

4.2.4 Geassocieerde objecten


Binnen een constraintcontext kunnen constraints gedefinieerd worden op andere objecten die met
de context geassocieerd zijn. Om deze geassocieerde objecten aan te duiden, wordt de rolnaam
van de associatie gebruikt. Indien geen rolnaam gespecificeerd is, kan de klassenaam (beginnend
met een kleine letter!) gebruikt worden.
Met de context Vlucht zijn volgende Luchthaven objecten geassocieerd: vertrekpunt en be-
stemming. Een invariant die rondvluchten verbiedt:

context Vlucht inv:


vertrekpunt <> bestemming

In de constraints kunnen ook alle attributen en query operaties van geassocieerde objecten
gebruikt worden.

context Vlucht inv:


bestemming.naam = ’Amsterdam’

In de volgende invariant wordt verondersteld dat bepaalBelasting een query operatie is van
de klasse Luchthaven.

context Vlucht inv:


vertrekpunt.bepaalBelasting() + bestemming.bepaalBelasting() <= 2000

4.2.5 Associaties en verzamelingen van objecten


Vaak specificeren associaties in een UML-diagram een één-op-veel of een veel-op-veel relatie. In
die gevallen zal het gebruik van een rolnaam in een OCL-expressie niet één enkel object opleveren
maar een verzameling van objecten.
OCL heeft een voorgedefinieerd type Collection waarmee dergelijke verzamelingen kunnen be-
handeld worden. Dit type is een supertype van de Set, OrderedSet, Bag en Sequence types. Een
instantie van het Set type is een verzameling zoals in de wiskunde gedefinieerd. Het Bag type re-
presenteert verzamelingen waarin een element meer dan één maal mag voorkomen. Een OrderedSet
en een Sequence zijn respektievelijk een geordende Set en een geordende Bag.

Operatie size: bepaalt het aantal elementen

context Luchthaven inv:


self.binnenkomendeVluchten− >size() < 100

Een voorgedefinieerde operatie op een collectie moet voorafgegaan worden door een pijl “− >”
(in plaats van een punt) om het verschil te kunnen maken met eigen gedefineerde operaties met
dezelfde naam.

Operatie notEmpty: geeft waar terug als de Set niet leeg is. Elke luchtvaartmaatschappij
moet minstens één vliegtuig hebben:

context Luchtvaartmaatschappij inv:


self.kisten− >notEmpty()
28 HOOFDSTUK 4. OBJECT CONSTRAINT LANGUAGE

Operatie collect: elke luchtvaartmaatschappij moet minstens één vliegtuig hebben dat een
vlucht uitvoert:

context Luchtvaartmaatschappij inv:


self.kisten− >collect(vluchten)− >notEmpty()

Hierbij wordt van de verzameling self.kisten voor ieder vliegtuig de verzameling vluchten ge-
nomen. Dit kan ook in een kortere versie (omdat deze constructie veel voorkomt):

context Luchtvaartmaatschappij inv:


self.kisten.vluchten− >notEmpty()

Operatie forAll: levert waar op als de expressie tussen de haken geldt voor elk element van
de verzameling. Voor alle KLM vluchten moet de naam van de vertrek- of aankomstluchthaven
Amsterdam zijn.

context Luchtvaartmaatschappij inv:


self.naam = ’KLM’ implies
self.kisten.vluchten− >forAll
(
vertrekpunt.naam = ’Amsterdam’
or
bestemming.naam = ’Amsterdam’
)

Operatie select: levert een deelverzameling van de oorspronkelijke verzameling op

context Vlucht inv:


self.passagier− >select(assistentieNodig)− >size() < 10

Hier resulteert de self.passagier in een Sequence vanwege de {ordered} constraint in het dia-
gram. De complete constraint stelt dat het aantal passagier objecten dat assistentie nodig heeft
kleiner is dan 10.

4.2.6 Klasse-operaties en -attributen


Klasse-operaties en -attributen kunnen in OCL ook gebruikt worden: de klassenaam (met hoofd-
letter) wordt gevolgd door twee dubbelpunten en de attribuut- of operatienaam.

context Tijd inv:


Tijd::nu().verschil( Tijd::nu() ).aantalSec = 0

De expressie Tijd::nu() levert de waarde van de klasse-operatie op, dit is de huidige tijd.

4.2.7 Operaties op alle objecten


Operaties isTypeOf en isKindOf: kunnen op alle objecten worden toegepast. Het resultaat
van de operatie isTypeOf is waar als het object een instantie is van de klasse die als parameter is
meegegeven. Het resultaat van de operatie isKindOf is waar als het object een instantie is van de
klasse die als parameter is meegegeven of van één van zijn subklassen.
Wanneer het object kist een instantie uit de klasse Straalvliegtuig is en Straalvliegtuig een
subklasse is van Vliegtuig, dan gelden de volgende expressies:
4.3. WERKWIJZE 29

kist.isTypeOf(Vliegtuig) = false
kist.isKindOf(Vliegtuig) = true :Vliegtuig
kist.isTypeOf(Straalvliegtuig) = true
kist.isKindOf(Straalvliegtuig) = true
kist.isTypeOf(Propellervliegtuig) = false

context Luchthaven inv: kist: Straalvliegtuig ···


Luchthaven.allInstances()− >size() <= 80

Operatie allInstances: kan alleen worden toegepast op een klasse en niet op een object. Het
resultaat is een verzameling met alle instanties uit de klasse. Hierboven is aangegeven dat het
totaal aantal instanties van de klasse Luchthaven ten hoogste gelijk is aan tachtig.

4.2.8 Initiële waarden en afleidingsregels


Naast invarianten kan met OCL ook andere soorten informatie gespecificeerd worden, zoals initiële
waarden en afleidingsregels:
• initiële waarde (keyword init): waarde van een attribuut of een associatie op het moment
van de creatie van het object;
• afleidingsregel (keyword derive): hoe de waarde van een afgeleid attribuut of een afgeleide
associatie bepaald moet worden.
De expressiecontext is in deze gevallen niet een klasse, maar een attribuut of een associatierol en
wordt aangegeven door de klassenaam, twee dubbelpunten en de attribuutnaam of rolnaam.

context Vlucht::passagier
init: OrderedSet{}

4.3 Werkwijze
Veelal worden constraints gebruikt om zogenaamde business rules vast te leggen. Het belangrijkste
daarbij is het vinden van de juiste business rules. Omdat dit zeer afhankelijk is van de “business”
waarin het systeem moet functioneren, is hiervoor geen algemene werkwijze te geven. In wat volgt
worden twee algemene richtlijnen beschreven.

4.3.1 Vind de regel voor de constraint


Om het UML-model precies en eenduidig te maken is het zeer belangrijk de juiste regels te vinden.
Dit kan door uit te gaan van het model zoals het tot dan toe beschreven is.
Invarianten kunnen gevonden worden door te zoeken naar afhankelijkheden tussen attributen
van diverse klassen en ook tussen attributen intern in een klasse. Een aantal voorbeelden zijn in
vorige paragraaf al gegeven.
Zeker voor afgeleide attributen moet altijd een afleidingsregel te vinden zijn die aangeeft hoe
dat afgeleide attribuut bepaald wordt.
1. De duur van een vlucht is de tijd tussen vertrektijd en aankomsttijd.
Invarianten kunnen ook gevonden worden door afhankelijkheden tussen associaties te onder-
zoeken.
2. Een vlucht kan niet beginnen en eindigen op hetzelfde vliegveld.
Of dit een goede regel is, moet blijken uit de context van het bedrijf waarin het systeem een
rol speelt.
Invarianten kunnen ook preciesere informatie geven omtrent de multipliciteit van een associatie:
3. Het aantal passagiers op een vlucht is ten hoogste gelijk aan de capaciteit van het
vliegtuig.
30 HOOFDSTUK 4. OBJECT CONSTRAINT LANGUAGE

Ook afgeleide associaties moeten door constraints worden vastgelegd:


4. Een vlucht kan alleen gevlogen worden door een bemanningslid met de functie piloot.

4.3.2 Bepaal de context en schrijft de constraint op


De constraintcontext is een indicatie waar de verantwoordelijkheid ligt om de constraint in het
run-time systeem te controleren en te bewaken. Constraints hoeven niet noodzakelijkerwijs op
deze manier geı̈mplementeerd te worden, maar deze denkwijze vergemakkelijkt het zoeken naar
de juiste context. Een andere factor om de juiste context te bepalen is dat de constraint zo kort
en eenvoudig mogelijk moet kunnen opgeschreven worden.

1. De duur van een vlucht is de tijd tussen het vertrek en aankomst.


Omdat het afgeleide attribuut bij Vlucht hoort, is dit de meest waarschijnlijke context.

context Vlucht::duur
derive: aankomsttijd.verschil(vertrektijd)

2. Een vlucht kan niet beginnen en eindigen op hetzelfde vliegveld.


Dit lijkt de verantwoordelijkheid van Vlucht:

context Vlucht inv:


vertrekpunt <> bestemming

Als alternatief kan Vliegveld als context gekozen worden:

context Vliegveld inv:


vertrekkendeVluchten− >intersection(binnenkomendeVluchten)− >isEmpty()

Er wordt gesteld dat de doorsnede van de vertrekkende en aankomende vluchten moet leeg
zijn. Dit is een complexere constraint en dus is Vliegveld een minder geslaagde context keuze.
3. Het aantal passagiers op een vlucht is ten hoogste gelijk aan de capaciteit van het vliegtuig.
Keuzes voor de context zijn Vlucht en Vliegtuig. Passagier ligt niet voor de hand, omdat de
constraint niets zegt over een enkele passagier.

context Vliegtuig inv:


vluchten− >forAll(passagier− >size() <= self.capaciteit)

context Vlucht inv:


passagier− >size() <= vliegtuig.capaciteit

De tweede mogelijkheid lijkt de eenvoudigste. Omdat Vlucht ook het object is dat de relatie
tussen Vliegtuig en de Passagiers tot stand brengt, is Vlucht het meest aangewezen object
om de verantwoording voor deze constraint te dragen.
4. Een vlucht kan alleen gevlogen worden door een bemanningslid met de functie piloot.

context Vlucht inv:


bemanning.bemanningsleden− >includes(piloot) and piloot.functie = FunctieType::piloot

C->includes(object): is waar als object een element is van de collectie C.


Hoofdstuk 5

Interactie diagrammen

5.1 Use-case diagram


5.1.1 Functionele en niet-functionele systeemeisen
De systeemeisen zijn de voorwaarden waaraan het (toekomstige) systeem moet voldoen. Er zijn
twee soorten. In de functionele systeemeisen staat de functionaliteit van het systeem beschreven:
wat de toekomstige gebruiker met het systeem kan uitvoeren. De niet-functionele systeemeisen
stellen voorwaarden aan de manier waarop het systeem de gevraagde functionaliteit moet aanbie-
den: snelheid, geheugengebruik, hard- en software omgeving.
De niet-functionele systeemeisen worden gebruikt in latere stadia van de systeemontwikkeling.
In de domeinanalyse spelen ze geen rol. De functionele systeemeisen (of kortweg, de systeemeisen)
zijn het uitgangspunt voor het use-case diagram.
Een use-case is een beschrijving van een bepaalde wijze waarop het systeem kan gebruikt
worden. Omdat use-cases een belangrijk hulpmiddel zijn bij de communicatie met de gebruikers
en de opdrachtgevers, is teveel formaliteit storend in dit proces. Daarom wordt voor de beschrijving
de natuurlijke taal gebruikt. In een volgend stadium worden de use-cases als uitgangspunt genomen
voor de formelere sequence diagrammen.
Use-cases kunnen ook gebruikt worden als test-cases voor het uiteindelijke systeem. Iedere
beschreven use-case moet met behulp van het systeem uitgevoerd kunnen worden. De verzame-
ling use-cases moet dan ook compleet zijn: elke gewenste systeemfunctie moet in een use-case
beschreven zijn.
Het gebruik van use-cases is een vorm van gebruikersgeoriënteerd werken. Het systeem wordt
beschouwd als een black box en men is alleen geı̈nteresseerd in de interactie tussen de gebruiker
en het systeem. Gebruikersgeoriënteerd werken gaat dus uit van de functionele systeemeisen die
aan het systeem gesteld worden en is een vorm van functionele decompositie op hoog niveau.

5.1.2 Actoren en use-cases


Een actor is een entiteit buiten het systeem die communiceert met het systeem. Een actor wordt
in het use-case diagram weergegeven als een poppetje met de naam van de actor eronder. Ook
mogelijk is de weergave als klasse met het stereotype <<actor>> (zie figuur 5.1). Vanuit het
systeem gezien zijn de actoren (mens of een ander systeem) de voorstelling van de complete
buitenwereld.
Een use-case is een beschrijving van een reeks interacties tussen één of meer actoren en het
systeem. Het gezichtspunt hierbij is het externe gedrag van het systeem, gezien door de gebruiker.
Een use-case beschrijft één manier waarop het systeem kan gebruikt worden.
Een use-case wordt beschreven in natuurlijke taal en kan gelezen worden als een kort verhaal.
Iedere interactie begint met een actie van de actor naar het systeem en vervolgt met een aantal

31
32 HOOFDSTUK 5. INTERACTIE DIAGRAMMEN

<<actor>>
Baliemedewerker

openRekening()
stortOpRekening()
Baliemedewerker neemOpVanRekening()

Figuur 5.1: Twee notatiewijzen van actor

interacties tussen het systeem en één of meerdere actoren, totdat het einde van de use-case bereikt
is.
Voor het maken van een use-case wordt een template gebruikt (zie tabel 5.1).

Naam De naam die gebruikt wordt om de use-case aan te duiden


Samenvatting Een korte beschrijving van het doel van de use-case
Actoren Alle actoren die in de use-case een rol spelen
Aannamen De toestand van het systeem bij de start van de use-case.
Beschrijving van aan welke voorwaarden voldaan dient te zijn om
de use-case te mogen starten. Beschrijving van de toestand waarin
het systeem zich moet bevinden voorafgaand aan de toepassing
van deze use-case.
Beschrijving De uitgebreide, complete beschrijving van de reeks van interacties
tussen systeem en actor(en).
De hoofdlijn van een use-case of de normale gang van zaken: een-
voudig en duidelijk omdat er geen speciale gevallen beschreven
worden.
Uitzonderingen Speciale, te voorziene uitzonderingsgevallen die optreden tijdens
de use-case.
De speciale gevallen die niet in de hoofdlijn staan. Elke uitzonde-
ring kan best een naam krijgen.
Resultaat De toestand van het systeem na afloop van de use-case.
Beschrijving van aan welke voorwaarden voldaan wordt na afloop
van de use-case. Beschrijving van de toestand waarin het systeem
zich bevindt na de toepassing van deze use-case.

Tabel 5.1: Use-case template

Omdat de use-case zich richt op de interactie tussen de actoren en het systeem, onderschei-
den we in de beschrijving interactiestappen, aangegeven met cijfers tussen haakjes (). Deze in-
teractiestappen worden gebruikt om het verband te leggen tussen een use-case en sequence- en
communicatiediagrammen.
Er zijn twee soorten relaties tussen use-cases:
• include-relatie: verbinding tussen een use-case en een sub-case. Een sub-case is een deel
van een use-case, dat op zichzelf weer als use-case beschouwd wordt. Een sub-case kan
door een willekeurig aantal use-cases gebruikt (of beter, geı̈ncludeerd, omvat) worden. Het
vertoont veel overeenkomst met een subroutine. Iedere use-case kan zelf ook als sub-case in
een andere use-case gebruikt worden.
• extends-relatie: verbinding tussen een use-case en een tweede use-case, die optioneel kan
uitgevoerd worden binnen de eerste use-case. De eerste use-case definieert een aantal uit-
5.1. USE-CASE DIAGRAM 33

breidingspunten, namen die punten in de beschrijving van de use-case markeren. De extends-


relatie wordt gemarkeerd met zo’n uitbreidingspunt om aan te geven waar in de uitvoering
van de use-case de tweede optionele use-case ingevoegd wordt. Ook kan er een conditie
verbonden worden aan het uitvoeren van de optionele use-case.

5.1.3 Use-case diagram


De notatie van een use-case is een ellips met de naam van de use-case erin. Een sub-case wordt
op dezelfde manier als een use-case weergegeven. Een use-case wordt met een sub-case verbonden
door een onderbroken pijl van de use-case naar de subcase. Bij een extends-relatie is de richting
van de pijl anders.
Het systeem wordt weergegeven door een rechthoek waarbinnen de use-cases getekend worden.
De actoren staan altijd buiten het systeem.
In figuur 5.2 staat een voorbeeld van een beschrijving van een eenvoudige use-case. Ook het
use-case diagram is opgenomen.

5.1.4 Werkwijze
1. Identificeer de grens van het systeem en vind de actoren.
De grenzen van het systeem worden bepaald door wat wel en niet onder de verantwoorde-
lijkheid van het systeem valt. Daarna wordt gezocht naar mensen en andere systemen die
direct met het systeem communiceren. Hiervoor worden de rollen bepaald die ze spelen ten
opzichte van het systeem. Eén mens of systeem kan meerdere rollen spelen. Iedere gevonden
rol is een actor.

2. Vind use-cases voor iedere actor.


Iedere manier waarop het systeem gebruikt wordt, is een use-case. Een use-case beschrijft
de taken die een actor met behulp van het systeem moet kunnen uitvoeren.
Omwille van de globale beschrijving moeten use-cases die veel op elkaar lijken, samengevoegd
worden tot één use-case. De bedoeling is niet ieder detail te specificeren maar een goed
overzicht te krijgen van de systeemeisen.
In deze stap moeten alle use-cases geı̈dentifceerd worden. Als het aantal use-cases te groot
wordt (bijv. groter dan 50), dan moet dit gereduceerd worden door de use-cases op een
hoger niveau te beschouwen.

3. Bepaal (per use-case) de aannamen.


Onder welke omstandigheden kan en mag de use-case uitgevoerd worden: welke gegevens
moeten gekend zijn, in welke toestand moet (een deel van) het systeem zich bevinden?

4. Bepaal (per use-case) de interactie.


Bedenken van zo concreet mogelijke voorbeelden van mogelijke interacties. Bepalen van
de gebeurtenis die de use-case initieert, en bepalen wanneer de use-case afgelopen is. Het
gaat hierbij om logische gebeurtenissen, en vooral niet om de precieze gebruikersinterface.
De “normale” gang van zaken tijdens een use-case wordt in natuurlijke taal beschreven.
Belangrijk is dat in deze fase snel een beschrijving van de functionaliteit verkregen wordt
vanuit het oogpunt van de gebruiker. Teveel formaliteit vertraagt het proces en maakt het
voor de gebruiker alleen maar lastiger.

5. Bekijk (per use-case) mogelijke uitzonderingen.


In deze stap worden alle mogelijke uitzonderingen die de loop van de use-case direct beı̈nvloeden,
bekeken. Voor iedere uitzondering wordt beschreven wat het effect is op de use-case.
34 HOOFDSTUK 5. INTERACTIE DIAGRAMMEN

Naam Rekening toevoegen.

Samenvatting Er wordt een nieuwe rekening aangemaakt voor een klant.

Actoren Baliemedewerker.

Aannamen Baliemedewerker heeft beschikking over NAW-gegevens van de klant.

Beschrijving (1) De baliemedewerker maakt aan het systeem bekend dat een nieuwe
rekening aangemaakt moet worden en geeft de NAW-gegevens van de
klant. Als de klant een bedrijf is, wordt ook de kamer van koophandel
nummer ingevuld.

(2) Het systeem checkt of de klant al bekend is. Is dit het geval, dan
worden de klantrekeningen gecontroleerd op roodstaan. Als de klant
roodstaat, treedt een uitzondering op. Het systeem maakt het nieuwe
rekeningnummer aan de baliemedewerker bekend.

Uitzonderingen [Roodstaan] Als één rekening van de klant roodstaat, dan wordt hiervan
door het systeem melding gegeven. De baliemedewerker kan naar de
use-case Storten overgaan om de klant de gelegenheid te geven het saldo
aan te vullen. Als het saldo aangevuld is, dan wordt de rest van deze
use-case uitgevoerd.

Resultaat De klant heeft minstens één rekening.

Banksysteem
conditie: {klant is reeds bekend}
extension point: klantgegevens

Rekening Klantgegevens
toevoegen <<extends>> opvragen

Baliemedewerker
<<include>> Vind
Opnemen
rekening

<<include>>

Storten
Klant

Figuur 5.2: Voorbeeld van een use-case en bijhorend diagram


5.2. SEQUENCE- EN COMMUNICATIEDIAGRAM 35

6. Splits de veel voorkomende sub-cases uit.


Zoek delen van use-cases die identiek zijn. Deze worden uit de bestaande use-cases gehaald
en als sub-case gedefinieerd. De originele use-cases verwijzen vervolgens naar de betreffende
sub-case.

7. Maak het use-case diagram.


Zet alle use-cases en alle actoren in een diagram om een overzicht te krijgen van de functio-
naliteit van het systeem.

5.2 Sequence- en communicatiediagram


5.2.1 Concepten
Sequence- en communicatiediagrammen zijn interactiediagrammen. Beide nemen de use-cases als
uitgangspunt en leggen informatie vast over het interne gedrag van het systeem. Ze geven inzicht
in de interactie tussen de objecten die nodig is om het systeemgedrag te realiseren.
Een sequencediagram toont een interactie met de nadruk op het tijdsaspect. In een sequence
diagram worden de exacte events tussen de objecten aangegeven, inclusief eventuele parameters.
Veel van deze events zullen later gemodelleerd worden als operaties bij de klasse van het object
dat ze ontvangt.
In een communicatiediagram wordt exact dezelfde informatie weergegeven als in een sequence
diagram. De nadruk ligt echter niet op de tijd, maar op de samenwerking van de objecten: welke
objecten werken samen om tot een bepaald doel te komen, d.i. het uitvoeren van een bepaalde
functionaliteit voor de gebruiker.

1. Een interactie is een reeks van gebeurtenissen die plaats vinden tijdens één specifieke (deel)
sessie met het systeem. Uitgaande van de interactie tussen de actor en het systeem in een
use-case, worden nu ook de interactie met behulp van boodschappen tussen objecten in het
systeem beschreven. Iedere input van een actor in een use-case is nu input voor een specifiek
object in het systeem. Dit object kan op zijn beurt weer boodschappen sturen naar andere
objecten in het systeem.

2. In een sequencediagram wordt onder iedere instantie een levenslijn getekend.


Collaboratiediagrammen kennen 1:aan
<<actor>>
geen levenslijnen. Het actorobject
:Gebruiker :Wekker
wordt aangeduid met het stereotype
<<actor>> of met een draadpoppetje. 2:zoem
Wanneer er gebruik wordt gemaakt van klasseattributen of klasseoperaties, kan een klasse
zelf ook in een interactiediagram voorkomen.

3. Een boodschap (beter dan event) is een stimulus die van een object naar een ander object
gestuurd wordt, bijvoorbeeld operatie-aanroepen en het sturen van signalen. Een interactie
is een serie boodschappen.

4. Een tijdsconstraint is een beperking op het tijdsverloop tussen twee events.

<<actor>>
:Gebruiker :Wekker
aan
Gebruiker zet wekker aan t1
zoem
Wekker laat zoem horen t2
{t2-t1<24 uur}
36 HOOFDSTUK 5. INTERACTIE DIAGRAMMEN

5. Een interactiediagram kan als geheel in een frame geplaatst worden. Linksboven in het frame
staat dan het keyword sd, gevolgd door de naam van het interactiediagram. Door middel van
deze naam kan in een interactiediagram naar een ander interactiediagram verwezen worden:
een intern frame met het keyword ref gevolgd door de naam.

sd afgaan alarm <<actor>>


:Gebruiker :Wekker
<<actor>>
:Wekker zetTijd
:Gebruiker
aan ref
afgaan alarm
zoem

6. Een asynchrone event is een event (operatie aanroep) die niet op het moment van verzending
verwerkt wordt door het ontvangende object.
7. Een conditionele event is een boodschap die alleen kan voorkomen onder bepaalde condities.


[not local] 1:getData()
mijnPC:Client :DatabaseServer

[local] 1:getData()
:LocalDatabase

Een speciaal geval van conditionele boodschap is een keuzemogelijkheid in een sequencedia-
gram door middel van een frame met keyword alt.

mijnPC:Client :DatabaseServer :LocalDatabase

alt [not local] getData()

[local] getData()

8. Iteratie van events. Vaak komt het voor dat een boodschap meerdere keren naar een object
gestuurd wordt, bijvoorbeeld met een andere parameter.
1: show
:MainWindow :LijstWindow 2 : ∗[i := 1..10] geefElem(i) :Lijst
3: hide

9. Activering van een object. In een sequence diagram kan aangegeven worden dat een object
gedurende een bepaalde tijd actief is, bijvoorbeeld tijdens de executie van een operatie. Een
object dat uit zichzelf acties kan uitvoeren of events kan versturen, is een actief object. De
tijdsperiode gedurende welke het object een actie uitvoert, direct of indirect via aanroep van
een andere operatie, wordt aangegeven door een witte balk.
:Luchthaven v:Vlucht :Vliegtuig

loop ∗[v in binnenkomendeVluchten]


geefMaatschappij
geefMaatschappij
5.2. SEQUENCE- EN COMMUNICATIEDIAGRAM 37

In een communicatiediagram kan de tijd dat een object actief is, niet worden aangegeven.

In de meeste interactiediagrammen zijn alle objecten, met uitzondering van de initiator,


passief. Ze reageren alleen wanneer een boodschap bij hen binnenkomt. Een object kan
echter ook actief zijn: het heeft een eigen “thread of control” en kan geheel zelfstandig
boodschappen versturen of eigen acties uitvoeren. Een actief object wordt aangegeven met
een extra lijn aan beide zijkanten van de rechthoek.

pc1:Client :DatabaseServer pc2:Client

getData()
getData()

10. Recursie of zelfaanroep. Het aanroepen door een object van een operatie op zichzelf wordt
in beide diagrammen weergegeven met een kromme lijn.

11. Ook creatie en verwijdering van objecten kan weergegeven worden. (Object wordt tijdens de
interactie gecreëerd.)

12. Soms is het relevant om het resultaat van een operatie-aanroep in de diagrammen op te
nemen.

:Window
sequence diagram:
create
:IntegerLijst
geefMaximum

∗[i := 1..aantalElementen]
vergelijk(elem[i], elem[i + 1])
p

communicatiediagram:
2 : ∗[i := 1..aantalElementen]
:Window 1: p:=geefMaximum :IntegerLijst{transient} vergelijk(elem[i], elem[i + 1])
<<self>>

Voorstelling:
38 HOOFDSTUK 5. INTERACTIE DIAGRAMMEN

sequence diagram communicatiediagram


boodschap horizontale pijl met de naam er- naam met een klein pijltje erbo-
bij ven of ernaast
tijdconstraint in de kantlijn niet mogelijk
asynchroon open pijlpunt idem
synchroon gesloten zwarte pijlpunt idem
conditioneel boolean expressie tussen rechte idem
haken voor de boodschapnaam
iteratie een sterretje met de iteratiewaar- idem
den tussen rechte haken
actief zijkanten: dubbele lijn idem
recursie kromme pijl van de oorspronke- <<self>> naast de kromme lijn
lijke witte balk naar een nieuwe
witte balk die gedeeltelijk over de
oorspronkelijke ligt
activering witte balk niet mogelijk
creatie pijl naar de rechthoek boven de constraint [new] bij de interactie
witte balk
verwijdering groot, dik kruis aan het eind van constraint [destroyed] bij de
de balk interactie
constraint [transient]
resultaat een onderbroken pijl met een waarde wordt “toegekend” aan
symbolische waarde een variabele

5.2.2 Voorbeelden
Een sequence diagram is weergegeven in figuur 5.3. De tijdsvolgorde is van boven naar beneden.

sd afgaan alarm

:InvoerController :Alarm :Timer :Zoemer

wektijd()
wektijd()
aan
aan
start
hetIsTijd
start
Zoem
uit
uit
stop
stopZoem

Figuur 5.3: Voorbeeld van een sequence diagram

Exact dezelfde informatie wordt weergegeven in het communicatiediagram (figuur 5.4). Het
tijdsaspect is echter minder visueel zichtbaar. Door middel van een decimaal nummering systeem
kan duidelijk gemaakt worden welke boodschap welke andere boodschap tot gevolg heeft.
5.2. SEQUENCE- EN COMMUNICATIEDIAGRAM 39

sd afgaan alarm

1:wektijd() 3.1:uit()
:InvoerController :Alarm
2:aan() 1.1:wektijd()
3:uit() 2.1:aan()
↓2.2:start()
2.4:start()
2.3:hetIsTijd() ↑
2.5:Zoem() 3.2:stop()

3.3:stopZoem() :Zoemer :Timer

Figuur 5.4: Voorbeeld van een communicatiediagram

Het communicatiediagram kan ook gebruikt worden als overzicht van alle boodschappen die
tussen objecten van bepaalde klassen plaatsvinden. Het diagram dient als verzamelplaats voor
alle events uit de sequence en/of communicatiediagrammen. Zo’n diagram kan zelfs bij een klein
aantal klassen al behoorlijk onoverzichtelijk worden. In dat geval kan een communicatiediagram
per klasse opgesteld worden. De klasse wordt in het midden getekend met alle andere klassen
die ermee communiceren in een cirkel eromheen. In dit diagram worden alleen de uitgaande
boodschappen van en de binnenkomende boodschappen naar de middelste klasse getekend.
Sequence- en communicatiediagrammen zijn semantisch equivalent: ze representeren dezelf-
de informatie. Het sequencediagram benadrukt de volgorde van de interacties in de tijd. Het
communicatiediagram legt de nadruk op de context en de globale organisatie van de objecten die
interactie voeren. Of, het sequencediagram wordt gerangschikt op tijd, het communicatiediagram
op ruimte.

5.2.3 Werkwijze
Om een compleet systeem te modelleren zijn altijd meerdere sequence- of communicatiediagram-
men nodig. Het is belangrijk om het aantal diagrammen dat nodig is, juist in te schatten. Teveel
diagrammen maken voegt geen extra kennis over het systeem toe, maar kost wel tijd. Te weinig
diagrammen maken betekent dat er niet genoeg kennis over het systeem is vastgelegd om verder
te kunnen gaan met het ontwikkelingstraject. Enkele richtlijnen voor het juist aantal diagram-
men:
• voor elke use-case minstens één diagram;
• voor elke keuze in een use-case die een relevant verschil in het vervolg van de use case
betekent, een apart diagram;
• wanneer verschillende diagrammen veel op elkaar gelijken, wordt één diagram gemaakt met
daarbij als commentaar welke boodschappen of boodschappenseries anders zouden zijn bij
de andere diagrammen.
Het stappenplan:

1. Kies use-case en interactie.


Omdat het aantal mogelijke interacties bij één use case heel groot kan zijn, worden per
use-case enkele “typische” gevallen uitgekozen. Naast enkele representanten voor algemene
gevallen zijn ook enkele randgevallen nodig, zoals de start van het systeem of een foutieve
invoer.

2. Bepaal naar welk object de actor zijn boodschap stuurt.


40 HOOFDSTUK 5. INTERACTIE DIAGRAMMEN

Dit is het object dat het verzoek van de gebruiker voor een service aanneemt. Gedurende de
domeinanalyse kan de user interface buiten beschouwing gelaten worden. De boodschap die
van de actor naar het aannemende object gaat, kan direct naar een domeinobject gestuurd
worden. Het is ook mogelijk om in deze fase een pseudo-object te introduceren dat de user
interface voorstelt. In een latere fase zal een werkelijk interface object de boodschap van de
actor moeten aannemen.
3. Bepaal de beantwoording.
Wanneer het aangeroepen object de gevraagde service zonder hulp van andere objecten kan
uitvoeren, moet nog een boodschap van het object naar de gebruiker toegevoegd worden om
de interactie compleet te maken.
Heeft het object informatie nodig van andere objecten of is de gevraagde service duidelijk
iets dat onder de verantwoordelijkheid van een ander object valt, dan stuurt het object op
zijn beurt weer een boodschap naar een ander object. Er gaat dus een pijl van het eerste
object naar dit tweede object.
4. Herhaal de vorige stap voor elk object dat in de interactie aangeroepen wordt. Elk nieuw
object dat nodig blijkt om de interactie te kunnen vervolgen, wordt toegevoegd aan het
diagram, inclusief de boodschap die ernaar gestuurd wordt.
5. Voeg extra informatie toe.
Bepaal nu of timing constraints of asynchrone boodschappen en dergelijke van toepassing
zijn. Voeg deze informatie in de gepaste vorm aan het sequence- of communicatiediagram
toe.

5.2.4 Gebruik van CRC-kaarten


Een CRC-kaart (Classes, Responsibilities and Collaborations) is een kaartje waarop voor één
klasse alle verantwoordelijkheden en samenwerkingsverbanden staan. Een eenvoudige vorm is
weergegeven in figuur 5.5.

Klassenaam Verantwoordelijkheden
...
Samenwerking ...
... ...
...
...

(objecten die een object uit deze klasse nodig heeft (zaken die aan objecten uit deze
om aan zijn verantwoordelijkheden te kunnen voldoen) klasse kunnen gevraagd worden)

Figuur 5.5: CRC kaart

CRC-kaarten worden meestal tijdens een workshopsessie gebruikt. De deelnemers aan de sessie
zijn domeinexperts, toekomstige gebruikers en systeemontwerpers. Bij deze techniek wordt voor
iedere klasse uit het model een kaartje gemaakt, met daarop de naam van de klasse. Tijdens de
sessie zullen hierop ook de verantwoordelijkheden en de objecten waarmee objecten uit deze klasse
samenwerken, genoteerd worden. Iedere deelnemer krijgt één of meer kaartjes en vereenzelvigt
zich dus met de klasse van het kaartje. Vervolgens worden de interactiestappen gespeeld.
De spelleider speelt de externe actor en begint. Hij geeft aan tot wie (welk object dus) hij zijn
vraag stelt. In de interactie van figuur 5.3 wordt dus de vraag zet wektijd aan de InvoerController
gesteld. De persoon die het kaartje met InvoerController heeft, bepaalt nu of hij de vraag zelf kan
beantwoorden, of dat hij hulp van andere klassen nodig heeft. Als hij zelf het antwoord weet, dan
5.2. SEQUENCE- EN COMMUNICATIEDIAGRAM 41

geeft hij dat terug aan de vrager. Zo niet, dan stelt hij op zijn beurt weer een vraag aan een ander
object. Het object dat bevraagd wordt, neemt vervolgens de controle over.
Iedere vraag die aan een bepaald object gesteld wordt, wordt door de persoon die het kaart met
de desbetreffende klasse heeft, onder “verantwoordelijkheden” opgeschreven. Iedere klasse die een
vraag stelt aan een ander object, zet de naam van dat object onder “samenwerking”. Na afloop
van een sessie staan bij iedere klasse twee lijsten, een lijst met verantwoordelijkheden (zaken die
aan objecten uit die klasse gevraagd kunnen worden) en een lijst met samenwerkers (objecten die
het object nodig heeft om aan zijn verantwoordelijkheden te kunnen voldoen).
Tijdens een sessie kan het voorkomen dat een vraag gesteld wordt, maar dat de verantwoor-
delijkheid voor het beantwoorden van de vraag bij geen van de aanwezige klassen te plaatsen
is. Dit betekent dat een nieuwe klasse moet toegevoegd worden aan het klassediagram. Voor
iedere use-case kan een sessie gedaan worden. Naar het einde toe zullen steeds minder nieuwe
verantwoordelijkheden en samenwerkingen ontdekt worden.

Alarm Verantwoordelijkheden
− zetten van wektijd
Samenwerking
− activeren van wekker
− Timer
− Zoemer − stopzetten van wekgeluid

Figuur 5.6: Voorbeeld van een CRC kaart


42 HOOFDSTUK 5. INTERACTIE DIAGRAMMEN
Hoofdstuk 6

Toestands- en activiteitsdiagram

6.1 Toestandsdiagram
6.1.1 Concepten
1. Een toestand is een stabiele staat waarin een object zich gedurende enige tijd bevindt.
Een toestand wordt in het diagram aangegeven door middel van een recht-
hoek met afgeronde hoeken met daarin de naam van de toestand. leeg
Een object van klasse Beker kan in twee toestanden zijn: leeg en vol.
2. Een transitie is een toestandsovergang, meestal van één toestand naar een andere toestand.
Maar een transitie kan ook naar dezelfde toestand leiden (zelftransitie). Een transitie wordt
veroorzaakt door een event, behalve bij een automatische transitie. Een event is een gebeur-
tenis die geen tijd kent; voorbeelden zijn een synchrone operatieaanroep (call event) en het
ontvangen van een asynchroon signaal (signal event). Wanneer de event schenkIn gebeurt,
gaat het object van toestand leeg naar toestand vol.
Een toestandsovergang wordt aangegeven met een pijl tussen twee toestanden met de naam
van de veroorzakende event naast de pijl.
3. Er zijn twee speciale toestanden. Een begintoestand is de toestand waarin het object zich
bevindt wanneer het gecreëerd wordt. Er zijn alleen transities van de begintoestand naar
een andere toestand. Een eindtoestand is de toestand waarin het object niet meer bestaat.
Er komen alleen transities voor die naar de eindtoestand gaan.

nieuw
schenkIn
leeg vol
drinkOp
gooiWeg

Een begintoestand wordt aangegeven door een zwart gevulde cirkel, een eindtoestand met
een zwart gevulde cirkel met eromheen een andere cirkel.
4. Aan het toestandssymbool kunnen details toegevoegd worden.
De rechthoek met afgeronde hoeken wordt in drie gebie- Naam
den verdeeld. Het bovenste gebied bevat de naam van
toestandsvariabelen
de toestand, het middeldste gebied bevat toestandsva-
riabelen, zoals tellers en timers, en het onderste gebied activiteiten
activiteiten.
5. Een activiteit is een operatie die uitgevoerd wordt binnen de tijd dat een object zich in
één toestand bevindt. Er is altijd maar één activiteit binnen één toestand mogelijk. Een
activiteit kan onderbroken worden.

43
44 HOOFDSTUK 6. TOESTANDS- EN ACTIVITEITSDIAGRAM

Een activiteit loopt of vanzelf af, of stopt automatisch


wanneer er een event plaats vindt die een toestands- zichtbaar
overgang tot gevolg heeft.
Een activiteit wordt binnen een toestand achter een la- do/ displayWaarde
bel do/ weergegeven.
6. Een guard is een voorwaarde die aangeeft of een transitie plaats kan vinden. Een guard
wordt aangegeven door een logische expressie tussen vierkante haken. Alleen wanneer deze
waar oplevert, kan de transitie plaatsvinden.

begin
witZet
witAanZet zwartAanZet [schaakmat]
zwartZet
[schaakmat]

Een guard kan ook in combinatie met een event bij een transitie opgegeven worden. De
transitie kan dan plaats vinden wanneer de guard waar oplevert op het moment dat de event
plaats vindt.
7. Een automatische transitie is een transitie die plaats vindt wanneer de activiteit in een
toestand is afgerond. Er gebeurt dus geen event.
lekEnVol
Een automatische transitie komt altijd voor in do/ druppel
combinatie met een activiteit of een guard. leeg
vloeistof eruit

8. Een actie is een atomaire operatie, vraagt dus logisch gezien geen tijd en kan nooit on-
derbroken worden. Net als een event, is een actie òf uitgevoerd, òf moet nog uitgevoerd
worden. Een actie is altijd een neveneffect van een transitie, bijvoorbeeld het zenden van
een boodschap naar een ander object of het aanpassen van de waarde van een attribuut.

inbreker/∧sirene.start
wachtend actief

Een actie wordt weergegeven door een schuine streep achter de event waar hij bij hoort,
gevolgde door de naam van de actie. Het ∧ symbool voor de actienaam geeft aan dat een
boodschap gezonden wordt naar een ander object.
In het voorbeeld wordt de boodschap start naar het object sirene gestuurd.
9. Volgende acties komen alleen in toestandsdiagrammen voor en worden binnen de toestand
aangegeven door een label exit/ of entry/ met daarachter de actie.
Een exit-actie bij een toestand is een actie die uitgevoerd
wordt wanneer de toestand verlaten wordt, ongeacht via bellend
welke transitie. Een entry-actie bij een toestand is een actie entry/ startRing
die uitgevoerd wordt op het moment dat het object in die exit/ endRing
toestand komt.
10. Complete event/transitie notatie: eventnaam (parameters) [guard] / actie.
De totale beschrijving van een event, met alle mogelijke zijeffecten, bestaat uit de eventnaam,
een guard en een actie. Een event kan ook nog parameters hebben.
11. Een subtoestand is een toestand binnen een andere toestand. Transities van buiten de hoofd-
toestand direct naar een subtoestand zijn toegestaan en worden weergegeven met een pijl
van een toestand buiten de hoofdtoestand eindigend bij de subtoestand. In het geval dat de
transitie naar de hoofdtoestand gaat, moet binnen de hoofdtoestand een begin(sub)toestand
gedefinieerd zijn en komt het object in die begin(sub)toestand.
6.1. TOESTANDSDIAGRAM 45

drinkOp(hoeveelheid)
ondrinkbaar [hoeveelheid = inhoud]
nieuw
leeg drinkbaar
vol
schenkIn lekt(hoeveelheid)
gooiWeg
[hoeveelheid < inhoud]
halfVol
drinkOp(hoeveelheid)
[hoeveelheid < inhoud]

6.1.2 Voorbeeld
Een toestandsdiagram van een bepaalde klasse beschrijft de levensloop (of levenscyclus) van objec-
ten uit die klasse. Een toestandsdiagram wordt ook aangeduid met de term state machine. Zo’n
diagram geeft inzicht in hoe het gedrag van een object wijzigt in de tijd gedurende zijn levensloop.
Er wordt per klasse één toestandsdiagram gemaakt.
Het gebruik van toestandsdiagrammen is een bekende techniek, vooral bij real-time systemen.
Zo’n traditioneel toestandsdiagram beschrijft de toestand van het systeem als geheel en worden
vaak alleen maar gebruikt voor relatief dynamische systemen zoals procesautomatisering. De
toestandsdiagrammen binnen UML beschrijven ieder slechts de toestand van objecten uit één
klasse. In de praktijk blijken deze toestandsdiagrammen ook erg nuttig te zijn bij zogenaamde
“saaie” administratieve systemen.
Een voorbeeld van de klasse Bankrekening met attributen positiefSaldo en negatiefSaldo is
gegeven in figuur 6.1.

open
pasGeopend stort(bedrag)
[negatiefSaldo > bedrag]
stort(bedrag)
stort(bedrag)
positiefSaldo [negatiefSaldo < bedrag] negatiefSaldo
do/berekenSaldo neemOp(bedrag) do/berekenSaldo
[positiefSaldo <= bedrag]
stort(bedrag)
neemOp(bedrag)
hefOp/betaalUit(saldo)
[positiefSaldo >= bedrag]

Figuur 6.1: Een toestandsdiagram

6.1.3 Werkwijze
Eerst moet bepaald worden voor welke klassen wel en voor welke klassen geen toestandsdiagram
gemaakt zal worden. Er zijn meestal een groot aantal nogal passieve objecten die geen enkel
interessant dynamisch gedrag vertonen. De bijhorende triviale toestandsdiagrammen kunnen beter
weggelaten worden.
Het stappenplan voor het maken van één toestandsdiagram:
1. Vind de toestanden waarin een object zich kan bevinden.
Uitgangspunt is de verzameling events die bij het object kunnen aankomen. Deze verzameling
kan uit het sequence- of communicatiediagram gehaald worden.
46 HOOFDSTUK 6. TOESTANDS- EN ACTIVITEITSDIAGRAM

Een binnenkomende event is voor een object ofwel een boodschap (een aanvraag van een
bepaalde service) ofwel het antwoord op een eerder verstuurde boodschap. Bij elke event
dat bij een object kan binnenkomen, moet men zich afvragen of het object in een specifieke
toestand moet zijn om de juiste service te kunnen leveren of om juist met de binnenkomende
informatie om te gaan.

2. Vind voor iedere event de bijbehorende transitie(s).


Elke event is een aanvraag van een bepaalde service. Het uitvoeren van die service kan alleen
vanuit een bepaalde toestand en kan als gevolg hebben dat het object in een nieuwe toestand
komt. Voor elke event worden deze twee toestanden bepaald en wordt een transitie tussen
deze toestanden toegevoegd.

3. Voeg eventueel begin- en eindtoestanden toe.


Direct na de creatie van een object zal het zich in een bepaalde toestand bevinden: vanuit
de begintoestand wordt één transitie naar deze toestand weergegeven.
De levensloop van een object kan alleen beëindigd worden vanuit bepaalde toestanden. Hier-
toe kan een eindtoestand toegevoegd worden.

4. Voeg acties toe.


Een actie is altijd een neveneffect van een transitie. Voor alle gevonden transities kan
nagegaan worden of er sprake is van een neveneffect. Zo’n neveneffect moet dan als actie bij
de betreffende transitie opgenomen worden.

5. Voeg activiteiten toe aan toestanden.


Een activiteit wordt altijd uitgevoerd wanneer het object in de toestand komt, onafhankelijk
van welke event een transitie naar deze toestand heeft veroorzaakt.

6. Voeg eventueel overige informatie toe.


Wanneer de activiteiten gekend zijn, kan nagegaan worden of het beëindigen van een activi-
teit moet leiden tot een automatische transitie. Ook guards, exit en entry-acties kunnen nu
pas toegevoegd worden.

7. Itereer over de gedane stappen.


Een eerste toestandsdiagram zal onvolkomenheden en fouten bevatten. Op basis van nieuwe
inzichten moeten de gedane stappen herhaald worden totdat er voldoende vertrouwen is dat
het model de gewenste situatie beschrijft.
Tijdens het maken van toestandsdiagrammen blijkt ook dikwijls dat het klassediagram moet
bijgewerkt worden, bijvoorbeeld het toevoegen van enkele associaties of zelfs een groot aantal
klassen.

In figuur 6.2 is nog een tweede voorbeeld van een toestandsdiagram gegeven.

6.2 Activiteitsdiagram
6.2.1 Concepten
1. Een activiteit is een proces, dat eventueel samengesteld kan zijn uit andere activiteiten.
Een activiteit die niet opgedeeld wordt, is een atomaire activiteit en wordt soms ook actie
genoemd. Een samengestelde activiteit wordt opgedeeld in subactiviteiten en deze opdeling
kan verder beschreven worden in een apart activiteitsdiagram. Atomaire en samengestelde
activiteiten kunnen in een diagram naast elkaar voorkomen. Het bijhorende symbool heeft
een rechte boven- en onderkant en ronde zijkanten met een activiteitsexpressie erin.
6.2. ACTIVITEITSDIAGRAM 47

Scherm
beveiligen

[isTimeout] toetsaanslagOfMuisbeweging

Werken

Initialiseren Gebruikers- Gebruikers- Gebruikers-


Afsluiten
invoer invoer invoer
do/startOp afwachten registreren visualiseren

Figuur 6.2: Toestanden en transities bij een grafische gebruikersinterface

2. Een externe activiteit is een activiteit die niet uitgevoerd wordt door het (software)systeem
dat beschreven wordt, maar door een entiteit daarbuiten. Net als actoren in use-cases
kunnen deze entiteiten mensen zijn, maar ook externe (software)systemen. Het stereotype
<<external>> geeft aan dat het over een externe activiteit gaat.

3. Flow of control: de volgorde van activiteiten in een activiteitsdiagram; zodra een activiteit
beëindigd is, zal de volgende activiteit starten. Voorstelling: een pijl van een activiteit naar
een volgende activiteit.

Voor het begin en het eind van het diagram worden dezelfde symbolen als in een toestands-
diagram gebruikt.

<<external>>
ontvangBestelling maakLevering leverAf

4. Een connector is een indicatie dat de flow-of-control-pijl waaraan de connector is vastge-


maakt, onderbroken is. Een dergelijke onderbreking is alleen voor de tekening van belang.
Connectoren komen altijd voor in groepen met minstens twee elementen. Een connector
wordt voorgesteld als een kleine cirkel met daarin het connectorlabel.

5. Een beslispunt is een punt waar mogelijke transities door guards bewaakt worden en waar
dus meerdere uitgaande (automatische) transities van een activiteitstoestand mogelijk zijn.

De plaats waar een keuze weer bij elkaar komt, heet een samenkomst punt.
48 HOOFDSTUK 6. TOESTANDS- EN ACTIVITEITSDIAGRAM

f berekenRisico

[risico groot]
vraagAutorisatie
[risico klein]
geefLening

f gaDoor

6. Een splitsing is een transitie die resulteert in twee of meer activiteiten. In tegenstelling tot
een keuzetransitie worden bij een splitsing beide nieuwe activiteiten actief en is er sprake
van parallellisme.
Een synchronisatie is een transitie vanuit twee of meer activiteiten welke eindigt in één
toestand. Parallelle activiteiten, geı̈ntroduceerd door een splitsing kunnen zo weer bij elkaar
komen.

7. Een activiteitsdiagram kan opgedeeld worden in swimlanes om aan te geven wie er verant-
woordelijk is voor het uitvoeren van een activiteit.

financiën balie administratie


geefLening

reserveerGeld maakContract

doeAanbod

Een activiteitsdiagram is een variatie op een toestandsdiagram: alle toestanden zijn activi-
teitstoestanden. In zo’n activiteitstoestand voert het object een activiteit uit, waarna het in een
volgende toestand terecht komt. De verschillen zijn dat (1) in activiteitsdiagrammen alleen acti-
viteitstoestanden voorkomen en dus voornamelijk automatische transities (dit zijn transities die
plaats vinden wanneer de activiteit in een toestand is afgerond), en dat (2) een activiteitsdiagram
toestanden van meer dan één object kan beschrijven. Een groot nadeel van activiteitsdiagrammen
is dan ook dat de koppeling activiteit-object niet duidelijk is.

6.2.2 Werkwijze
Op hoog niveau kunnen activiteitsdiagrammen gebruikt worden voor het beschrijven van be-
drijfsprocessen. In dit geval zijn de verantwoordelijke eenheden in de swimlanes de verschillende
afdelingen van een bedrijf en is er geen directe relatie met de andere UML-diagrammen en met de
objecten uit het klassediagram. Met dit type wordt workflow modelering mogelijk, bijvoorbeeld
het weergeven van parallellisme van activiteiten.
Ook op gedetailleerd niveau kunnen activiteitsdiagrammen gebruikt worden als beschrijving
van een proces of een algoritme. In deze vorm kan het diagram gebruikt worden om een operatie
van een klasse te definiëren. Het niveau van het diagram moet natuurlijk wel hoger blijven dan
de programmacode. Volgend stappenplan kan gebruikt worden:
6.2. ACTIVITEITSDIAGRAM 49

1. Selecteer operaties.
Alleen van operaties van de klassen uit het klassediagram die werkelijk complex zijn, worden
activiteitsdiagrammen gemaakt. Meestal is dit een relatief klein aantal.
2. Vind de activiteiten en de bijhorende flow.
Schrijf de activiteiten op in volgorde waarin ze uitgevoerd moeten worden. Wanneer de
volgorde niet van belang is, gebruik dan een splitsing waarbij de verschillende activitei-
ten parallel gedaan worden. Voor een duidelijker diagram kunnen eventueel connectoren
gebruikt worden.
3. Bepaal per activiteit welk object verantwoordelijk is.
Het verantwoordelijke object is het object dat de activiteit uitvoert, nogal dikwijls het object
dat de operatie uitvoert. Maar dit is niet noodzakelijk omdat een activiteit kan gedelegeerd
worden naar een ander object.
4. Splits activiteiten indien nodig.
Indien in vorige stap geen enkel verantwoordelijk object kan gevonden worden, dan moet
die activiteit opgesplitst worden in deelactiviteiten waarvoor wel verantwoordelijke objecten
te vinden zijn. Deze opsplitsing kan binnen hetzelfde activiteitsdiagram plaatsvinden, maar
kan eventueel ook leiden tot een subactiviteitsdiagram waarin de samengestelde activiteit
beschreven wordt.
50 HOOFDSTUK 6. TOESTANDS- EN ACTIVITEITSDIAGRAM
Hoofdstuk 7

Applicatie- en
implementatiestadium

7.1 Beschrijving
In de domeinanalysefase is de focus gericht op wat er dient te gebeuren. De opgestelde modellen
richten zich op het probleemdomein; er worden geen veronderstellingen gedaan over de implemen-
tatie. In de ontwerpfase is de aandacht juist wel gericht op hoe zaken gerealiseerd moeten worden.
De aandacht verschuift van het probleemdomein naar computeraspecten.
Voordat een applicatie- of implementatieversie van de diagrammen kan gemaakt worden, moe-
ten een aantal beslissingen over de omgeving waarbinnen het systeem geı̈mplementeerd wordt,
duidelijk gedocumenteerd zijn, inclusief argumentatie en verworpen alternatieven. Zaken zoals
de keuze van de programmeertaal, besturingssysteem, klassebibliotheken (o.a. voor de GUI), da-
tabase en hardware moeten vastgelegd zijn. In verband met het gegevensbeheer moet bepaald
worden welke objecten persistent moeten zijn. Dit zijn objecten die na het beëindigen van een
sessie bewaard moeten blijven. Er moet ook geweten zijn op welke manier deze objecten moeten
worden opgeslagen.
Een andere voorwaarde voor de start van een volgend stadium is dat het huidige model stabiel
is, d.w.z. dat het de verwachting is dat de structuur en dynamiek van de objecten die tot dan
toe herkend zijn niet meer significant zullen wijzigen. Indien het domeindeel van de diagrammen
gewijzigd wordt, dan zullen ook alle beslissingen over applicatieklassen en implementatiestructuren
opnieuw bezien moeten worden. Sommige daarvan zullen nog steeds valide zijn, maar de kans is
groot dat er beslissingen bij zijn die anders uit gaan vallen.
In de ontwerpfase worden de bestaande diagrammen verder uitgewerkt tot een applicatie-
model en vervolgens tot een implementatiemodel. Gedurende dit proces worden nieuwe klas-
sen toegevoegd en bestaande klassen nader gedetailleerd. Bovendien wordt de informatie uit
alle diagrammen met elkaar geı̈ntegreerd in het klassediagram. Het uiteindelijke resultaat is een
implementatie-klassediagram, een complete beschrijving van alle klassen in het systeem. Dit is de
blauwdruk voor de implementatie. Het stelt de programmeurs in staat om rechttoe, rechtaan het
systeem te coderen.

1. Uitbreiden van bestaande diagrammen.


Er is een onderscheid tussen uitbreidingen in de diepte en in de breedte. Bij de eerste
worden aan de reeds bekende klassen meer detail toegevoegd. Bij de tweede worden klassen
en associaties aan de bestaande modellen toegevoegd. Bij een groot ontwikkelteam kunnen
beide types uitbreidingen onafhankelijk van elkaar en gelijktijdig uitgevoerd worden.
Niet alle uitbreidingen in de diepte moeten in het grafische klassediagram opgenomen wor-
den. Op die manier zou het overzicht verloren kunnen gaan. Het is praktischer om een
gedetailleerde klassespecificatie in een apart document te beschrijven.

51
52 HOOFDSTUK 7. APPLICATIE- EN IMPLEMENTATIESTADIUM

2. Koppeling van de diagrammen.


Enkele duidelijke regels voor de koppeling:

• Boodschappen of events in de interactie- of toestandsdiagrammen zijn ofwel operaties


ofwel returnwaarden van operaties in het klassediagram.
• Activiteiten in de toestandsdiagrammen zijn operaties in het klassediagram.
• De toestanden in de toestandsdiagrammen geven de pré- en postcondities voor de
operaties weer en definiëren op deze wijze de contracten van de klassen.

De toestanden in de toestandsdiagrammen worden in het klassediagram voorgesteld door de


waarden van de attributen van een object op een bepaald moment. In het geval dat klanten
van het object de toestand van dit object moeten kunnen herkennen, moeten query-operaties
op deze attributen in het klassediagram toegevoegd worden.

De verzameling van complete, volledig ingevulde klassespecificaties vormt het implementatie-


model. Het implementatiemodel is een directe, één-op-één beschrijving van de programmacode en
is een uitstekende documentatie van het systeem.
Een complete klassespecificatie bestaat uit:
• De naam en verantwoordelijkheid van de klasse, met eventueel de naam van de superklasse
waarvan eigenschappen geërfd worden.
• Voor alle attributen de naam, het type, eventuele initiële waarde en de toegestane waarden.
• Voor iedere operatie de complete signatuur: de naam, de parameters inclusief het type, het
eventuele returntype, de précondities (de voorwaarden waaronder de operatie gebruikt mag
worden), de postcondities (wat, en niet hoe, na afloop van de operatie veranderd is in de
toestand van de objecten van het systeem).
• Voor alle operaties een korte beschrijving van wat de operatie doet.
Met deze informatie wordt de exacte interface voor iedere klasse gedefinieerd.
• Privé-interface: de gehele klassebeschrijving; de interface die bekend is aan alle objecten
van deze klasse en geërfd wordt door subklassen.
• Publieke interface: (het contract) de signaturen van de publieke operaties; de interface die
bekend is aan alle andere klassen.
Dank zij zo’n expliciete interfacedefinitie kan de implementatie verder per klasse geschieden.
Alle code die tijdens de implementatie voor een klasse geschreven wordt, wordt door deze interface
afgeschermd, geheel verborgen ontwikkeld voor alle klanten van de klasse.

7.2 Werkwijze
Om tot een applicatie- of implementatiemodel te komen, worden de stappen die tot de domeinversie
van de diagrammen geleid hebben, simpelweg herhaald, maar nu met de aandacht gericht op
applicatie- of implementatieaspecten. De informatie die over een aantal diagrammen verspreid is,
moet in één diagram geı̈ntegreerd worden.

7.2.1 Integreer alle informatie in het klassediagram


Alle informatie uit de interactie- en toestandsdiagrammen die niet in het klassediagram te vinden
is, wordt daar nu opgenomen. Hiervoor worden de tien stappen om tot het origineel klassediagram
te komen, terug uitgevoerd.
1. Controleer klassen en associaties (stap 1–4).
Klassen die tijdens het maken van de interactie- en toestandsdiagrammen geı̈dentificeerd
zijn, worden aan het klassediagram en aan de modeldictionary toegevoegd (voor zover dit
7.2. WERKWIJZE 53

nog niet gebeurd is). Associaties tussen de nieuwe klassen en de oude klassen worden gelegd.
De modeldictionary voor alle oude klassen wordt gecontroleerd en eventueel verbeterd.
Uit de sequence- of communicatiediagrammen blijkt welke objecten boodschappen versturen
naar andere objecten. Om een boodschap te kunnen sturen moet het ontvangende object
wel bekend zijn bij de zender. Hiervoor bestaan in het algemeen drie manieren:
• De zender heeft een link met de ontvanger, dus de klasse van de zender heeft een
associatie met de klasse van de ontvanger (zie figuur 7.1).
• De zender krijgt een referentie naar de ontvanger (de identiteit ervan) mee als para-
meter bij een boodschap. Gedurende het uitvoeren van die boodschap kent de zender
dan de ontvanger (zie figuur 7.2).
• De zender kan vanuit een object dat hem bekend is (op één van bovenstaande ma-
nieren) via één of meer links het ontvangende object vinden.
Indien de zenders uit de interactiediagrammen de ontvangende objecten niet kunnen berei-
ken, moet het klassediagram aangepast worden.
2. Leid attributen uit de interactie- en toestandsdiagrammen af (stap 5).
Hier kunnen bijvoorbeeld toestandsattributen worden afgeleid, die aangeven in welke toe-
stand een object zich bevindt.
3. Voeg operaties aan het klassediagram toe (stap 6).
Binnenkomende boodschappen uit een interactiediagram en binnenkomende events uit een
toestandsdiagram worden operaties bij de betreffende klasse in het klassediagram. Een even-
tuele returnwaarde, die in het interactiediagram aangegeven is, moet meegenomen worden
als resultaattype van de operatie. Alle operaties die zo uit boodschappen/events ontstaan,
zijn publieke operaties.
Voor iedere actie en activiteit uit een toestandsdiagram wordt een corrsponderende operatie
bij de betreffende klasse gemaakt. Omdat dit allemaal zaken zijn die het object intern
uitvoert, worden deze operaties in het algemeen privé-operaties binnen de klasse.
4. Vervolledig het klassediagram (stap 7–10).
Het toevoegen van overerving, het schrijven van OCL-constraints en het model eventueel
opdelen.

Rechthoek Tekening Window


* *

teken(w:Window) teken(w:Window) tekenLijn()

Figuur 7.1: Deel van een klassendiagram


Window heeft een associatie met één Tekening: dus een Window object
kan de boodschap teken() sturen naar het Tekening object.

7.2.2 Detailleer het klassediagram


1. Ontwerp associaties.
Omdat nu bekend is in welke richting de associaties in het klassediagram doorlopen worden,
kan beslist worden hoe de associaties werkelijk geı̈mplementeerd zullen worden: bidirectio-
neel of in één richting (in dit geval wordt een pijlpunt toegevoegd aan de associatie).
Associaties worden in de implementatie van een klasse omgezet naar attributen met als type
de geassocieerde klasse. De richting waarin de associatie gebruikt wordt, bepaalt in welke
klasse de associatie als attribuut opgenomen wordt. Bij een bidirectioneel gebruik van de
associatie worden in beide klassen attributen met elkaars type opgenomen.
54 HOOFDSTUK 7. APPLICATIE- EN IMPLEMENTATIESTADIUM

:Window :Tekening :Rechthoek


teken(self)
teken(window)

tekenLijn()

Figuur 7.2: Een klein sequencediagram


Rechthoek krijgt bij de boodschap teken() als parameter een referentie
naar een Window object mee; dus Rechthoek kent Window en kan er
bijvoorbeeld de boodschap tekenLijn() naar toe sturen.

werktbij jef:Persoon werktbij denayer:Bedrijf


Persoon Bedrijf
bedrijf: denayer arbeider: jef

Ook een associatie met een associatieklasse wordt omgezet naar attributen bij de betreffende
klassen. Bij een bidirectionele associatie zal de associatieklasse attributen hebben met als
type de klassen die met elkaar geassocieerd zijn. Deze beide klassen zullen attributen hebben
met als type de associatieklasse. Indien een associatie met een associatieklasse slechts in
één richting wordt geı̈mplementeerd, vervallen een aantal attributen.

Huwelijk

Man Vrouw
isGetrouwdMet

Wanneer een associatie in twee richtingen wordt geı̈mplementeerd, moet een strategie geko-
zen worden om ervoor te zorgen dat beide richtingen consistent met elkaar blijven. Meestal
betekent dit dat de operatie waarin de associatie (d.i. attribuut) wordt bijgewerkt, extra
acties zal uitvoeren om de consistentie ofwel te controleren ofwel af te dwingen.
2. Ontwerp attributen.
Er wordt bepaald hoe de objecten intern gerepresenteerd gaan worden: voor alle attributen
moet het type en het waardebereik gedefinieerd worden. Tijdens deze stap worden vaak
utilityklassen geı̈dentificeerd die als type van een attribuut nodig zijn, bijvoorbeeld Tijdstip,
Datum, Adres. Deze utilityklassen worden meestal niet opgenomen in het klassediagram
omdat ze van ondergeschikt belang zijn en het overzicht in het diagram verloren zou kunnen
gaan.
3. Ontwerp operaties.
Het type van de parameters en resultaat moeten worden toegevoegd. Ook pré- en postcon-
dities (in OCL) kunnen bij elke operatie in het klassediagram toegevoegd worden. Uit het
toestandsdiagram kan afgeleid worden welke events voor een object toegestaan zijn in een
bepaalde toestand. Hieruit volgen direct de voorwaarden om de bij een event horende ope-
ratie te mogen gebruiken: het object moet zich in een toestand bevinden waarin het event
is toegestaan (pré-conditie). Uit de toestandsdiagrammen kan ook afgeleid worden wat het
effect van een event is. Het object kan in een nieuwe toestand komen. Deze informatie
wordt opgenomen in de postconditie van de bij de event horende operatie.
7.2. WERKWIJZE 55

4. Overerving.
De overervingsrelaties moeten opnieuw gecontroleerd worden; waarschijnlijk zal weinig de-
tailinformatie toegevoegd worden.
5. OCL-constraints.
In eerdere stadia hebben deze veel inzicht gegeven in de exacte structuur en werking van
het systeem. Nu moet bepaald worden hoe deze constraints geı̈mplementeerd gaan worden.
Is het mogelijk dit te doen met behulp van een exceptiemechanisme of kunnen een paar
eenvoudige testen op het moment dat een operatie wordt aangeroepen, volstaan.
6. Packages.
Het (opnieuw) opdelen van het model is zinvol wanneer door de extra toegevoegde infor-
matie, een nieuwe of andere logische opdeling kan gemaakt worden.

7.2.3 Voeg nieuwe klassen toe


1. Applicatieklassen of het definiëren van de userinterface.
Tot nu toe is de enige beschrijving van de gebruikersinterface de verzameling use-cases. In
deze stap wordt bepaald welke klassen toegevoegd moeten worden om het aan de gebruiker
mogelijk te maken met de objecten in het domeinmodel te werken. Er zijn twee typen
klassen die normaal gezien tot de gebruikersinterface behoren: de views en de controllers.
Een view (of presentatie) is een klasse die de informatie uit één of meer instanties van een
domeinklasse op een bepaalde wijze aan de gebruiker presenteert. Om de views te vinden
wordt bottom-up gewerkt. Voor elke interactie uit de interactiediagrammen wordt bekeken
welke informatie uit de domeinklassen door de gebruiker gezien of gewijzigd moet kunnen
worden. Vervolgens wordt voor ieder van deze domeinklassen één of meer manieren bepaald
waarop ze gepresenteerd kunnen worden. Binnen een GUI vormen deze presentaties vaak
onderdelen van een window.
Een controller is een klasse die de manier waarop de gebruiker met het systeem kan wer-
ken, bestuurt. Een controller verwerkt de invoer van de gebruiker en stuurt de views en
domeinobjecten aan. Om de controllers te vinden wordt top-down gewerkt. Per taak die de
gebruiker met het systeem moet kunnen uitvoeren, wordt bepaald of een controller toege-
voegd moet worden die de wijze bestuurt waarop de gebruiker de taak kan uitvoeren. Over
het algemeen zijn de use-cases gestructureerd naar deze taken en kunnen deze als input
gebruikt worden. Vaak wordt bij iedere use-case een controller geı̈dentificeerd die aangeeft
welke gebruikersacties, in welke volgorde, beschikbaar zijn.
2. Implementatieklassen.
Utilityklassen, zoals queues, worden toegevoegd om de implementatie van het systeem te
vergemakkelijken. Deze komen meestal op een natuurlijke en geleidelijke manier tot stand.
Er moet ook aandacht besteed worden aan de opslag van persistente objecten. Soms is
het nodig om extra klassen aan het systeem toe te voegen die de opslag regelen; soms kan
worden volstaan met extra operaties in domeinklassen. Bij het gebruik van een relationele
databank kan het bij voorbeeld een optie zijn om elk domeinobject een extra operatie te
geven met daarin de benodigde SQL statements verwerkt. Bij een “lagen-model” is het
meestal aan te raden om in de datalaag extra klassen te voorzien die als intermediair tussen
de domeinobjecten en de fysieke opslag fungeren.
3. Overige stappen.
Voor de nieuwe klassen moeten de associaties, attributen, operaties, enz. bepaald worden.
Dit kan weer door het stappenplan voor het klassediagram te doorlopen maar met een
andere focus.

7.2.4 Maak dynamische diagrammen


De werkwijze voor het opstellen van sequence-, communicatie- en toestandsdiagrammen voor de
nieuwe objecten uit de bijgevoegde klassen is zoals beschreven in de vorige hoofdstukken. De use-
56 HOOFDSTUK 7. APPLICATIE- EN IMPLEMENTATIESTADIUM

cases dienen als basis, maar op dit moment worden o.a. boodschappen beschreven die uitgewisseld
worden tussen objecten in de userinterface. Van de sequencediagrammen zal er vaak een nieuwe
versie gemaakt worden. De bestaande toestandsdiagrammen blijven correct, maar er zullen vooral
voor controllerklassen nieuwe toestandsdiagrammen gemaakt worden.

7.2.5 Integreer alle informatie

Deze laatste stap is eigenlijk weer gelijk aan de eerste stap. Nieuwe kennis, nieuwe details, maar ook
compleet nieuwe klassen moeten op zorgvuldige wijze worden ingepast in het bestaande model.
Vaak blijkt in dit stadium dat de bestaande diagrammen structureel weinig gewijzigd worden,
terwijl er erg veel elementen (zowel operaties, attributen als klassen) aan toegevoegd worden.
Ook tijdens het implementeren kunnen kleine punten in het model bijgesteld moeten worden.
Hierbij moet steeds de uitgangspunten van het systeem in de gaten gehouden worden. Dit zijn
de verantwoordelijkheden die in de domeinklassen vastgelegd zijn. Verder is het zinvol om schei-
dingen zoals in een lagen-model te gebruiken. Deze leveren een bijdrage aan de flexibiliteit en
onderhoudbaarheid van het systeem. Als een lagen-model gebruikt wordt, is het belangrijk om de
scheidingen zuiver te houden. Databeheer hoort thuis op de datalaag en niet in bijvoorbeeld de
userinterfacelaag, ook al kost dit in eerste instantie meer werk. Dergelijke kosten worden tijdens
onderhoud terugverdiend.

7.3 Component- en deployment diagrammen


Deze diagrammen vormen de implementatie diagrammen in UML. Beide diagrammen zijn relatief
nieuw en danken hun opkomst aan de groeiende belangstelling voor het ontwikkelen van software
door middel van plug-and-play componenten.
De interesse in componenten zou men kunnen omschrijven als een “hype”. Het is een relatief
nieuwe term in de informatica met nog verschillende definities:
• An executable software module with identity and a well-defined interface (Booch).
• A component is a physical and replaceable part of a system that conforms to and provides
the realization of a set of interfaces (Booch, Rumbaugh en Jacobson).
Uit deze definities blijken al twee kenmerken: een goed gedefinieerde interface en een execu-
teerbare eenheid. Een derde essentieel kenmerk van een component is dat zijn interface(s) bekend
moeten zijn voor mogelijke gebruikers. In een componentsysteem (bijv. CORBA1 , DCOM, Ja-
vaBeans) functioneert een interface als een contract tussen de component die de interface imple-
menteert en de componenten die gebruikmaken van deze component.
Een component is niet een volledige applicatie, maar een deel van een groter geheel, dat niet
volledig gekend is. Een component wordt dus gebruikt in onvoorspelbare combinaties met andere
componenten. De combinatie van componenten die het geheel vormt, waarbinnen een component
zijn werk moet doen, is per definitie onvoorspelbaar.
Een samenvattende definite:

Een component is een executeerbare eenheid, maar geen complete applicatie, met één of
meer goedgedefinieerde interfaces die binnen een componentensysteem bekend gemaakt
kunnen worden, en die binnen het systeem op onvoorspelbare wijze gebruikt wordt.

1 Common Object Request Broker Architecture


7.3. COMPONENT- EN DEPLOYMENT DIAGRAMMEN 57

Een component wordt in een UML-


diagram weergegeven als een rechthoek
met daarop aan de linkerkant twee klei- Opslag
nere rechthoekjes.
In het componentdiagram worden de orga-
nisatie van en de afhankelijkheden tussen
componenttypes weergegeven. Een com-
ponenttype (of kortweg ook component)
geeft de soort van de executeerbare een-
heid aan, niet de executeerbare eenheid UserInterface Model
zelf. Dit is analoog aan het onderscheid
tussen klasse en object.
Verschillen met een package: een package is niet noodzakelijk een afzonderlijk executeerbare
eenheid en een package zal meestal binnen een min of meer voorspelbare context werken. Wanneer
een systeem wordt opgedeeld op een manier die resulteert in delen die wel onderling minimaal
gekoppeld zijn en intern maximaal samenhang hebben, maar niet apart executeerbaar zijn, is dit
een opdeling in packages en niet in componenten.
Het splitsen van een systeem in componenten zou moeten leiden tot een opdeling waarbij de
delen zoveel mogelijk onafhankelijk van elkaar zijn. Bij het bepalen van de componenten moet men
er op letten dat relaties tussen klassen in het object- en dynamisch model ook relaties impliceren
tussen de componenten waarin de klassen voorkomen. Bij kleinere projecten kan het splitsen in
componenten in de ontwerpfase gebeuren. Bij een groter project kunnen meestal bij het begin van
de analysefase de belangrijkste componenten onderscheiden worden. Iedere component wordt dan
apart ontwikkeld.
Een node is een fysiek object dat een computerresource voorstelt. Het is een algemene naam
voor elk type computerelement (computer, monitor, schrijfstation, printer, modem, enz.). Er be-
staan twee soorten nodes. Een processor (verwerker) is een node die een component kan uitvoeren.
Een device (apparaat) is een node die dat niet kan. Een device (zoals een printer of een monitor)
is op één of andere manier een interface naar de buitenwereld.

<<processor >> <<device>>


deMachineVanJef: PC deFax: Fax

Over het algemeen heeft een node geheugen en vaak ook een processor. Een node wordt in
een diagram weergegeven als een kubus of balk. Een deployment diagram toont de configuratie
van nodes in het run-time systeem en de componentinstanties en objecten die daarop draaien. De
nodes zijn met elkaar verbonden door communicatiepaden (een doorgetrokken lijn van de ene node
naar de andere). Deployment diagrammen zijn alleen zinvol bij de bouw van een gedistribueerd
systeem.
58 HOOFDSTUK 7. APPLICATIE- EN IMPLEMENTATIESTADIUM

Internet
<<Processor>>

:ISP

<<Processor>>
<<Device>>
:mijnComputer
:Monitor

<<Device>> Linux

:Modem

<<Device>>

Netscape :Printer
UserInterface

Figuur 7.3: Deploymentdiagram

You might also like