Ga naar hoofdinhoud

Vergelijkingscriteria

Het is handig om twee sequentiediagrammen te vergelijken aan de hand van een specifieke procedure, meestal is dit een methode uit een klasse (maar niet altijd).

Vergelijkingscriteria

Neem een specifieke procedure uit twee sequentiediagrammen die voor dezelfde domain story verschillende oplossingen weergeven.

Beantwoord voor elk sequentiediagram de volgende drie vragen:

  1. Welk object weet hoe een functie/methode werkt?
  2. Van welke object(en), of actor(en) krijgt het object bij vraag 1 informatie om het werk te kunnen doen? (anders gezegd: Waar komen de parameters vandaan?)
  3. Welke objecten moeten binnen de procedure samenwerken om het werk te kunnen doen? (NB: Nieuwe objecten maken, doorgeven of retourneren telt niet als samenwerken, alleen methoden aanroepen van andere eerder gemaakte objecten telt als samenwerken).
vuistregel

Je probeert de hoeveelheid informatie en de hoeveelheid samenwerking uit criterium 2 en 3 zo laag mogelijk te houden. (loose coupling = lage koppeling)

Voorbeeld: genereren van een kaartje

We bekijken het genereren van een kaartje van de bioscoop-casus uit de voorbereiding. Hieronder zie je twee sequentiediagrammen die twee verschillende oplossingen weergeven voor het genereren van een kaartje. We beantwoorden bovenstaande drie vragen voor elk sequentiediagram.

Klassendiagram

Dit is het klassendiagram met de vraag die we willen beantwoorden met de sequentiediagrammen.

a6b500d3e2d2f8db78fb9a4f4fcfa4a4

PlantUML broncode voor "klassendiagram met overweging"
@startuml

@startuml
hide circle

class Vertoning <<entity>> {
id
titel
datum
starttijd
filmzaal
getBeschikbareStoelen()
genereerKaartje(stoelNummer)
}

note right of Vertoning::genereerKaartje
De vraag is of
deze Vertoning deze
methode moet
bevatten
end note

class Stoel <<entity>> {
stoelNummer
isBeschikbaar
reserveer()
}

class Kaartje <<Value Object>> {
titel
datum
starttijd
filmzaal
stoelNummer
}

Vertoning "1" --> "stoelen *" Stoel

@enduml

Klassendiagram met 3 klasse(n) en 1 relatie(s).

Klassen:

  • Klasse Vertoning met stereotype entity met:
    • publieke methode 'getBeschikbareStoelen', zonder parameters, return type void
    • publieke methode 'genereerKaartje', met parameter(s) 'stoelNummer', return type void
    • publieke attribuut 'id'
    • publieke attribuut 'titel'
    • publieke attribuut 'datum'
    • publieke attribuut 'starttijd'
    • publieke attribuut 'filmzaal'
  • Klasse Stoel met stereotype entity met:
    • publieke methode 'reserveer', zonder parameters, return type void
    • publieke attribuut 'stoelNummer'
    • publieke attribuut 'isBeschikbaar'
  • Klasse Kaartje met stereotype Value Object met:
    • publieke attribuut 'titel'
    • publieke attribuut 'datum'
    • publieke attribuut 'starttijd'
    • publieke attribuut 'filmzaal'
    • publieke attribuut 'stoelNummer'
    • geen methoden

Relaties:

  • Vertoning heeft een associatie-relatie met naam 'stoelen *' met Stoel

Notities:

  • Bij klasse Vertoning: ":genereerKaartje"

Optie A: CinemaApp genereert Kaartje

cb803c36673ca135c4f231f399785fdc

PlantUML broncode voor "systeem genereert kaartje optie 1"
@startuml

title Optie A CinemaApp genereert Kaartje

autonumber

actor Bezoeker
participant "app:\nCinemaApp" as app
participant "vertoning:\nVertoning" as vertoning
participant "stoel:\nStoel" as stoel
participant "kaartje:\nKaartje" as kaartje
database Store

Bezoeker -> app : reserveerStoel(\n\
stoelNummer, id)

app -> Store : vertoning = findVertoning(id)
app -> vertoning: reserveerStoel(stoelNummer)
vertoning -> vertoning: stoel = findStoel(stoelNummer)

vertoning -> stoel : reserveer()
stoel -> stoel: isBeschikbaar(false)

app -> vertoning: titel = getTitel()
app -> vertoning: datum = getDatum()
app -> vertoning: startTijd = getStartijd()
app -> vertoning: filmzaal = getFilmzaal()

create kaartje
app -> kaartje : kaartje = new Kaartje(titel, datum, startTijd, filmzaal, stoelNummer)
Bezoeker <-- app : kaartje

@enduml

Sequentiediagram met 6 deelnemers: Bezoeker, app van het type CinemaApp, vertoning van het type Vertoning, stoel van het type Stoel, kaartje van het type Kaartje en Store.

Interacties:

  1. Bezoeker roept app.reserveerStoel(\n\() aan
  2. app roept Store.vertoning = findVertoning(id) aan
  3. app roept vertoning.reserveerStoel(stoelNummer) aan
  4. vertoning roept vertoning.stoel = findStoel(stoelNummer) aan
  5. vertoning roept stoel.reserveer() aan
  6. stoel roept stoel.isBeschikbaar(false) aan
  7. app roept vertoning.titel = getTitel() aan
  8. app roept vertoning.datum = getDatum() aan
  9. app roept vertoning.startTijd = getStartijd() aan
  10. app roept vertoning.filmzaal = getFilmzaal() aan
  11. app roept kaartje.kaartje = new Kaartje(titel, datum, startTijd, filmzaal, stoelNummer) aan
  1. Welk object weet hoe de functie/methode voor het genereren van een kaartje werkt?

Het object app. De klasse CinemaApp heeft (nog) geen definitie van de methode genereerKaartje maar de code om dit te doen is er wel.

  1. Waar komen de parameters vandaan?

Het object app krijgt van actor Bezoeker de informatie over stoelNummer en van object vertoning de informatie over titel, datum, startTijd en filmzaal.

  1. Met welk(e) object(en) moet er binnen genereer kaartje samengewerkt worden?

Geen (een nieuw kaartje-object maken telt niet).

Optie B: Vertoning genereert Kaartje

319f6c15b70c547a35db2c21ec3803e6

PlantUML broncode voor "systeem genereert kaartje optie 2"
@startuml

title Optie B: Vertoning genereert kaartje

autonumber

actor Bezoeker
participant "app:\nCinemaApp" as app
participant "vertoning:\nVertoning" as vertoning
participant "stoel:\nStoel" as stoel
participant "kaartje:\nKaartje" as kaartje
database Store

Bezoeker -> app : reserveerStoel(\n\
stoelNummer, id)

app -> Store : vertoning = findVertoning(id)
app -> vertoning: reserveerStoel(stoelNummer)
vertoning -> vertoning: stoel = findStoel(stoelNummer)

vertoning -> stoel : reserveer()
stoel -> stoel: isBeschikbaar(false)

app -> vertoning : genereerKaartje(stoelNummer)


create kaartje
vertoning -> kaartje : kaartje = new Kaartje(\n\
titel, datum, startTijd, filmzaal, stoelNummer)
app <-- vertoning: kaartje
Bezoeker <-- app : kaartje

@enduml

Sequentiediagram met 6 deelnemers: Bezoeker, app van het type CinemaApp, vertoning van het type Vertoning, stoel van het type Stoel, kaartje van het type Kaartje en Store.

Interacties:

  1. Bezoeker roept app.reserveerStoel(\n\() aan
  2. app roept Store.vertoning = findVertoning(id) aan
  3. app roept vertoning.reserveerStoel(stoelNummer) aan
  4. vertoning roept vertoning.stoel = findStoel(stoelNummer) aan
  5. vertoning roept stoel.reserveer() aan
  6. stoel roept stoel.isBeschikbaar(false) aan
  7. app roept vertoning.genereerKaartje(stoelNummer) aan
  8. vertoning roept kaartje.kaartje = new Kaartje(\n\() aan

Doe voor optie B nu zelf de analyse aan de hand van de criteria net als bij A is gedaan, en schrijf de antwoorden voor jezelf op.

(Zet hieronder onder de vragen een blok met je muis om antwoorden te zien, maar doe eerst zelf een poging!)

❓ Of maak deze quiz met deze vragen in multiple choice format om te oefenen.

  1. Welk object weet hoe de functie/methode voor het genereren van een kaartje werkt?

De klasse Vertoning heeft een definitie van de methode genereerKaartje.

  1. Waar komen de parameters vandaan?

Het object vertoning krijgt van object app de informatie over stoelNummer

  1. Met welk(e) object(en) moet er binnen genereer kaartje samengewerkt worden?

Geen (een nieuw kaartje-object maken telt niet).

Analyse en conclusie

Welke ontwerpbeslissing is het beste voor de functionaliteit 'genereren van een kaartje' van de bioscoop casus? Welke participant kun je het best deze verantwoordelijkheid geven?

Aan de hand van de vuistregel om hoeveelheid data heeft optie B de voorkeur voor het genereren van een kaartje. Want deze heeft van minder objecten informatie nodig (criterium 2; vertoning heeft alle informatie over titel, datum en startTijd en filmzaal al).