Relevantie
Eisen die robuustheid uitdrukken tegen functionele veranderingen en uitbreidingen worden niet-functioneel genoemd, terwijl de behoefte aan functionaliteit zelf wordt uitgedrukt in functionele eisen. Functionaliteit in software werkt compositioneel; dat wil zeggen dat het wordt gecreëerd door het combineren van componenten die functionaliteit gedeeltelijk realiseren. Deze gedeeltelijke functionaliteit die een component biedt, wordt niet beïnvloed door het maken van dergelijke composities. Men kan dus functionele zorgen scheiden. Dergelijke compositionaliteit werkt echter niet voor niet-functionele aspecten zoals performantie en de ‘-ilities’ (schaalbaarheid, herbruikbaarheid, uitbreidbaarheid enz.). Als we bijvoorbeeld twee onafhankelijke componenten hebben die een deadline halen als ze afzonderlijk worden ingezet, is het verre van zeker dat ze dezelfde deadline halen als ze samen worden ingezet. Het voldoen aan een deadline kan niet worden gelokaliseerd (bijvoorbeeld in een enkele klasse) en vereist de toepassing van heel andere technieken dan het realiseren van functionele eigenschappen. Een eenvoudige verdeel-en-heers aanpak is niet effectief. Veel auteurs definiëren systeemeigenschappen die niet te lokaliseren zijn als architectuur.
De 4-daagse cursus aan het High Tech Institute introduceert en verkent de belangrijkste ideeën achter objectgeoriënteerde ontwikkeling en bespreekt hoe deze techniek kan worden gebruikt om aan de architecturale of niet-functionele eisen te voldoen. De modelleertaal UML wordt gebruikt als belangrijkste hulpmiddel.
Deze cursus is natuurlijk verdeeld in twee in elkaar grijpende delen: objectgeoriënteerde analyse en objectgeoriënteerd ontwerp. Tijdens de analyse wordt een objectgeoriënteerde gedragsspecificatie van het systeem gemaakt. Tijdens het ontwerpproces wordt deze specificatie aangevuld met de gewenste niet-functionele systeemeigenschappen. Analyse legt dus de functionele eisen vast en produceert een (mogelijk uitvoerbare) functionele specificatie, terwijl de ontwerpstap de niet-functionele eisen vastlegt en realiseert.
Objectgeoriënteerde analyse
Objectgeoriënteerd programmeren is een vorm van modulair programmeren met de klasse als basisbouwsteen. Klassen kunnen worden verkregen uit de objecttypen die we in het probleemdomein aantreffen: de objecten in de machine die moet worden bestuurd of in het bedrijfsproces dat moet worden ondersteund. Objectoriëntatie staat in contrast met (oudere) procedurele benaderingen. In het algemeen is het makkelijker voor mensen om in termen van objecten te denken dan om procedureel te denken.
Een klasse is een softwaremodule die toegang biedt tot zijn gegevens, ook wel attributen genoemd, via operaties. Dit bevordert het idee van “gegevens op één plaats houden” en informatie verbergen, wat kan helpen om software minder gevoelig te maken voor veranderingen in de representatie van gegevens en uitbreidingen. Wanneer een objectgeoriënteerde aanpak goed wordt toegepast, leidt dit tot een betere lokalisatie van softwareveranderingen in vergelijking met de traditionele procedurele manier van werken.
Het analyseproces begint met de definitie van zogenaamde use cases, scenario-achtige beschrijvingen van gebruiker-systeem-interacties. Daarnaast wordt de systeemstructuur vastgelegd als een eenvoudige klassehiërarchie. Vervolgens worden de use cases geanalyseerd en gerealiseerd met behulp van UML sequentiediagrammen. Dit helpt om gedrag toe te wijzen aan de systeemobjecten op zo’n manier dat de interacties zoals gespecificeerd in de use cases ontstaan. Deze gedragstoewijzing resulteert in de ontdekking van operaties op klassen. De laatste stap is het verfijnen van het gedrag van individuele klassen in UML-statusmachinebeschrijvingen, (maximaal) één statusmachine per klasse.
Tijdens de analyse wordt het systeem in ontwikkeling gemodelleerd in plaats van de software in ontwikkeling. Dit is belangrijk omdat het leidt tot het lokaliseren van systeemparameters en bijbehorend gedrag en het helpt om inkapseling te bevorderen. Op deze manier wordt het verbergen van informatie en inkapseling op natuurlijke wijze ingebouwd in het object-georiënteerde model.
Objectgeoriënteerd ontwerp
Een functioneel correct (deel)analysemodel is een goed startpunt voor het ontwerp. Het ontwerpgedeelte van de cursus is gebaseerd op de 4+1 Views van architectuur van P. Krugten: de Logical, Process, Component en Deployment Views. Deze views zijn geïntroduceerd om de geadresseerde niet-functionele aspecten en de gebruikte technieken voor hun realisatie te scheiden.
Een belangrijke architectuurtechniek die in de logische visie wordt gebruikt is modulariteit. Veel cursisten in deze cursus denken dat modulariteit zelf een vereiste is. De cursus pleit ervoor om dit anders te bekijken. Modulariteit is er altijd met het oog op een ander, hoger doel (bijv. hergebruik, uitbreidbaarheid, onderhoudbaarheid). Het veranderen van de softwarestructuur wordt dus gezien als een middel om de gewenste niet-functionele eigenschappen te bereiken. Er zijn twee belangrijke manieren om de softwarestructuur te veranderen: (1) code refactoring en (2) de toepassing van design patterns. Beide technieken kunnen zo worden toegepast dat de functionaliteit behouden blijft.
Tijdens de procesweergave wordt ingegaan op zaken als performance schaalbaarheid, correctheid (afwezigheid van deadlock en race conditions). Er wordt getoond hoe de gedragsbeschrijvingen in de vorm van UML toestandsmachines concurrency (multi-threading) opleveren die natuurlijk is voor het probleem, het systeemgedrag. Threading kan worden gerefactored in de procesweergave, net zoals transformatie kan helpen bij het refactoren van klassen en hun structuur in de logische weergave. Enkele eenvoudige transformaties gebaseerd op thread cohesie argumenten worden besproken en geïllustreerd.
Tot slot worden de components en deployment views heel kort besproken. Deze visies gaan over de manier waarop uitvoerbare softwarebouwstenen worden aangeboden voor implementatie op een uitvoeringsplatform. Typische onderwerpen zijn schaalbaarheid en software evolutie. De focus ligt hier vooral op notaties, maar ook enkele problemen met componentinterfaces worden kort behandeld.
Het cursusmateriaal bevat een flink aantal casestudies die als voorbeelden en oefeningen worden gebruikt. Deze casestudies zijn tot in detail uitgewerkt, van requirements via modellen tot uitvoerbare (Java) implementaties. De laatste stap wordt uitgevoerd als “proof of concept”. Cursisten ontvangen deze casestudies op USB-stick.
Deze cursus is met name bedoeld voor softwareontwikkelaars die de hierboven genoemde problemen herkennen en het gevoel hebben dat ze baat hebben bij een duidelijke en samenhangende behandeling. De duidelijke leerdoelen en de vele oefeningen zullen helpen om de gepresenteerde theorie en technieken te consolideren.
Een natuurlijk vervolg op deze training is “Design patterns en emergent architecture“. Het wordt aanbevolen om eerst deze OOAD cursus te volgen.