Na de analysefase wordt het conceptuele model verder ontwikkeld tot een objectgeoriënteerd model met behulp van objectgeoriënteerd ontwerp (OOD). Bij OOD worden de technologie-onafhankelijke concepten in het analysemodel in kaart gebracht in uit te voeren klassen, worden beperkingen geïdentificeerd en worden interfaces ontworpen, hetgeen resulteert in een model voor het oplossingsdomein. In een notendop, wordt een gedetailleerde beschrijving opgesteld die specificeert hoe het systeem moet worden gebouwd op basis van concrete technologieën
De fasen voor object-georiënteerd ontwerp kunnen worden geïdentificeerd als –
- Definitie van de context van het systeem
- Ontwerpen van systeemarchitectuur
- Identificatie van de objecten in het systeem
- Bouw van ontwerpmodellen
- Specificatie van object interfaces
Systeemontwerp
Object-georiënteerd systeemontwerp omvat het definiëren van de context van een systeem, gevolgd door het ontwerpen van de architectuur van het systeem.
-
Context – De context van een systeem heeft een statisch en een dynamisch deel. De statische context van het systeem wordt ontworpen aan de hand van een eenvoudig blokschema van het gehele systeem, dat wordt uitgebreid tot een hiërarchie van subsystemen. Het subsysteemmodel wordt gerepresenteerd door UML packages. De dynamische context beschrijft hoe het systeem interageert met zijn omgeving. Deze wordt gemodelleerd met behulp van use-case-diagrammen.
-
Systeemarchitectuur – De systeemarchitectuur wordt ontworpen op basis van de context van het systeem, overeenkomstig de beginselen van architectonisch ontwerp en de domeinkennis. Typisch wordt een systeem opgedeeld in lagen en elke laag wordt ontleed om de subsystemen te vormen.
Object-Oriented Decomposition
Decompositie betekent het opdelen van een groot complex systeem in een hiërarchie van kleinere componenten met een kleinere complexiteit, volgens de principes van verdeel-en-heers. Elke belangrijke component van het systeem wordt een subsysteem genoemd. Objectgeoriënteerde decompositie identificeert individuele autonome objecten in een systeem en de communicatie tussen deze objecten.
De voordelen van decompositie zijn –
-
De afzonderlijke componenten zijn minder complex, en dus beter te begrijpen en te beheren.
-
Het maakt verdeling van arbeidskrachten met gespecialiseerde vaardigheden mogelijk.
-
Het maakt het mogelijk subsystemen te vervangen of te wijzigen zonder dat dit gevolgen heeft voor andere subsystemen.
Identificatie van Concurrency
Concurrency maakt het mogelijk dat meer dan één object tegelijkertijd gebeurtenissen ontvangt en dat meer dan één activiteit tegelijkertijd wordt uitgevoerd. Concurrency wordt geïdentificeerd en weergegeven in het dynamische model.
Om concurrency mogelijk te maken, krijgt elk concurrency-element een aparte thread of control toegewezen. Als de concurrency op objectniveau is, dan krijgen twee gelijktijdige objecten twee verschillende threads of control toegewezen. Als twee operaties van een enkel object concurrent van aard zijn, dan wordt dat object verdeeld over verschillende threads.
Concurrency wordt geassocieerd met de problemen van data integriteit, deadlock, en starvation. Dus een duidelijke strategie moet worden gemaakt wanneer concurrency nodig is. Bovendien, concurrency vereist te worden geïdentificeerd in de ontwerpfase zelf, en kan niet worden overgelaten aan de implementatiefase.
Identifying Patterns
Bij het ontwerpen van toepassingen, een aantal algemeen aanvaarde oplossingen worden aangenomen voor bepaalde categorieën van problemen. Dit zijn de patronen van het ontwerp. Een patroon kan worden gedefinieerd als een gedocumenteerde reeks bouwstenen die kunnen worden gebruikt bij bepaalde soorten problemen bij de ontwikkeling van toepassingen.
Enkele veelgebruikte ontwerppatronen zijn –
- Façade patroon
- Model view separation patroon
- Observer patroon
- Model view controller patroon
- Publish subscribe patroon
- Proxy patroon
Controlling Events
Tijdens het systeemontwerp, moeten de gebeurtenissen die zich in de objecten van het systeem kunnen voordoen, worden geïdentificeerd en op passende wijze worden afgehandeld.
Een gebeurtenis is een specificatie van een significante gebeurtenis die een plaats in tijd en ruimte heeft.
Er zijn vier soorten gebeurtenissen die kunnen worden gemodelleerd, namelijk –
-
Signaalgebeurtenis – Een met name genoemd object dat door een object wordt geworpen en door een ander object wordt opgevangen.
-
Aanroepgebeurtenis – Een synchrone gebeurtenis die de verzending van een bewerking vertegenwoordigt.
-
Time Event – een gebeurtenis die het verstrijken van tijd vertegenwoordigt.
-
Change Event – een gebeurtenis die een verandering in de status vertegenwoordigt.
Handling Boundary Conditions
In de ontwerpfase van het systeem moet aandacht worden besteed aan de initialisatie en het einde van het systeem als geheel en van elk subsysteem. De verschillende aspecten die worden gedocumenteerd zijn als volgt –
-
Het opstarten van het systeem, d.w.z. de overgang van het systeem van de niet-geïnitialiseerde toestand naar de stabiele toestand.
-
Het beëindigen van het systeem, d.w.z, het sluiten van alle draaiende threads, het opschonen van resources en de te verzenden berichten.
-
De initiële configuratie van het systeem en de herconfiguratie van het systeem indien nodig.
-
Het voorzien van storingen of ongewenste beëindiging van het systeem.
Grensvoorwaarden worden gemodelleerd met behulp van boundary use cases.
Objectontwerp
Nadat de hiërarchie van subsystemen is ontwikkeld, worden de objecten in het systeem geïdentificeerd en worden hun details ontworpen. Hier geeft de ontwerper nadere invulling aan de strategie die tijdens het systeemontwerp is gekozen. De nadruk verschuift van toepassingsdomeinconcepten naar computerconcepten. De tijdens de analyse geïdentificeerde objecten worden geëtst voor implementatie met als doel de uitvoeringstijd, het geheugengebruik en de totale kosten te minimaliseren.
Objectontwerp omvat de volgende fasen –
- Objectidentificatie
- Objectrepresentatie, d.w.z., constructie van ontwerpmodellen
- Classificatie van operaties
- Algoritme-ontwerp
- Ontwerpen van relaties
- Implementatie van controle voor externe interacties
- Pakketten van klassen en associaties in modules
Objectidentificatie
De eerste stap van objectontwerp is objectidentificatie. De objecten die in de objectgeoriënteerde analysefasen zijn geïdentificeerd, worden gegroepeerd in klassen en verfijnd zodat zij geschikt zijn voor de feitelijke implementatie.
De functies van deze fase zijn –
-
Het identificeren en verfijnen van de klassen in elk subsysteem of pakket
-
Het definiëren van de koppelingen en associaties tussen de klassen
-
Het ontwerpen van de hiërarchische associaties tussen de klassen, d.w.z, de generalisatie/specialisatie en overervingen
-
Ontwerpen van aggregaties
Objectrepresentatie
Wanneer de klassen eenmaal zijn geïdentificeerd, moeten ze worden gerepresenteerd met behulp van technieken voor objectmodellering. Deze fase omvat in wezen het construeren van UML-diagrammen.
Er zijn twee soorten ontwerpmodellen die moeten worden geproduceerd –
-
Statische modellen – Om de statische structuur van een systeem te beschrijven met behulp van klassendiagrammen en objectdiagrammen.
-
Dynamische modellen – Om de dynamische structuur van een systeem te beschrijven en de interactie tussen klassen weer te geven met behulp van interactiediagrammen en toestandsdiagrammen.
Classificatie van operaties
In deze stap worden de operaties die op objecten moeten worden uitgevoerd gedefinieerd door de drie modellen te combineren die in de OOA-fase zijn ontwikkeld, namelijk het objectmodel, het dynamische model en het functionele model. Een bewerking specificeert wat er moet worden gedaan en niet hoe het moet worden gedaan.
De volgende taken worden uitgevoerd met betrekking tot bewerkingen –
-
Het toestandsovergangdiagram van elk object in het systeem wordt ontwikkeld.
-
Bewerkingen worden gedefinieerd voor de gebeurtenissen die door de objecten worden ontvangen.
-
Zaken waarin een gebeurtenis andere gebeurtenissen in dezelfde of verschillende objecten activeert, worden geïdentificeerd.
-
De suboperaties binnen de acties worden geïdentificeerd.
-
De belangrijkste acties worden uitgebreid tot dataflowdiagrammen.
Algoritme-ontwerp
De operaties in de objecten worden gedefinieerd met behulp van algoritmen. Een algoritme is een stapsgewijze procedure waarmee het in een bewerking vastgelegde probleem wordt opgelost. Algoritmen richten zich op de manier waarop het moet worden gedaan.
Er kan meer dan één algoritme zijn dat overeenkomt met een bepaalde bewerking. Zodra de alternatieve algoritmen zijn geïdentificeerd, wordt het optimale algoritme voor het gegeven probleemdomein gekozen. De metrieken voor de keuze van het optimale algoritme zijn –
-
Computationele complexiteit – De complexiteit bepaalt de efficiëntie van een algoritme in termen van rekentijd en geheugenvereisten.
-
Flexibiliteit – De flexibiliteit bepaalt of het gekozen algoritme op geschikte wijze kan worden geïmplementeerd, zonder verlies van geschiktheid in verschillende omgevingen.
-
Onbegrijpelijkheid – Hiermee wordt bepaald of het gekozen algoritme gemakkelijk te begrijpen en te implementeren is.
Ontwerpen van relaties
De strategie voor het implementeren van de relaties moet worden uitgestippeld tijdens de fase van het objectontwerp. De belangrijkste relaties die aan de orde komen, bestaan uit associaties, aggregaties en overervingen.
De ontwerper moet het volgende doen met betrekking tot associaties –
-
Identificeer of een associatie unidirectioneel of bidirectioneel is.
-
Het pad van associaties analyseren en deze zo nodig bijwerken.
-
De associaties implementeren als een afzonderlijk object in het geval van veel-op-veelrelaties; of als een koppeling naar een ander object in het geval van één-op-één- of één-op-veelrelaties.
Met betrekking tot overervingen dient de ontwerper het volgende te doen –
-
De klassen en hun associaties aanpassen.
-
Aftrekselklassen identificeren.
-
Zorg ervoor dat gedragingen worden gedeeld wanneer dat nodig is.
Implementatie van besturing
De objectontwerper kan verfijningen aanbrengen in de strategie van het toestandsdiagrammodel. Bij het systeemontwerp wordt een basisstrategie voor het realiseren van het dynamische model gemaakt. Tijdens het objectontwerp wordt deze strategie op passende wijze verfraaid voor een geschikte implementatie.
De benaderingen voor de implementatie van het dynamische model zijn –
-
Represent State as a Location within a Program – Dit is de traditionele procedure-gedreven benadering waarbij de plaats van controle de programmatoestand bepaalt. Een eindige toestandsmachine kan worden geïmplementeerd als een programma. Een overgang vormt een inputstatement, het hoofdbesturingspad vormt de volgorde van instructies, de vertakkingen vormen de voorwaarden, en de achterwaartse paden vormen de lussen of iteraties.
-
State Machine Engine – Deze benadering vertegenwoordigt een toestandsmachine rechtstreeks via een state machine engine class. Deze klasse voert de toestandsmachine uit via een reeks overgangen en acties die door de toepassing worden verstrekt.
-
Controle als samenlopende taken – In deze benadering wordt een object geïmplementeerd als een taak in de programmeertaal of het besturingssysteem. Hier wordt een gebeurtenis geïmplementeerd als een inter-taak oproep. Hiermee wordt de inherente gelijktijdigheid van echte objecten behouden.
Packaging Classes
In elk groot project is een zorgvuldige indeling van een implementatie in modules of pakketten belangrijk. Tijdens het ontwerpen van objecten worden klassen en objecten gegroepeerd in pakketten om meerdere groepen in staat te stellen samen aan een project te werken.
De verschillende aspecten van verpakken zijn –
-
Het verbergen van interne informatie van buitenaf – Hierdoor kan een klasse worden gezien als een “zwarte doos” en kan de implementatie van de klasse worden gewijzigd zonder dat clients van de klasse code hoeven te wijzigen.
-
Samenhang van elementen – Een element, zoals een klasse, een bewerking of een module, is samenhangend als het volgens een consistent plan is georganiseerd en alle onderdelen ervan intrinsiek met elkaar zijn verbonden zodat ze een gemeenschappelijk doel dienen.
-
Bouw van fysieke modules – De volgende richtlijnen helpen bij de bouw van fysieke modules –
-
Klassen in een module moeten soortgelijke dingen of componenten in hetzelfde samengestelde object vertegenwoordigen.
-
Nauw verbonden klassen moeten in dezelfde module worden geplaatst.
-
Niet-verbonden of zwak-verbonden klassen moeten in afzonderlijke modules worden geplaatst.
-
Modules moeten een goede cohesie hebben, d.w.z,
-
Een module moet een lage koppeling met andere modules hebben, d.w.z. de interactie of onderlinge afhankelijkheid tussen modules moet minimaal zijn.
-
Optimalisatie van het ontwerp
Het analysemodel legt de logische informatie over het systeem vast, terwijl het ontwerpmodel details toevoegt om een efficiënte toegang tot de informatie te ondersteunen. Voordat een ontwerp wordt geïmplementeerd, moet het worden geoptimaliseerd om de implementatie efficiënter te maken. Het doel van optimalisatie is het minimaliseren van de kosten in termen van tijd, ruimte, en andere metrieken.
Hoewel, optimalisatie van het ontwerp moet niet overdadig zijn, omdat gemak van implementatie, onderhoudbaarheid, en uitbreidbaarheid ook belangrijke punten van zorg zijn. Men ziet vaak dat een perfect geoptimaliseerd ontwerp efficiënter is, maar minder leesbaar en herbruikbaar. De ontwerper moet dus een evenwicht zien te vinden tussen die twee.
De verschillende dingen die kunnen worden gedaan voor ontwerpoptimalisatie zijn –
- Opnemen van overbodige associaties
- Opnemen van niet-bruikbare associaties
- Optimalisatie van algoritmen
- Opslaan van afgeleide attributen om herberekening van complexe expressies te voorkomen
Opnemen van overbodige associaties
Tijdens ontwerpoptimalisatie, wordt gecontroleerd of het afleiden van nieuwe associaties de toegangskosten kan verlagen. Hoewel deze overbodige associaties misschien geen informatie toevoegen, kunnen ze de efficiëntie van het totale model verhogen.
Toevoeging van niet-bruikbare associaties
De aanwezigheid van te veel associaties kan een systeem onleesbaar maken en daarmee de algehele efficiëntie van het systeem verminderen. Daarom worden tijdens de optimalisatie alle niet-bruikbare associaties verwijderd.
Optimalisatie van Algoritmen
In object-georiënteerde systemen, gebeurt de optimalisatie van gegevensstructuur en algoritmen op een collaboratieve manier. Zodra het klasse-ontwerp er is, moeten de operaties en de algoritmen worden geoptimaliseerd.
Optimalisatie van algoritmen wordt verkregen door –
- Herschikking van de volgorde van rekentaken
- Omkering van de uitvoeringsvolgorde van lussen ten opzichte van die welke in het functionele model is vastgelegd
- Verwijdering van dode paden binnen het algoritme
Opslaan en opslaan van afgeleide attributen
Afgeleide attributen zijn die attributen waarvan de waarden worden berekend als een functie van andere attributen (basis-attributen). Het opnieuw berekenen van de waarden van afgeleide attributen telkens wanneer ze nodig zijn, is een tijdrovende procedure. Om dit te vermijden kunnen de waarden worden berekend en opgeslagen in hun berekende vorm.
Hierbij kunnen echter update-anomalieën optreden, d.w.z. een wijziging in de waarden van de basisattributen zonder overeenkomstige wijziging in de waarden van de afgeleide attributen. Om dit te voorkomen, worden de volgende stappen ondernomen –
-
Met elke bijwerking van de waarde van de basiseigenschap, wordt ook de afgeleide eigenschap opnieuw berekend.
-
Alle afgeleide eigenschappen worden periodiek opnieuw berekend en bijgewerkt in een groep in plaats van na elke bijwerking.
Ontwerpdocumentatie
Documentatie is een essentieel onderdeel van elk softwareontwikkelingsproces waarin de procedure voor het maken van de software wordt vastgelegd. De ontwerpbeslissingen moeten worden gedocumenteerd voor elk niet-triviaal softwaresysteem om het ontwerp aan anderen over te brengen.
Gebruiksgebieden
Hoewel een secundair product, is een goede documentatie onontbeerlijk, met name op de volgende gebieden –
- Bij het ontwerpen van software die door een aantal ontwikkelaars wordt ontwikkeld
- In iteratieve softwareontwikkelingsstrategieën
- Bij het ontwikkelen van volgende versies van een softwareproject
- Voor het evalueren van een software
- Voor het vinden van voorwaarden en gebieden voor het testen
- Voor het onderhoud van de software.
Inhoud
Een nuttige documentatie dient in hoofdzaak de volgende inhoud te bevatten –
-
Hoge systeemarchitectuur – Procesdiagrammen en modulediagrammen
-
Kernabstracties en mechanismen – Klassendiagrammen en objectdiagrammen.
-
Scenario’s die het gedrag van de belangrijkste aspecten illustreren – Gedragsdiagrammen
Functies
De eigenschappen van een goede documentatie zijn –
-
Concreet en tegelijkertijd ondubbelzinnig, consistent en volledig
-
Traceerbaar naar de specificaties van de systeemvereisten
-
Goed gestructureerd
-
Diagrammatisch in plaats van beschrijvend