In 't kort: Modelleren met UML
Afbeeldingen:
Artform NO. 1

Haagse Hogeschool - Afdeling Informatica
OOA & OOD
Object oriented analysis and design
Reader bij het vak AP-003
Van de opleiding I
Door Jan Schramp
Juli 2003

 

Verantwoording

Deze reader is een bewerking van het boek APPLYING UML AND PATTERNS van Craig Larman ISBN 0-13-092569-1 uitgegeven door Prentice Hall. Dit boek is een diamantmijn voor goede ideeën. Helaas heeft een diamantmijn een groot probleem. Je moet tonnen zand zeven om een beetje diamanten te vinden. Het is geen kluis met diamanten.

Praktisch komt het er op neer dat studenten deels het boek niet willen kopen vanwege de prijs, en als ze het al kopen het dan niet willen lezen vanwege de dikte en het erge Amerikaans in al die voorbeelden.

In deze reader wil ik een andere aanpak uitproberen: ik volg Craig Larman in grote lijnen, en vertaal de theorie in een reeks stellingen van de soort: "Als een OO Analyse niet helder is, maar onbegrijpelijk, dan deugt die niet." De bedoeling is dat deze stellingen richting geven aan het analyseproces en het ontwerpproces. Ik eindig met wat checklijstjes waarmee studenten en beoordelaars de software na kunnen lopen.

Het resultaat wordt naar ik hoop een handvol diamanten gezeefd uit de diamantmijn van Craig Larman. Anderen zullen later ongetwijfeld gaan zeggen dat die diamanten zo puur opgediend behoorlijk onverteerbaar zijn. Helaas stuiten we hier op een behoudswet: een probleem verandert niet van grootte door er meer woorden aan te besteden. Mijn wiskundige achtergrond maakt dat mijn voorkeur uitgaat naar korte, scherpe en heldere formules.

En als u het niet begrijpt kunt u altijd nog Craig Larman raadplegen. Naar hem en zijn boek verwijs ik hierna met [Larman]. Ik volg de titels van zijn hoofdstukken. Daarnaast voeg ik wat peper en zout toe uit mijn eigen koker om een smakelijke hap te maken.

Ik behandel geen schematechnieken volgens UML. Dit document is van oorsprong bedoeld voor het vak AP-003, een integrerend practicum, dat voorafgegaan is door een cursus UML. UML plaatjes worden dus bekend verondersteld evenals de kernbegrippen uit de OO denkwijze.

 

 

 

 

 

1 Objectgeoriënteerde analyse en ontwerp

  • Verwar automatisering niet met "business process reengineering".
  • Een automatiseerder is geen organisatiedeskundige.
  • Een voorstel begint op de achterkant van een sigarendoosje. Wantrouw zo’n voorstel. Ga er niet direct mee op de loop, de opdrachtgever was dronken.
  • Analyse betreft de buitenwereld van het informatiesysteem.
  • Analyse betreft de huidige situatie en de gewenste situatie.
  • Analyse beschrijft wat een systeem moet kunnen, niet hoe het gedaan wordt.
  • Analyse werkt top-down: van het globale geheel naar de details.
  • Analyse geeft slechts een benadering van de gewenste situatie.
  • Als het resultaat van een analyse onbegrijpelijk is, dan is de analyse nutteloos.
  • Wensenanalyse met Use-Cases is geen onderdeel van OOA (object georiënteerde analyse)
  • UML is een diagrammentaal.
  • UML is vooral bruikbaar voor discussies, kladpapier en schoolborden.
  • UML is niet bruikbaar voor omvangrijke gedetailleerde specificaties. Gebruik hiervoor opsommingen. Noteer de ideeën direct in een programmeertaal als Java of C++.
  • Patterns zijn ontwerpREGELS, geen vrijblijvende opties. Niet "Zo kan je het misschien doen", maar "ZO MOET JE HET DOEN".
  • Patterns regelen het verdelen van taken en verantwoordelijkheden over de onderdelen van een systeem.
  • Analyse gaat over het onderzoeken van een (beoogd) systeem.
  • Design gaat over het construeren van een oplossing.
  • OOAnalyse beschrijft een systeem in termen van dingen en concepten en hun onderlinge relaties uit de echte wereld.
  • OODesign vertaalt de objecten uit OOA naar software objecten en voegt daar extra software objecten aan toe.

 

 

2 Iteratieve ontwikkeling en Unified Process

  • Meestal begrijpen we elkaar niet eens. Maar als we goed onderhandelen over de betekenis van de woorden lukt het soms.
  • In één keer een specificatie correct krijgen is net zo onmogelijk als in één keer een programma correct opschrijven.
  • Iteratief-incrementele ontwikkeling volgens Unified Process poogt een systeem in kleine stappen te ontwikkelen. Het systeem moet geleidelijk groeien.
  • Analyse, ontwerp en implementatie moeten in samenhang groeien. Het resultaat van iedere iteratie moet een werkend maar onvolledig systeem zijn.
  • De output van een iteratie is niet een prototype dat later wordt weggegooid.
  • Iteraties duren kort. Voor opdrachten op school adviseer ik iteraties van 1 week. Aan het eind van iedere week van het schoolproject zijn er zichtbare resultaten ter beoordeling van de opdrachtgever.
  • Doel is: kleine stappen te maken, snelle terugkoppeling te krijgen op ideeën en resultaten, snel aan kunnen passen aan nieuwe ideeën.
  • Timeboxed iteratie gebruiken: rigide einddatum handhaven voor iedere iteratie. Anders kan je geen vaste afspraak maken voor presentatie van resultaten aan opdrachtgever of klankbord-groep. Zo'n afspraak is lastig te maken.
  • Tegenover vaste tijdsruimte flexibele invulling van iteratie regelen via MOSTEK principes. Must-haves moeten af in de gegeven tijd. Overige onderdelen voor zover mogelijk.
  • Start met waardevolle en risicovolle delen in de eerste iteraties.
  • Betrek opdrachtgever / gebruikers / klankbordgroep zo nauw mogelijk bij de ontwikkeling.
  • Bouw een samenhangende kernarchitectuur in de eerste iteraties.
  • Test voortdurend de kwaliteit, test vroeg, test in de practijk.
  • Laat Use-Cases samenvallen met iteraties.
  • Gebruik UML voor het visueel modelleren van software.
  • Overdrijf het UML-modelleren niet. Alleen voor zover je zelf gelooft dat het je helpt. Het mag geen blok aan het been worden.
  • Het geloof dat je OO-goden kunt behagen met UML zodat alles vanzelf goed komt is een ketterij.
  • Inceptiefase: benaderde ideeën , business case, bereik van project, vage schattingen.
  • Elaboratiefase: precieze ideeën, iteratieve implementatie van de kernarchitectuur, beperken van de grootste risico’s, vaststellen van de meeste eisen en grenzen van systeem, realistischer schattingen.
  • Constructiefase: iteratieve implementatie van de rest, voorbereiding voor ingebruikstelling.
  • Transitiefase: beta testen, uitleveren, in gebruik nemen.
  • Iedere fase bevat één of meer iteraties. Fasen volgen elkaar op. Fasen vormen geen waterval! Binnen iteraties gaan analyse, ontwerp, programmeren en testen hand in hand.

Zie verder [Larman] 2.8

 

 

4 Inceptie = het begin van de ontwikkeling

  • Inceptie is een korte initiële stap om uit te maken: wat is het idee, welke toepassing gaat het om? Haalbaaar / levensvatbaar? Kopen of zelf bouwen? Grove schatting van de kosten 10000 Euro? 100000 euro? Of miljoenen? Doen we het of niet?
  • Inceptie kan heel kort zijn.
  • In één zin: in kaart brengen van de reikwijdte van het product, het idee en de zakelijke toepassing.
  • Het hoofdvraag die we beantwoorden is: Zijn de belanghebbenden het fundamenteel eens over het idee achter het project en is het de moeite waard om te investeren in serieus onderzoek?
  • Deze producten kan je maken bij inceptie:
  • Visie-document en beschrijving van de zakelijke toepassing.
  • Use-Case-model.
  • Aanvullende specificaties.
  • Begrippenlijst.
  • Onderzoeken van de risico’s.
  • Prototypen bouwen als proof-of-concept.
  • Plan voor de volgende iteraties.
  • Deze producten hoeven niet volledig af te komen. Het gaat hier om een eerste indruk van de hoofdlijnen.
  • Alleen die producten maken waarvan het nut vanzelf spreekt.
  • Inception duurt heel kort. Voor een schoolproject maximaal één dag.
  • Niet alle systeemeisen worden in kaart gebracht. Het gaat om de grote lijnen.
  • Planningen zijn heel voorlopig.
  • Architectuur ligt nog niet vast.
  • Er moet wel een duidelijke toepassing in de bedrijfsorganisatie worden uitgewerkt. Geen zweverige plannen zonder opdrachtgever! Het idee achter het project, de doelstelling moet duidelijk zijn.
  • Actors en Use-Cases moeten benoemd kunnen worden zonder veel verder in details te gaan.
  • Alleen de Use-Cases van de hoofdlijnen moeten goed zijn uitgewerkt.

Zie verder 4.4

 

5 Begrijpen van Systeemeisen

  • Niet alle systeemeisen zijn gelijksoortig.
  • Soorten systeemeisen:
    • Functionele eisen:
    • Niet-functionele eisen.
  • Functionele eisen:
    • Mogelijkheden en eigenschappen van het beoogde systeem.
    • Wat moet het systeem gaan doen.
  • Niet-functionele eisen:
    • Bruikbaarheid: menselijke factoren, hulp, documentatie.
    • Betrouwbaarheid: faalfrequentie, herstelbaarheid, voorspelbaarheid.
    • Performance: response tijden, capaciteit, nauwkeurigheid, beschikbaarheid, beroep op resources.
    • Ondersteunbaarheid: aanpasbaarheid, onderhoudbaarheid, internationaliseerbaarheid, instelbaarheid.
    • Grenzen voor implementatie: grenzen van resources, talen en gereedschappen, hardware …
    • Interfaces: beperkingen oplegd door koppeling aan externe systemen.
    • Operations: eisen vanuit operationeel systeembeheer.
    • Packaging.
    • Juridische zaken: licenties etc.
  • Functionele eisen worden uitgewerkt in use-cases.
  • Andere eisen in een overzicht van aanvullende specificaties.
  • Visie-document geeft overzicht van functionele eisen.
  • Termenlijst verheldert de gebruikte woorden.

 

 

6 Use-Case-Model: noteren van systeemeisen in hun context

  • Use-Case-Model is de collectie van alle Use-Cases.
  • Use-Case-Model is het model van de functionaliteit en de omgeving van het systeem.
  • Use-Cases zijn verhaaltjes die beschrijven hoe een systeem wordt gebruikt om zekere doelstellingen te bereiken.
  • Een Actor is iets/iemand met zeker gedrag zoals een persoon, een computer, een organisatie.
  • Een scenario is een specifieke serie acties en interacties tussen een Actor en het betrokken systeem. Ook genoemd een instantie van een Use-Case.
  • Eén Use-Case is een collectie van gerelateerde succesvolle en mislukkende scenario's.
  • Use-Cases zijn teksten, geen diagrammen. Use-Case-modelleren gaat om het maken van beschrijvingen. Het gaat niet om het tekenen van diagrammen.
  • Use-Cases beschouwen gewoonlijk het systeem als black box.
  • Afhankelijk van de behoefte worden Use-Cases beschreven op verschillend niveau:
    • Kort: beknopte samenvatting van het succesvolle hoofdscenario.
    • Informeel: Meerdere paragrafen met diverse scenario’s voor één Use-Case.
    • Volledig uitgewerkt: alle stappen en variaties in detail met ondersteunde secties zoals precondities en garanties bij succes.
  • Template van volledig uitgewerkte Use-Case omvat:
    • Primaire actor
    • Belanghebbenden en hun belang.
    • Precondities.
    • Garanties bij succes (Postcondities).
    • Hoofdscenario bij succesvolle afhandeling.
    • Uitbreidingen en alternatieven
    • Speciale eisen
    • Mogelijke variaties in technologie en gegevens.
    • Frequentie van voorkomen van deze Use-Case.
    • Open punten
  • Precondities stellen vast aan welke eisen voldaan is voordat een scenario wordt gestart van deze Use-case.
  • Postcondties stellen vast aan welke eisen is voldaan na ieder scenario (succes of anders).
  • Een EBP = elementair business proces = een taak verricht door één persoon op één plaats en op één moment met een meetbaar zakelijk effect dat gegevens achterlaat in een consistente toestand.
  • EBP geen primitieve stap, maar 5 tot 10 stappen die één sessie of één transactie omvatten in een tijdsbestek van enkele minuten tot een uur.
  • EBP’s vormen het uitgangspunt voor Use-Cases.
  • Een Use-Case op het niveau van een EBP correspondeert met een doelstelling (of een behoefte) van één actor.
  • Procedure voor definiëren van Use-Cases:
    • Vind de doelstellingen van de gebruikers.
    • Definieer een Use-Case voor iedere doelstelling.
  • Doelstellingen en Use-Cases kunnen samenstellingen zijn van subdoelen en sub-Use-Cases.
  • Vinden van primaire actors, doelen en Use-Cases:
    • Stel de grens van het systeem vast.
    • Wijs de primaire actors aan: diegenen wier doelstellingen worden vervuld door het systeem. NB: primaire actors hebben zelf voordeel van het systeem. Actors die diensten aan het systeem leveren noemen we ondersteunende actors.
    • Inventariseer de doelstellingen van iedere actor.
    • Beschrijf Use-Cases die deze doelen vervullen.
  • Use-Cases worden nooit geheel perfect. Stop op tijd.
  • Use-Cases gaan vooraf aan een eventueel user interface. Concentreer op doelstellingen. Wat moet er bereikt worden, niet hoe!
  • Actors zijn rollen, niet direct individuele personen. Pas op voor koppelen van rollen in één persoon die de deur openzetten naar fraude.
  • Soorten Actors:
    • Primaire actor: krijgt zijn doelstellingen vervuld.
    • Ondersteunende actor: voorziet in een dienst aan het systeem, bijvoorbeeld informatie.
    • AchtergrondsActor: derde partij die hooguit belang heeft bij het systeem.
  • Bij Use-Cases gaat het om de teksten. Diagrammen zijn ondergeschikt, maar kunnen het overzicht over het geheel verbeteren.
  • Use-cases zijn niet object georiënteerd.

 

 

7 Andere systeemeisen

  • De aanvullende specificatie betreft documentatie, packaging, ondersteuning, licenties enz …
  • Begrippenlijst (glossary) geeft een overzicht van de gebruikte termen en definities.
  • Het Visie-document geeft een beknopte samenvatting van de redenen waarvoor het project wordt voorgesteld, wat de problemen zijn, wie de belanghebbenden zijn, wat hun behoeften zijn, en hoe de voorgestelde oplossing er uitziet.

 

  • Aanvullende specificatie kan bevatten:
    • Eisen m.b.t. functionaliteit, bruikbaarheid, betrouwbaarheid, performance, ondersteuning … (FURPS+ requirements [Larman])
    • Rapporten.
    • Hardware en software beperkingen.
    • Beperkingen bij de ontwikkeling (talen, tools).
    • Andere beperkingen voor ontwerp en implementatie.
    • Punten voor internationalisatie: talen, eenheden.
    • Documentatie en help voorzieningen.
    • Licenties en andere juridische zaken.
    • Packaging: vorm van uitlevering.
    • Standaarden: technisch, veiligheid, kwaliteit.
    • Fysieke omgeving: bijv. hitte. trillingen.
    • Operationele zaken: wat te doen met fouten, wanneer back-up’s.
    • Domein regels of business regels.
    • Informatie over het domein.
  • Het Visie-document van het systeem kan het volgende bevatten:
    • Samenvatting overall probleem.
    • Kerndoelen en kernproblemen van de belanghebbenden.
    • Wat zijn onderliggende problemen en doelstellingen?
    • De neuzen van alle betrokkenen moeten één kant op staan. Gebruik hierbij groepscommunicatie technieken.
  • Volgorde:
    • Start met een eerste ontwerp van het Visie-document.
    • Vind doelstellingen van gebruikers en bijbehorende Use-Cases.
    • Werk de kern-Use-Cases uit en start met de aanvullende specificaties.
    • Verfijn het Visie-document.
  • Start vroeg met de Begrippenlijst. Het gaat er niet om alle begrippen op te nemen, maar wel alle minder duidelijke termen waarover discussie kan ontstaan.
  • Let speciaal op de eenheid waarin waarden worden vastgelegd en eventuele variaties hierin. Adagium onder fysici: een getal zonder eenheid is waardeloos.
  • Mogelijke attributen van termen in de Begrippenlijst zijn:
    • De betrokken term.
    • Synoniemen van de term.
    • Beschrijving van het concept.
    • Format (type, lengte, eenheid).
    • Relatie met andere elementen.
    • Waardenbereik.
    • Geldigheidsregels.
  • Begrippenlijst legt ook samengestelde begrippen uit.
  • Begrippenlijst is meer dan een datadictionary. Bruikbaarheid is ruimer.
  • Betrouwbare specificaties: contradictio in terminis.
  • Specificaties in Inceptiefase blijven nog onaf. Hebben voorlopige status. Worden in latere fasen verfijnd.

 

 

8 Van Inceptie naar Elaboratie

  • Elaboratie is de eerste serie iteraties waar:
    • De meeste eisen worden vastgelegd.
    • De belangrijkste risico’s worden verzwakt.
    • Elementen van de kern-architectuur worden geïmplementeerd en hun bruikbaarheid wordt aangetoond.
  • Wat bereikten we in de inceptiefase? (Dit is een checklist!!)
    • Meeste Actors, Doelen en Use-Cases nu bekend?
    • 10-20% van de use-cases gedetailleerd uitgewerkt. (In verhaalvorm!!)
    • We weten nu welke eisen de grootste risico’s geven of het grootste belang hebben.
    • Initiële versies van het Visie-document en de Aanvullende Specificatie nu gereed. Er is een begrippenlijst aangelegd.
    • Risicolijstje beschikbaar / Deadlines.
    • Er zijn technische proof-of-concept testen gedaan en andere onderzoekingen om de technische haalbaarheid te onderzoeken en zo mogelijk te garanderen.
    • User-interface oriented prototypes gemaakt om functionele eisen te verhelderen.
    • Aanbevelingen welke bestaande componenten te bouwen, of te kopen, of te hergebruiken.
    • Er ligt een concept voor de globale architectuur.
    • Plannen voor de eerste iteratie.
    • Lijst van mogelijke tools.
  • Elaboratie in één zin: bouw de kernarchitectuur, los de elementen op met hoge risico’s, beschrijf de meeste systeemeisen, maak schattingen voor voor het gehele traject en de noodzakelijke hulpbronnen.
  • Practische suggesties:
    • Korte timeboxed risico-driven iteraties.
    • Begin vroeg met programmeren.
    • In kleine stappen ontwerpen, implementeren en testen van de kern en de riskante delen van de architectuur.
    • Test vroeg, dikwijls en op realistische wijze.
    • Maak aanpassingen op basis van de resultaten van tests, reacties van gebruikers en reacties van ontwikkelaars.
    • Beschrijf de meeste Use-cases in detail, door een reeks workshops, minstens eenmaal per iteratie.
  • De eerste iteraties bouwen en onderzoeken de bruikbaarheid van de kernarchitectuur. Zie verder [Larman] 8.6

 

 

 

9 Use-Case-model: System Sequence Diagrams opstellen

Een System Sequence Diagram toont voor één scenario de interactie tussen de Actors en het Systeem. Hierbij geldt:

  • Scenario is onderdeel van één Use-Case.
  • Meestal slechts één Actor.
  • Systeem wordt gezien als Black-box.
  • Het gaat er om een overzicht te maken van de gebeurtenissen en hun volgorde.
  • Een System Sequence Diagram moet gemaakt worden voor het hoofdscenario / successcenario van iedere use-case en voor veelvoorkomende en ingewikkelde scenario’s.
  • Alle acties die de systeemgrens overschrijden dienen zo in kaart te worden gebracht.
  • Dit diagram is tevens een check op de Use-Case beschrijvingen. Kan aanleiding zijn deze aan te passen.
  • De actor kan ook een andere computer, ander systeem zijn. Je beschrijft hier dan het protocol voor de interacties.
  • Beschrijf acties in een actieve vorm los van een User-Interface. Beschrijf de intentie van de actie.
  • Hier User-Interfaces gebruiken is te vroeg. Die horen bij het design. Het gaat hier om het probleem. Een user-interface is een mogelijke oplossing.

 

 

10 Domeinmodel: het vinden van de objectklassen

  • Domeinmodel gaat over objecten uit de buitenwereld, de omgeving van het beoogde systeem. We zitten hier in de analysefase en onderzoeken het probleem. De oplossingen komen later pas aan de orde in de designfase.
  • Het Domeinmodel is het belangrijkste resultaat van de analysefase. Het is een visuele representatie van conceptuele klassen van domeinobjecten uit echte wereld.
  • Domeinmodel bestaat uit een klassendiagram:
    • Met associaties.
    • Met multipliciteiten bij de associaties.
    • Met attributen bij de klassen.
    • Zonder operaties bij klassen.
  • NB: bij operaties in de relatie tussen twee klassen bestaat gewoonlijk de mogelijkheid om de operatie bij de een of bij de ander te plaatsen: de een kan geven of de ander kan vragen. Reden om dit soort besluiten uit te stellen.
  • Domeinmodel gaat niet over software, maar over dingen uit de buitenwereld dus:
    • Bevat geen windows of andere GUI-componenten.
    • Geen verantwoordelijkheden of methoden.
    • Geen sleutelattributen. Sleutels horen bij de oplossingen om een object terug te kunnen vinden in een database. Dus sleutels komen pas aan de orde in de Designfase.

 

  • Conceptuele klassen kan je vanuit verschilende invalshoeken beschouwen:
    • Symbool: de naam en plaatjes als representatie van de klasse.
    • Intension: de volledige definitie van de klasse.
    • Extension: een collectie van voorbeelden van objecten uit deze klasse.
  • Een paar kanttekeningen bij conceptuele klassen:
    • Het is beter om een domeinmodel met veel fijnkorrelige klassen te hebben, dan om er weg te laten.
    • Een domeinmodel is niet beter als er minder conceptuele klassen zijn, het is eerder omgekeerd.
    • Een klasse vergeten is gewoon. Je kan het model later altijd nog aanvullen.
    • Laat een klasse nog niet weg omdat er (nog) geen behoefte bestaat er informatie over te bewaren.
    • Een klasse zonder attributen kan ook bruikbaar zijn.
    • Een klasse die alleen gedrag representeert kan ook bruikbaar zijn.
  • Technieken om klassen te vinden:
    • Gebruik een lijstje van soorten conceptuele klassen.
      • Tastbare objecten.
      • Specificaties en beschrijvingen van dingen.
      • Locaties.
      • Transacties.
      • Transactie regels.
      • Rollen van mensen.
      • Containers van andere dingen.
      • Dingen in een container.
      • Andere systemen buiten het systeem dat we bestuderen.
      • Abstracte begrippen.
      • Organisaties, organisatie-onderdelen.
      • Gebeurtenissen.
      • Processen.
      • (Beleids-)Regels.
      • Catalogi.
      • Documenten / registraties betreffende geld, werk, contracten …
      • Financiële instrumenten en diensten.
      • Handleidingen, boeken, rapporten, …
    • Onderzoek alle documenten uit de Inceptionfase op zelfstandige naamwoorden. Dus ook alle beschikbare Use-Case beschrijvingen, het Visie-document en de Begrippenlijst. Schoon de lijst van zelfstandige naamwoorden op met de regels:
      • Vervang synoniemen door één term.
      • Verwijder woorden die elementaire data-elementen voorstellen, maar laat data-elementen die enige structuur of gedrag vertonen beslist staan.
      • Bij twijfel of een woord een data-element is dan wel een object voorstelt, het woord als conceptuele klasse handhaven!
    • Resultaten van de woordenlijstbenadering vergelijken met de bovenvermelde standaardlijst.

 

 

  • Nog een paar aanwijzingen:
    • Maak een domeinmodel zoals cartograaf dat doet:
      • Gebruik de namen uit het terrein.
      • Laat irrelevante details weg.
      • Voeg niets toe dat er niet is.
    • Als we bij een conceptuele klasse niet denken aan een getal of een tekst, dan is het waarschijnlijk een klasse en geen attribuut.
    • Een domeinmodel is niet absoluut goed of absoluut fout. Het moet bruikbaar zijn.
  • Beschrijvende klassen dienen soms toegevoegd te worden om de gemeen-schappelijke attributen van een groep objecten op te slaan. Dit is noodzakelijk wanneer:
    • Er behoefte bestaat aan de beschrijving van een object onafhankelijk van het bestaan van zo’n object.
    • Vandaar de term Beschrijvende klasse.

 

 

11 Domeinmodel: Associaties toevoegen

  • Associaties zijn nuttig als ze helpen om aan de informatiebehoefte te voldoen.
  • Een associatie is een relatie tussen twee typen / objectklassen.
  • Lijst van gebruikelijke associaties tussen objecten A en B:
    • A is deel van B (++)
    • B bevat A (++)
    • A is beschrijving van B
    • A is bekend bij B (++)
    • A is lid van B
    • A gebruikt B
    • A communiceert met B
    • A grenst aan B
  • Richtlijnen:
    • Concentreer op associaties waarvan de kennis over de verbinding voor langere tijd bewaard moet blijven.
    • Klassen zijn belangrijker dan associaties.
    • Vermijd redundante en (transitief) afleidbare associaties.
    • Wantrouw lussen.
    • Te veel associaties leidt tot verwarring. Alleen "need-to-know" associaties opnemen.
    • Een klasse kan een asscociatie met zichzelf hebben. Bijvoorbeeld: een klasse van personen waartussen familierelaties bestaan.
    • Tussen twee klassen kan meer dan één associatie bestaan.
  • Een associatie verbindt twee objectklassen. Er hoort een naam voor de relatie bij en multipliciteiten voor beide zijden van de relatie.
  • Bij domeinmodellering is een associatie een aanduiding dat een relatie betekenis heeft in de werkelijke wereld. Het verplicht niet tot implementatie later.

12 Domeinmodel: Attributen toevoegen

  • Een attribuut is een waarde behorend bij een object.
  • Verwar geen attributen behorend bij een collectie (klasse van?) objecten met attributen behorend bij individuele objecten. Misschien hebt u een afzonderlijk containerobject nodig om collectie en objecten goed te scheiden.
  • In het domeinmodel nemen we alleen attributen op die volgens Use-Cases onthouden zouden moeten worden.
  • Attributen horen elementaire dingen te zijn. Zodra daar twijfel over bestaat, voeg dan een klasse en een bevat-relatie toe.
  • Klassen worden gekoppeld met een associatie, niet met een sleutel-attribuut. Sleutel-attributen komen pas naar voren in de Designfase.
  • Bij numerieke grootheden hoort altijd een Dimensie en een Eenheid: Vb. X is een afstand in km. Y een bedrag in foppen.

 

13 Use-Case-model: Detailleren met contracten voor operaties.

  • Contracten beschrijven systeemgedrag in detail in termen van toestands-veranderingen van de objecten in het domeinmodel nadat de operatie door het systeem is uitgevoerd. Contracten beschrijven het resultaat van een operatie.
  • Contracten betreffen nooit de acties van een Actor.
  • Contracten hebben alleen nut in complexe situaties. Meestal is de Use-Case beschrijving voldoende. Contracten zijn een uitbreiding hierop.
  • Een contract betreft één operatie van het systeem, dus één onderdeel van een scenario.
  • Contracten bestaan uit:
    • Operatie: naam en argumenten.
    • Kruisverwijzing: naar alle plaatsen in scenario’s waar deze operatie voorkomt.
    • Precondities: Veronderstellingen over de toestand van het systeem waaraan voldaan is voorafgaand aan de operatie en waarop blind kan worden vertrouwd.
    • Postcondities: De toestand van de objecten in het systeem na de operatie.
  • Postcondities beschrijven niet de acties die worden verricht of hoe ze worden verricht, maar vertellen in welke toestand het systeem zich bevindt naar afloop van de operatie.
  • Belangrijkste typen van veranderingen die moeten worden beschreven:
    • Creatie en verwijdering van instanties van objecten.
    • Verandering van waarden van attributen.
    • Links tussen objecten die worden gecreëerd of vernietigd.
  • Postcondities gebruiken het domeinmodel en kunnen leiden tot modificatie van het domeinmodel. Zie het als een wederzijdse check.
  • Tijdens het werken aan de specificaties kunnen postcondities niet echt volledig zijn. Zie het als een voorlopige gok. De details komen later nog wel eens boven water.
  • Wantrouw operaties met ingewikkelde toestandsveranderingen.
  • Vergeet het maken van nieuwe objecten en het creëren van links ernaar niet.

14 Van systeemeisen naar ontwerp

  • Het voorafgaande moet in een schoolproject plaatsvinden in enkele dagen. Het zou af moeten zijn aan het einde van de eerste week.
  • De verschillende stukken moeten gelijktijdig ontwikkeld worden en niet na elkaar. De modellen moeten onderling getoetst worden op inconsistenties. Die toetsing stuurt het analyseproces.
  • Schema’s die te onoverzichtelijk worden dienen vertaald te worden in tabellen. Bedenk: een graph bestaande uit lijnen en vakjes kan ook worden vertaald in een opsomming. Wiskunstig is het een eindige relatie op een verzameling (object-klassen). Gewoon een tabelletje dus.
  • Details passen niet gauw in schema’s. Reserveer één A4’tje per klasse.
  • Werk op kladblokken in de loop van het proces. Gebruik een prullenbak.
  • Lever schema’s handgeschreven op, netjes getekend met de hand op fatsoenlijk papier.
  • Verspil geen tijd met dagenlang achter de computer schemaatjes te tekenen die even later de prullenbak in gaan.
  • Er zijn nog zoveel leuke manieren om je tijd te verknoeien J
  • Tijdens object design ontwikkelen we een oplossing voor het probleem uit het domeinmodel. We creëren hierbij:
    • Interactie-diagrammen. Deze laten zien hoe objecten samenwerken.
    • Klassendiagrammen geven een samenvatting van alle gebruikte software klassen in het designmodel.
  • De interactiediagrammen zijn het belangrijkste en kosten de meeste moeite.
  • Er wordt gewerkt hierbij op basis van twee vormen van aanpak;
    • Principes voor het toekennen van verantwoordelijkheden. De vraag is vooral welk object doet wat. (Of is er verantwoordelijk voor.)
    • Gebruik van vaste ontwerpprincipes. (Patterns)

 

 

15 Diagrammen voor interactie van objecten

  • Een systeem bestaat uit samenwerkende objecten.
  • We moeten voor alle operaties op het systeem nagaan waar de vraag van de actor binnenkomt en hoe deze wordt vertaald naar operaties te verrichten door andere objecten.
  • Kernideeën:
    • Specialisatie door objecten. Ieder object zijn eigen kunstje.
    • Isolatie / defensief gedrag van objecten.
    • Uitbesteden van werk aan andere objecten.
    • Rationalisatie in taken.
  • De wijze waarop objecten samenwerken wordt vastgelegd met Collaboration Diagrams.
  • Vergeet Sequence diagrams, maak gebruik Collaboration diagrams. Ze werken prettiger en gaan efficienter om met de beperkte ruimte van het papier. Ze hebben overigens de zelfde betekenis.
  • Het uiterlijk van Collaboration diagrams staat beschreven in [Larman] 15.6. Let op alle subtiele details. Je kan je overigens afvragen of dit type diagrammen niet beter gevat kan worden in een vorm van pseudocode. Maar ja, dat is niet visueel, dus uit de mode.
  • Sequence diagrammen slaan we over. [Larman] houdt er niet van.

 

 

16 GRASP Patterns = Standaardregels voor ontwerpen: De basis

  • Objecten krijgen verantwoordelijkheden toegewezen. GRASP staat voor General Responsibility Assignment Patterns. Patterns zijn hierbij dwingende regels die bij het ontwerp gevolgd moeten worden. Het zijn geen vrijblijvende suggesties of opties.
  • Twee typen verantwoordelijkheden:
    • Doen:
      • Zelf doen, een object creëren, een berekening doen.
      • Werk uitbesteden aan andere objecten.
      • Werk van andere objecten besturen en coördineren.
    • Weten:
      • Eigen binnen object opgesloten data-elementen kennen.
      • Geassocieerde objecten kennen.
      • Dingen kennen die kunnen worden afgeleid of berekend.
  • Klassen krijgen verantwoordelijkheden toegekend tijdens het ontwerp van objecten.
  • Verantwoordelijkheden worden vertaald naar objectklassen en derzelver methoden.
  • Een methode is geen verantwoordelijkheid, maar verantwoordelijkheden worden geïmplementeerd om verantwoordelijkheden te vervallen.
  • Toekennen van verantwoordelijkheden vindt gewoonlijk plaats tijdens het maken van interactiediagrammen. Dus de interactiediagrammen tonen de keuzen die zijn gemaakt bij het toekennen van verantwoordelijkheden aan objecten.
  • Patterns worden beschreven met de volgende onderdelen:
    • Naam: Een naam voor het patroon.
    • Oplossing: Een beschrijving van de standaardaanpak volgens dit patroon.
    • Probleem: Een beschrijving van het probleem wat er door wordt vermeden of opgelost.
  • Nieuwe patterns bestaan niet. Een pattern presenteert een beproefde standaardoplossing voor een standaardprobleem. Een pattern representeert onze collectieve ervaring na 50 jaar werken met computers.
  • Bij voorkeur voldoe je aan alle patterns tegelijk. Dat dit lukt is niet waarschijnlijk. Patterns bieden een vorm van kritiek op analyse en ontwerp. Ieder knelpunt wijst een zwak punt in analyse en ontwerp aan.
  • De eerste patterns die worden geïntroduceerd zijn extreem belangrijk. Ze vormen de basis van het denken achter objectgeörienteerd programmeren. Zondig hier niet tegen, of zoek een slimme omweg. Het zijn:

 

 

    • Informatie expert pattern.
      • De regel: het object dat de informatie heeft om iets te kunnen doen, die moet het ook doen (of er althans een methode voor hebben die anderen kunnen aanroepen). Objecten werken vooral op hun eigen informatie.
      • Het is dus fout als je informatie uit een object haalt om daar elders dingen mee te gaan doen. Laat het object het zelf doen.
      • Het gaat er hier om de juiste plaats aan te wijzen voor taken. Het beantwoordt de vraag waar zal ik deze taak/verantwoordelijkheid plaatsen. Het antwoord: het object dat de benodigde informatie heeft.
      • Misschien is het trouwens nodig om informatie bij een ander object te plaatsen. De regel beïnvloedt de indeling in klassen.
    • Creatorpattern.
      • De regel: klasse B heeft de taak om instanties van klasse A te creëren als aan één van de volgende regels is voldaan:
        • B bevat A objecten.
        • B houdt alle instanties bij van A’s.
        • B gebruikt A’s intensief.
        • B heeft de initialiserende gegevens noodzakelijk bij het creëren van A’s.
      • Als er meer dan één mogelijke B-candidaat is, dan een klasse kiezen die de A’s bevat.
      • Niet ieder object mag zomaar willekeurig andere objecten aanmaken. Aanmaken van objecten, administratie van objecten en vernietigen van objecten dienen per type op één centrale plek plaats te vinden. Zondigen hiertegen wordt bestraft met onoplosbare geheugenlekken. Zie ook "Grote samenhang" hierna.
    • Grote samenhang pattern.
      • De regel: verantwoordelijkheden zo verdelen dat ieder object een samenhangende groep taken heeft.
      • We praten hier over functionele samenhang (cohesie). De taken van het object moeten draaien om één zaak. Het gaat erom complexiteit beheersbaar te houden. Een klasse met lage samenhang doet dingen die weinig met elkaar te maken hebben. Slechte samenhang kan het noodzakelijk maken een klasse te splitsen. Klassen met slechte samenhang verrichten te veel taken of vergeten om taken te delegeren.
    • Lage koppelings pattern.
      • De regel: verdeel taken zo dat koppeling met andere klassen laag wordt. Onder koppeling verstaan we de mate waarin een object is verbonden met, kennis nodig heeft van, of afhankelijk is van andere objecten.
      • We wensen lage afhankelijkheid van andere delen van een systeem. Objecten dienen zo onafhankelijk mogelijk te zijn om te verkomen dat wijzigingen in het ene deel van het systeem een waterval van veranderingen in andere delen teweeg brengt. Lage koppeling bevordert hergebruik van objecten.
      • Lage koppeling begint met dichttimmeren t.o.v. de buitenwereld: alle attributen lokaal maken. Geen onbeheerste externe toegang via publieke attributen. Alleen beperkt toegang voor zover nuttig via methoden. Alleen resultaten teruggeven als returnwaarde van een methode. In het ideale geval worden beginwaarden van attributen gegeven bij creatie van een object en veranderen attributen daarna alleen maar als resultaat van een functioneel gerichte activiteit. Geen set-methoden, geen get-methoden. Geen toegang tot alle methoden. Slechts een beperkt aantal methoden publiek maken als onderdeel van een doordacht API dat het object verbindt met de omgeving. (API = application programmers interface.)
    • Bestuurderspattern:
      • De regel: Geef de verantwoordelijkheid voor het ontvangen en afhandelen van een signaal (system event) aan een "event-handler". Hiervoor bestaan twee soorten:
        • Een event handler voor het gehele (sub-)systeem. Hier doorheen passeren dan alle denkbare signalen. Dit noemen we een facadecontroler omdat deze de signalen weer door moet sturen / delegeren aan andere controlers.
        • Een event handler voor het scenario waarbinnen het signaal optreedt. We noemen dit een use-case session controler.
      • Het onderliggende probleem is de vraag wie verantwoordelijk is voor de afhandeling van een input system event. Een input system event is een signaal gegenereerd door een externe actor.
      • Een controler is een niet-userinterface object dat verantwoordelijk is voor het ontvangen en verwerken van deze signalen. De controler is het startpunt voor de activiteiten die volgen op zo’n signaal (bijv. het drukken op een OK-knop.)
      • Een controler doet slechts het hoogst noodzakelijke en hoort het meeste werk te delegeren naar andere objecten. Een controler hoort slechts heel beperkte verantwoordelijkheden te krijgen.
      • Opgeblazen controlers zijn slecht ontworpen controlers die teveel taken op zich hebben genomen en daarmee alle regels van grote samenhang en lage koppeling schenden. Het is zichtbaar als de controler meer doet dan de juiste afhandelingsmethode activeren. Het is niet gewenst dat de controler alles zelf doet. De belangrijkste taak is het signaal opvangen en beslissen wie nu de controle moet krijgen om het af te handelen. Bij voorkeur start de controler een nieuwe thread voor de afhandeling.

 

17 Overgeslagen: alleen voorbeelden.

 

 

18 Ontwerp: Zichtbaarheid

  • Onder zichtbaarheid van object B vanuit object A verstaan we dat A toegang heeft tot een referentie naar B.
  • Zichtbaarheid is nodig om vanuit A een message naar B te kunnen sturen. Hieronder wordt verstaan dat vanuit A een methode in B wordt geactiveerd. (Methode is OO-argot voor een functie.)
  • Er zijn 4 soorten zichtbaarheid voor een referentie naar een object:
    • Zichtbaarheid als attribuut: het A object bevat zelf een referentie naar B.
    • Zichtbaarheid als argument: de actieve methode in A heeft als argument een referentie naar B gekregen.
    • Locale zichtbaarheid: de referentie naar B is een locale variabele in de actieve methode in A.
    • Globale zichtbaarheid: de referentie naar B is op de een of andere manier globaal zichtbaar, bijvoorbeeld via een publiek attribuut van een klasse of een ander object.
  • Zichtbaarheid beÏnvloedt koppeling tussen objecten. Traditioneel wordt globale zichtbaarheid als ongewenst beschouwd. De andere vormen zijn acceptabel. Een attribuut dat naar een ander object wijst hoort niettemin private te zijn.
  • Zichtbaarheid van elementaire variabelen laat zich op gelijksoortige wijze beschrijven. Globale zichtbaarheid is hier strikt ongewenst.

 

 

19 Ontwerp: Klassendiagram in het ontwerp

  • Bij het ontwerp worden klassendiagram en interactiediagrammen parallel ontwikkeld.
  • Een Klassendiagram in het ontwerp gaat niet meer over het domein, maar gaat over softwareklassen en interfaces. Typische onderdelen van dit klassendiagram zijn:
    • Klassen, associaties en attributen.
    • Interfaces met hun operaties en constanten.
    • Methoden.
    • Type-informatie van atrributen e.d.
    • Bevaarbaarheid J (Navigability) en zichtbaarheid.
    • Afhankelijkheden.
  • Een klassendiagram ontwerpen:
    • Allereerst een iteratief proces. Je begint ergens bijvoorbeeld het domeindiagram en voegt computergerichte objecten toe voor userinterfaces en benadering van de database. Daarna laat het model groeien en houdt je model tegen het licht van de Patterns. Je modificeert het model om knelpunten volgens de Patterns te verwijderen en herhaalt e.e.a. Patterns zijn hierbij richtinggevend. Ieder object moet aan zoveel mogelijk patterns voldoen. Dan ben je pas tevreden.
    • Mogelijke operaties:
      • Klassen weggooien die niet bijdragen aan de verwerking die wordt gevraagd.
      • Klassen splitsen die niet voldoende samenhang hebben.
      • Operaties verplaatsen naar de Informatie Experts.
      • Hulpklassen (bijvoorbeeld containers) verzinnen.
      • Adaptorklassen maken om een gemeenschappelijke interface te kunnen presenteren voor onderling verschillende klassen.
      • Klassen splitsen / verdelen over een overervingshierarchie.
      • Klassen samenvoegen.
  • Een klassendiagram van enige omvang kan niet meer op een overzichtelijke wijze alle details bevatten. Gebruik één A4'tje per klasse voor de details. Noteer deze details in uw favoriete OO programmeertaal (Java of C++).
  • Gebruik het klassendiagram om de relaties tussen de klassen in beeld te brengen voor het noodzakelijke overzicht.
  • Werkwijze voor de andere onderdelen van het klassediagram:
  • Methoden worden ontleend aan het interactiediagram. Get- en setmethodes worden gewoonlijk niet opgenomen omdat ze geen functionaliteit van het systeem voorstellen. Ik zou ze trouwens het liefst verbieden. Constructormethoden worden eveneens weggelaten uit het model.
  • Ieder uiteinde van een associatie wordt een rol genoemd. In de klassendiagrammen kan de rol worden versierd met een pijl die de vaarrichting aangeeft. Onder de vaarrichting verstaan we de richting van de zichtbaarheid tussen de objecten. Associaties die in beide richtingen ondersteunen moeten gesplitst worden in twee associaties die tegengestelde richtingen aangeven. Op deze wijze wordt een klassendiagram een gerichte graaf en wordt zichtbaar welke delen nog niet bereikbaar zouden zijn.
  • Bij het ontwerp worden associaties gekozen met de Spartaanse regel dat de noodzaak bestaat dat de het ene object het andere object direct moet kunnen aanwijzen. Een associatie wordt bij implementatie direct vertaald naar een link door een attribuut van het ene object naar het andere object met inachtneming van de navigatierichting.
  • Alle andere links worden weergegeven met gestippelde pijlen en worden afhankelijkheden genoemd.

 

 

20 Implementatiemodel

  • Iteraties duren kort.
  • Iedere iteratie bevat analysecomponenten, designcomponenten en implementatiewerk.
  • Iedere iteratie levert iets werkends op.
  • Gebruik voor het ontwerpen van diagrammen eenvoudige hulpmiddelen die geen lange inwerktijdnodig hebben: Een schoolbord, een bordpen, een borstel en een digitale camera om diagram vast te leggen zijn genoeg. Als je een CASE-tool weet waarmee het sneller gaat: OK ga je gang.
  • Documenteer details die niet meer in een plaatje passen in een tekstfile. Gebruik voor de tekst de programmeertaal waarin je implementeert verluchtigd met commentaar om e.e.a. te verhelderen. Je maakt in één moeite door een begin met coderen.
  • Een ontwerp is altijd onvolledig vergeleken met de latere implementatie. Houd er rekening mee dat bij het coderen het ontwerp verder wordt uitgewerkt en nog verandert. Probeer niet alle code terug te vertalen naar ontwerpdetails. Het ontwerp moet vooral overzicht blijven geven over het geheel. Het ontwerp moet wel in overeenstemming blijven met de code. Maar er blijft altijd een verschil in het niveau van detail.
  • Links / gerichte associaties worden referentie-attributen van het ene object naar het andere. NB: de links worden dus attributen van het object! Gebruik de rolnaam uit het objectdiagram als attribuutnaam.
  • Iedere message in het interactiediagram wordt vertaald naar een message in de code.
  • Bij een een-op-veel associatie hoort een containerklasse die referenties bevat naar alle betrokken objecten. In zo'n klasse hoort een zoekmethode die het gewenste object selecteert. Gebruik geen klassenattributen (static) voor de implementatie hiervan, maar houd zo'n klasse gescheiden van de gerefereerde objecten. Gebruik je Javaconstructies als array's, lists, maps e.d. maak dan minstens van de zoekbewerking een afzonderlijke methode.
  • Excepties in Java zijn in UML asynchrone messages net zoals events van het use-interface.
  • Implementatievolgorde wordt geregeld door de volgorde van de links: een klasse die een link heeft naar een andere klasse wordt als laatste van die twee geïmplementeerd.
  • Testen en bijbehorende drivers dien gemaakt te worden voor de actuele implementatie van een klasse.

 

 

21 Eisen van iteratie 2

  • Aan het einde van de eerste iteratie van het ontwikkelingsproces moet er werkende basisversie beschikbaar komen van het gevraagde systeem voor evaluatie en beta-testing. Deze eerste versie is vanzelfsprekend grondig getest door het ontwikkelteam Ook resterende bugs zijn gedocumenteerd! Het systeem bevat geen ongedocumenteerde features.
  • Gebruik een CASE-tool om de gecreëerde code terug te vertalen naar een klassendiagram.
  • Er wordt nog gestudeerd op de effectiviteit van de GUI.
  • Er wordt nog gestudeerd op de juiste vorm van de database.
  • Nu is het tijd om de eisen voor de volgende iteratie op te gaan stellen. Start met een workshop voor het uitbreiden van de Use-Cases en System Sequence Diagrams.

Deze samenvatting eindigt hierna met het presenteren van nog meer patterns.

 

 

22 GRASP: nog meer patterns voor verantwoordelijkheden

De laatste vier patterns voor het toekennen van verantwoordelijkheden zijn:

  • Polymorfisme pattern:
    • Als een klasse vergelijkbare alternatieven kent, zorg dan voor een (abstracte) superklasse voor deze klassen en definieer bij de superklasse de gemeenschappelijke (abstracte) interface. Laat de afzonderlijke klassen die interface implementeren. Zet er eventueel nog een adapter klasse tussen om te converteren tussen het gewenste interface en het feitelijke interface van de bedoelde subklasse.

Het probleem wat je oplost is de behandeling van type-afhankelijke verschillen. Door polymorfisme te gebruiken hoef je nooit te testen op het type van een object. Het systeem kan zelf aan het type zien welke methoden van welke klasse geactiveerd moeten worden.

  • Zuiver verzinsel pattern:
    • Geef sterk samenhangende verantwoordelijkheden aan een klasse die je voor het gemak er bij bedacht hebt. Doel is het bereiken van grote samenhang, lage koppeling en hergebruik.

Vooral bedoeld om problemen met samenhang en koppeling op te lossen waar andere patronen geen oplossing bieden. Je kan bijvoorbeeld een klasse met te weinig samenhang splitsen in een aantal klassen, evenals een klasse met teveel verschillende koppelingen.

  • Indirectie pattern:
    • Creëer een object om te bemiddelen tussen twee andere klassen bijvoorbeeld om te vertalen van een interface die wordt geboden en een interface die wordt gevraagd.
  • Beschermde variaties pattern:
    • Op punten waar variaties voorzien kunnen worden creëer daar klassen met een stabiele interface als abstracte superklasse voor de toekomstige varianten.

Dit niet overdrijven. Niet alle denkbare variaties zo behandelen, maar alleen de met enige waarschijnlijkheid voorspelbare variaties.

 

 

23 Use-Case realisatie met GoF patterns

  • GoF patterns slaat op de zogenaamde Gang of Four. Hiermee worden de auteurs aangeduid van het boek Design Patterns van de auteurs Gamma, Helm, Johnson en Vlissides. In dit boek werd voor het eerst het ontwerpprobleem benaderd met patterns: standaardproblemen oplossen met beproefde standaardoplossingen. Dit boek is inmiddels een classic geworden dat iedere ontwerper zou behoren te kennen.
  • [Larman] benadert patterns op een andere wijze, namelijk met zijn General Responsibility Assignment Patterns. Hij neemt daarmee een ander standpunt in dan de Gang of Four. In dit hoofdstuk presenteert hij een aantal patterns van de Gang of Four en vergelijkt ze met zijn eigen GRASP-patterns. Hij probeert hier zijn standpunten te verdedigen. Het blijkt dat GRASP-patterns primitiever zijn en meer gaan over algemene ontwerpprincipes, maar minder over beproefde recepten. GRASP-patterns zijn daarmee ook bruikbaar als checks om een ontwerp te toetsen. Maar het nieuwe van dit boek schuilt in het idee dat objecten verantwoordelijkheden hebben. GoF-patterns zijn wat meer sophisticated maar daarmee ook complexer en minder bruikbaar voor checks, maar wel een bron van goede ideeën.
  • De opgenomen GoF-patterns zijn:
    • Adapterpattern
      • Wat te doen met een niet-passend interface voor een object?
      • De oplossing: Zet er een ander object tussen dat de omzetting doet tussen de gewenste interface en de feitelijke interface. Vooral van belang als er één of meer externe componenten in een systeem worden opgenomen waarvan de interface door anderen is vastgesteld.
    • Factorypattern
      • Om de samenhang van andere klassen te verbeteren is het dikwijls gewenst om de aanmaak van een bepaald type object bij één gespecialiseerde klasse of zelfs één object onder te brengen. De speciale klasse noemen we een factory. Een factory is gewoonlijk een singleton.
    • Singletonpattern
      • Als er van een klasse maar precies één objectinstantie mag zijn noemen we de klasse / object een singleton. De oplossing is een klassenmethode die als resultaat de referentie naar het object teruggeeft als het object bestaat en eventueel het object ook nog aanmaakt. Door de static klassenmethode creëer je één uniform toegangpad. De referentie naar het ene object wordt een klassenattribuut.
    • Strategypattern
      • Hoe ga je om met wisselende algoritmen voor hetzelfde probleem? Maak voor het probleem een abstracte superklasse met een abstracte interface en laat de erfgenamen ieder een algoritme implementeren voor deze interface.
    • Compositepattern
      • Hoe behandel je samengestelde objecten en enkelvoudige objecten op de zelfde wijze? Definieer de klassen voor deze objecten zo dat ze de zelfde interface implementeren. Dwing e.e.a. af met een abstracte superklasse.
    • Facadepattern
      • We wensen een standaardinterface voor een aantal verschillende implementaties met verschillende interfaces van een subsysteem (bijv. meerdere verschillende dbms-en), die eventueel weer kunnen veranderen.

Oplossing: een facade-object dat de systemen verbergt en de gewenste interface implementeert.

    • Observerpattern / Publish-Subscribepattern / Delegation Event Model
      • Verschillende soorten abonnees (objecten) kunnen geïnteresseerd zijn in toestandsveranderingen van een uitgever (ook een object). Het idee is dan dat de uitgever de abonnees een signaal stuurt in plaats van het opvragen van informatie door de abonnees bij de uitgever. De taak van de uitgever is om abonnees te registeren en om ze via het "listnerinterface" een signaal te sturen als de betrokken toestandsverandering optreedt. Let er wel op dat de achtergrond hier is dat uitgever en abonnees in verschillende threads parallel functioneren.

CHECKLIST voor beoordelaars van de software

  • Bekijk de klassen.
  • Iedere klasse heeft één taak. Die moet beschreven zijn. (Cohesie!)
  • Iedere klasse definieert een API .
  • Methode die behoren bij de API worden public gedefinieerd.
  • Bij iedere methode van de API hoort een beschrijving van zijn werking en aanroep Hierbij moet het Javadoc systeem gevolgd worden!
  • Andere methoden zijn intern en dus private en kunnen niet extern aangeroepen worden. Beschrijving in locaal commentaar is voldoende. (Ontkoppeling!)
  • Voor zover er beperkingen zijn in de volgorde van gebruik van de methoden van de API, dient er een Statediagram te zijn om die volgorde vast te leggen.
  • Liefst geen klassenmethoden en klassenattributen, herkenbaar aan de term static, tenzij er een goed verhaal bij geleverd wordt om het te verklaren. Als je iets wilt met een collectie gelijksoortige objecten, dan moet er een afzonderlijke containerklasse zijn. (Ontkoppeling - spreiding verantwoordelijkheden!)
  • Beslist geen set-methoden voor attributen van een object, beperkt get-methoden om waarden aan de buitenwereld te kunnen geven. (Ontkoppeling!)
  • Slechts heel beperkt object attributen, allemaal local en dus afgeschermd voor de boze buitenwereld. Niet allerlei tellertjes en hulpvariabelen als objectattributen opnemen. Alleen de zaken die tussen opeenvolgende messages uit de buitenwereld bewaard moeten blijven zijn goede objectattributen. Het is een speciale uitverkiezing voor een variabele om objectattribuut te mogen zijn.
  • Objecten met veel attributen zijn verdacht.
  • Attributen dragen begrijpelijke namen evenals de methoden uit de API.
  • Binnen methoden de declaratie van variabelen strikt gescheiden houden van de uitvoerbare statements. Ik zie studenten die een toekenning niet kunnen onderscheiden van een declaratie met initialisering omdat in allerlei voorbeelden in het @#$%^&-boek voor iedere toekenning een type staat.
  • Methoden met veel locale variabelen zijn verdacht.
  • Methoden met veel argumenten zijn verdacht.
  • Langdradige onoverzichtelijke methoden zijn verdacht.
  • Binnen objecten kan je gewoon klassiek gestructureerd programmeren en het werk verdelen over een groot aantal kleine locale methoden. Methoden horen daarom klein en overzichtelijk te zijn. Methoden die te lang zijn omdat ze teveel willen doen moeten daarom opgesplitst worden. (Gestructureerd programmeren is niet dood, maar leeft voort onder het OO-oppervlak!)
  • Code die herkenbaar is gekopieerd met copy/paste afschieten. Moet omgezet naar locale submethoden evt. met argumenten. Toont domheid programmeur aan.
  • Laat student een eigen stuk code aanwijzen en vraag hem om het uit te leggen J na twee weken JJ

 

Zelf iets bouwen dat er leuk uitziet en aardig werkt. Dat is de sport bij een practisch vak als AP-003. Vergeet niet op tijd hulp te halen als je klem loopt. Wie er geen aardigheid in heeft en het als marteling ervaart kan beter een ander beroep kiezen.

Jan Schramp, 19 juli 2003.