Hoofdstuk Systeem- en Programma-ontwerp



Dovnload 64.33 Kb.
Datum22.08.2016
Grootte64.33 Kb.
Hoofdstuk 1.

Systeem- en Programma-ontwerp.

Vooraleer men met het schrijven van een programma kan beginnen dient men precies te weten wat het moet doen. Dit lijkt wel evident, maar toch blijkt dat meer dan de helft van de moeilijkheden, die zich voordoen bij het gebruik van programma's, resulteren uit misverstanden over wat het programma precies moet doen. Het belang van volledige en correcte specificaties mag dus nooit onderschat worden.
1.1. Specificaties.
Programma specificaties beschrijven nauwkeurig wat een programma moet doen. Formeel uitgedrukt betekent dit dat specificaties drie elementen definiëren:

-1) de verzameling van alle mogelijke (correcte en incorrecte) gegevens die kunnen ingevoerd worden,

-2) de verzameling van alle mogelijke resultaten,

-3) een functie die elk element van de eerste verzameling doet overeenstemmen met een element van de tweede.


Voor betrekkelijk kleine en eenvoudige programma's is het mogelijk de specificaties zeer formeel, met wiskundige striktheid, op te stellen. Hiervoor bestaan er specifieke notaties en technieken. Deze werkwijze zou de voorkeur moeten genieten wanneer men een hoog vertrouwen in de resultaten wenst.
Voor veel grotere programma's zijn de formele specificatietechnieken nog ontoereikend, want te log, en dient een compromis gezocht te worden tussen de volledigheid en correctheid van de specificaties enerzijds en de inspanning voor het opstellen van die specificaties anderzijds.
Om de moeilijkheid van het opstellen van specificaties te evalueren dient men rekening te houden met twee belangrijke factoren: enerzijds het aantal personen die het programma zullen moeten gebruiken en anderzijds het aantal andere programma's waarmee gegevens zullen moeten uitgewisseld worden.
Het eenvoudigste geval is ongetwijfeld het alleenstaande programma, dat enkel door zijn auteur zal gebruikt worden.

Als voorbeeld hiervan kan men programma's citeren die door studenten geschreven worden om een welbepaalde vergelijking op te lossen of om de optimale oplossing voor een scrabble wedstrijd te vinden. De auteur weet over welke gegevens hij beschikt, wat zijn programma er zal mee moeten doen en welke resultaten hij wenst; formaten van gegevens en resultaten worden meestal gespecificeerd tijdens het schrijven van het programma en voorzieningen voor verkeerde invoer kunnen erg summier blijven vermits de auteur van het programma meestal weet hoe hij het moet gebruiken en niet in paniek zal geraken bij een verkeerde handeling.


Het meest complex geval treft men aan wanneer men volledige informatiesystemen moet specificeren, waarin honderdtallen programma's onderling gegevens moeten kunnen uitwisselen om allerlei specifieke verwerkingen te verrichten, en waarbij de gebruikers van dat informatiesysteem erg uiteenlopende vormingen en interesses hebben, die meestal niets te maken hebben met informatica. In geautomatizeerde administraties, maar ook in moderne studiebureaus en in geautomatizeerde fabrieken treft men dergelijke informatiesystemen aan.
Volgens F.Brooks (Zie boek in bibliografie) moet men rekenen dat een zelfde programma tot drie maal meer zorg vergt, en dus drie maal duurder zal zijn, wanneer het moet kunnen gebruikt worden door iemand anders dan de auteur, en dat er nog eens een factor drie bijkomt wanneer het programma moet kunnen geïntegreerd worden in een verzameling programma's. Deze verhoogde kwaliteit moet zich uiteraard weerspiegelen in de specificaties, die alle voorzieningen voor gebruikersvriendelijkheid en compatibiliteit met andere programma's expliciet moeten formuleren.
1.2. Ontwerp methodes.
Een bepaald probleem kan gewoonlijk door oneindig veel programma's opgelost worden: sommige programma's zullen minder geheugen vergen, andere zullen sneller werken, nog andere zullen minder programmatiewerk vergen, enkel in uitzonderlijke gevallen kan één duidelijk optimum gevonden worden.
Het ontwerp van een programma, zoals trouwens van gelijk welk ander produkt, zal dus cycli van probleem analyse, oplossingskeuze, oplossingsrealisatie en oplossingsevaluatie moeten doorlopen.
De krachtigste methode om complexe problemen te benaderen bestaat erin deze trachten op te splitsen in eenvoudigere deelproblemen die onafhankelijk van elkaar kunnen opgelost worden. Deze methode biedt het bijkomend voordeel dat ze ploegwerk in de hand werkt, vermits elk onafhankelijk deelprobleem aan andere mensen kan toevertrouwd worden.
Om een complex probleem op te splitsen in deelproblemen kunnen twee ontwerpmethodes gebruikt worden: de "Top Down" en de "Bottom Up" methode.
1.2.1. Top down.
In de beginfaze zal het probleem globaal bekeken worden, met weinig aandacht voor de realisatiedetails. Daarna zal het opgesplitst worden in kleinere deelproblemen, die meer in detail zullen onderzocht worden, rekening houdend met eigenschappen van de beschikbare middelen (talen, computerhardware...).

Deze detailstudie zal dikwijls aantonen dat de opsplitsing in deelproblemen niet ideaal was qua verwezenlijkbaarheid van de deeloplossingen. Men zal dan terug naar het globaal niveau moeten keren, om een betere opsplitsing te realiseren.


Deze benadering, van algemeen naar detail, wordt een "top down" benadering genoemd en is sterk aan te raden wanneer omvangrijke en/of slecht gekende problemen dienen opgelost te worden.
Bij het ontwerpen van geïntegreerde informatiesystemen is een voorafgaande studie van gans de organisatie en van de informatiestromen in die organisatie, los van de details van de electronische informatieverwerking, een essentiële stap die de specificaties van programma's moet voorafgaan. Dit kan ook als een eerste stap van de "top-down" benadering van het ontwerp van informatiesystemen beschouwd worden.
1.2.2. Bottom up.
Een andere mogelijke oplossingsmethodiek bestaat erin eerst enkele programma's te schrijven om deelproblemen op te lossen, vervolgens gebruik te maken van deze programma's als bouwstenen om grotere deelprogramma's samen te stellen, en zo verder te gaan tot uiteindelijk het gehele probleem opgelost is. Wanneer men hogere niveaus bereikt, kan men uiteraard vaststellen dat de bouwstenen slecht gekozen waren en dat men verplicht is er andere te maken.
Deze methode kan voor kleinere problemen, waarmee de ontwerper goed vertrouwd is, sneller tot een efficiënte oplossing leiden dan de top down methode, maar zal gewoonlijk quasi onbruikbaar zijn voor complex problemen waarvan de programmeur niet a-priori een globale visie heeft.
Bottom up methodes zijn ook aangewezen wanneer men dikwijls gelijkaardige problemen moet oplossen: om een nieuw programma te maken zal men uit bestaande programma's zoveel mogelijk bouwstenen halen.

Dergelijke werkwijze kan uiteraard alleen maar succesvol zijn wanneer alle modules onafhankelijk kunnen gebruikt worden en informatie uitwisselen op een goed omschreven en uniforme wijze.

Moderne besturingssystemen en software ontwikkelingsomgevingen bieden aan de gebruikers volledige bibliotheken met programma’s die vaak voorkomende taken verrichten, zoals bv. het tekenen van een afrolbaar menu, het tonen van een bitmap, het formateren van teksten, het spelen van een stukje musiek, enz. Op deze wijze wordt de ontwikkeling van een nieuwe toepassing het aaneenlijmen van verschillende bestaande software componenten. De ontwerpmethodiek hiervoor is een combinatie van top-down en bottom-up: top-down om de globale oplossing te ontwerpen en om het raamwerk dat de verschillende componenten aan elkander hecht te definiëren, bottom-up om de beschikbare componenten in de globale oplossing in te passen.
1.2.3. Voorbeeld.
Er zal hier een voorbeeld behandeld worden dat niets met de informatica te maken heeft, maar dat toelaat, mits een beetje goede wil van de lezer, de voornaamste concepten van de verschillende ontwerpmethodes te illustreren zonder op enige programmatie kennis beroep te doen.
Het voorbeeld handelt over een wagen met een lekke band langs de autosnelweg. Er wordt gevraagd een handleiding [programma] te schrijven die aan de chauffeur zou uitleggen wat hij hoeft te doen in termen die voor elke (niet technisch begaafde) chauffeur verstaanbaar zouden zijn [uitvoerbare instructies].
Eerst moet een oplossingsstrategie [systeemorganisatie] gekozen worden. Men zou inderdaad kunnen aanraden Touring Wegenhulp op te bellen, of gewoonweg naast de wagen te blijven staan met een smekende glimlach tot iemand stopt om de karwei op te knappen... Hier zal enkel het geval van de chauffeur die tracht zijn wagen zelf te herstellen besproken worden.
Wanneer het probleem "top down" benaderd wordt, zou de eerste stap van het ontwerp er als volgt kunnen uitzien:
Eerst dienen de gegevens waarover men beschikt opgesomd te worden. Hier zullen we, met een beetje goede wil, volgende elementen als gegevens beschouwen:


defekte wiel;

reserve wiel;

gereedschappen;

Daarna worden de acties die uitgevoerd worden op deze gegevens opgesomd:




Onderzoek het reservewiel;
INDIEN het in goede staat is
DAN kan u trachten de herstelling zelf te verrichten
ZONIET moet u externe hulp oproepen.

De verschillende onderdelen van de geschetste oplossing kunnen dan meer gedetailleerd worden. Zo kan men bijvoorbeeld het "zelf herstellen" als volgt ontbinden:




Neem gereedschappen;
Neem reservewiel;
Vervang defekte wiel door reserve wiel;
Berg defekte wiel;
Berg gereedschappen;

"neem gereedschappen" en "berg gereedschappen" kunnen op hun beurt als volgt verder uitgewerkt worden:




INDIEN gereedschappen ontbreken of onbruikbaar zijn
DAN HERAAL tracht gereedschappen te lenen
TOT u er goede hebt OF u ontmoedigd bent;
INDIEN u geen gereedschappen hebt
DAN moet u externe hulp vragen;

INDIEN gereedschappen geleend
DAN geef gereedschappen terug aan eigenaar;
dank voor de gereedschappen
ZONIET plaats gereedschappen terug in de wagen;

"Vervang defekte wiel door reserve wiel" vergt ook meer details, zowel qua gegevens als qua acties:

Voor wat de gegevens betreft dient het begrip "gereedschappen" verder verfijnd te worden en dienen "bevestigingsbouten" gedefinieerd te worden:


gereedschappen:

krik;


hendel;

engelse sleutel;

bevestigingsbouten;


De acties worden dan in meer detail beschreven als volgt:




Maak de bevestigingsbouten los;
Licht wagen op met de krik;

Verwijder de bevestigingsbouten;


Neem het defekte wiel weg;
Plaats het reserve wiel;
Plaats de bevestigingsbouten;
Breng wagen omlaag;
Span de bevestigingsbouten aan;

Deze ontbinding kan verder gedreven worden tot alle akties beschreven zijn in termen die eenvoudig genoeg zijn om verstaanbaar te zijn voor elke onervaren chauffeur.


Bij een "bottom up" benadering, zou men eerst in detail beschrijven hoe men een wagen opkrikt, hoe men een bout losdraait, hoe men er een vastdraait, enz... Deze beschrijvingen zouden dan gegroepeerd worden om de globale handleiding voor het herstellen van een lekke band samen te stellen, maar dezelfde beschrijvingen zouden ook nog elders kunnen gebruikt worden, bv. om uit te leggen hoe men de banden moet uitwisselen om slijtage van voor- en achterbanden te uniformiseren.
1.2.4. Gestruktureerde gegevens.
Een programma is de beschrijving van akties die moeten uitgevoerd worden. Deze akties spelen in op bepaalde voorwerpen, de gegevens, die door het programma verwerkt worden.
Soms is het mogelijk de aard van de gegevens af te leiden van de akties die erop toegepast worden, en dan is het niet strikt noodzakelijk een beschrijving van de gegevens in het programma op te nemen, maar meestal zullen programma's wel beter leesbaar en betrouwbaarder zijn wanneer alle gegevens expliciet beschreven zijn.
Dergelijke beschrijving kan ook modulair en hiërarchisch opgevat worden en volgens de "top-down" of de "bottom-up" methode ontworpen worden. Hier zal de top-down methode ook de meest natuurlijke zijn, maar de bottom-up methode kan interessant zijn wanneer men de opslag en de toegang tot de gegevens in het geheugen van de computer wenst te optimiseren door de organisatie van de gegevens aan te passen aan de fysische kenmerken van de computer.
In het voorbeeld van de lekke band heeft men voorwerpen zoals "reservewiel", "defekt wiel", "gereedschappen" en "bevestigingsbouten" als gegevens beschouwd. Het begrip "gereedschappen" is dan vatbaar voor verfijning: het is een kollektieve naam voor "krik", "hendel" en "engelse sleutel".
1.2.5. Globale gegevens.
De programma's die logischerwijze resulteren uit een top-down of een bottom-up ontwerp zijn hiërarchisch: een hoofdprogramma bevat de definities van de verschillende deelprogramma's en van de gegevens die doorheen gans het programma gebruikt worden. Elk van de deelprogramma's bevat dan op zijn beurt de definitie van de deelprogramma's waarvan het gebruik moet maken, en van de gegevens die eigen aan het deelprogramma zijn.
Alhoewel deze struktuur tot zeer duidelijke programma's leidt, is ze niet ideaal geschikt voor omvangrijke programma's: vermits gegevens meestal globaal gedefinieerd zijn en door meerdere deelprogramma's gebruikt worden, zal elke wijziging in de definitie van een gegevenstruktuur aanpassingen in verschillende deelprogramma's noodzakelijk maken, wat een bron van fouten kan zijn, vooral wanneer de verschillende deelprogramma's door verschillende personen geschreven zijn.
Indien het model van krik zou gewijzigd worden in het voorbeeld van de lekke band, zal niet alleen de beschrijving van de krik moeten aangepast worden, maar ook de test om te zien of de krik wel in orde is, de gebruiksaanwijzing van de krik en misschien zelfs de uitleg over het wegbergen van de gereedschappen.
1.2.6. Objekt georiënteerde programmatie.
In plaats van het accent te leggen op de akties die moeten verricht worden om een bepaald probleem op te lossen, kan men zich ook toespitsen op de gegevens die in het programma moeten verwerkt worden en op al de operaties die men moet kunnen verrichten op die gegevens om het gestelde probleem op te lossen.
Deze denkwijze, gecombineerd met een top-down of een bottom-up ontwerpmethode zal ook tot een modulair programma leiden, maar met een totaal andere opsplitsing dan deze die beschreven werd in de vorige paragraaf. Hier zal een module samengesteld zijn uit de beschrijving van een bepaald type gegeven en van alle operaties die gegevens van dat type kunnen ondergaan.
Dergelijk module noemt men een "objekt".
Vermits de beschrijving van alle operaties op een bepaalde gegevensstruktuur in een enkele module samengebracht zijn, kunnen de verschillende modules heel onafhankelijk van elkaar opgebouwd worden, zodat een wijziging in een module meestal geen gevolg zal hebben in andere modules.
In een "objekt georiënteerde" benadering van de lekke band zouden de objekten "wiel" en "gereedschappen" voorkomen. Het objekt "gereedschappen" zou verfijnd worden in "krik","hendel", "Engelse sleutel", enz... De beschrijvingen van de operaties "nemen", "lenen", "werking controleren", "onder wagen plaatsen", "opkrikken", "neerlaten" en "wegbergen" zouden samen met de beschrijving van de krik zelf het objekt "krik" vormen. Indien elders in het programma naar een krik moet verwezen worden zou dat noodzakelijk gebeuren via de operaties die in het objekt gedefiniëerd zijn. Indien het model van de krik nu zou gewijzigd worden, zou alleen het objekt "krik" moeten aangepast worden, terwijl de rest van het programma ongewijzigd zou kunnen blijven.
1.3. Hulpmiddelen voor specificatie en ontwerp.
Het is natuurlijk mogelijk, zoals in voorgaand voorbeeld, specificaties en programmaontwerp te beschrijven in een min of meer geformaliseerde natuurlijke taal, maar men zal meestal beroep doen op betere hulpmiddelen.

Er bestaan zeer veel verschillende hulpmiddelen om informatiesystemen en programma's te specificeren en te ontwerpen. Dit bewijst enerzijds het nut van dergelijke hulpmiddelen, maar anderzijds ook dat er nog geen echt goede bestaan. De meeste zijn goed geschikt om een bepaald aspect toe te lichten, maar zijn dan meestal ontoereikend voor andere aspekten.


1.3.1. Beslissingstabellen.
Wanneer men alleen maar de verschillende opties die in een programma voorzien zijn in functie van de invoergegevens wenst te illustreren, kan men beslissingstabellen gebruiken. Zij geven aan wat er moet gebeuren voor de verschillende combinaties van invoergegevens.

Het voorbeeld van de lekke band kan dit ook illustreren (fig 1.1)







Reservewiel OK

Reserve wiel niet OK

Gereedschappen OK

Herstel zelf

Externe hulp nodig

Gereedschappen niet OK

Tracht gereedschappen te lenen of roep externe hulp

Externe hulp nodig

Fig.1.1. Beslissingstabel voor het probleem van een lekke band.
Men dient op te merken dat er in dergelijke beslissingstabel geen enkele aanduiding van tijd of volgorde is: men weet niet of men eerst de gereedschappen of eerst het reservewiel moet controleren.
1.3.2. Programmastroomschema's (control-flow charts).
1.3.2.1. Principe.

Om de opeenvolging van akties in een programma te illustreren gebruikt men dikwijls programmastroomschema's. Dat zijn diagrammen opgebouwd uit drie elementen:

- rechthoeken om verzamelingen akties voor te stellen.

- ruiten om beslissingen betreffende het verder verloop van het programma voor te stellen.

- georiënteerde lijnen tussen deze elementen om het verloop van het programma voor te stellen .
Meer algemeen kan men rechthoeken aanwenden om deelprogramma's voor te stellen met één enkel beginpunt en één enkel eindpunt. Ruiten kunnen gebruikt worden voor deelprogramma's waarin een keuze moet gemaakt worden, zodat men het deelprogramma op twee verschillende manieren kan verlaten. Deze extensie laat toe programmastroomschema's te gebruiken bij een hiërarchisch ontwerp: een eerste schema stelt het globaal verloop van het programma voor, met rechthoeken en ruiten die grote deelprogramma's voorstellen. Volgende schema's geven dan de inhoud van elke rechthoek en ruit van het eerste, en zo verder tot alles in voldoende detail weergegeven is.
1.3.2.2. Voorbeeld.
Opnieuw zal het voorbeeld van de lekke band aangewend worden om programmastroomschema's, hun voordelen en hun nadelen te illustreren.

In fig. 1.2 vindt men een schema dat overeenstemt met het eerste ontwerp, zoals beschreven in paragraaf 1.2.3. en de verfijning van de rechter blok "repair yourself".

F
ig. 1.2. Een eerste ontwerp voor het herstellen van een lekke band, met de verfijning van de blok "repair yourself".
De blok “Get Tools” kan op zijn beurt verfijnd worden, zoals weergegeven in fig.1.3

F
ig. 1.3. Verfijning van de blok "get tools" uit fig 1.3.


In fig 1.3 stelt men vast dat, om rekening te houden met de moeilijkheid van het lenen van gereedschappen, men een bijzondere uitweg naar het oproepen van externe hulp heeft voorzien. Deze uitweg was niet voorzien in figuur 1.2. Hier hebben we te maken met een iteratie in het top-down ontwerpproces: bij het uitwerken van de details van een deeloplossing merken we dat de oorspronkelijke opsplitsing niet helemaal korrekt was. Fig. 1.4 en 1.5 geven aangepaste programmastroomschema's.
F
ig. 1.4. Een verbeterd algoritme voor het herstellen van een lekke band.
F
ig. 1.5. Verfijning van de blok "fetch tools" uit fig. 1.4.
1.3.2.3. Nadelen van programmastroomschema's.
Programmastroomschema's worden nog veel gebruikt bij het ontwerpen en het documenteren van programma's. Zij hebben echter fundamentele tekortkomingen waarvan de belangrijkste hier kort zullen besproken worden.
a) Programmastroomschema's laten niet toe gegevensstructuren voor te stellen terwijl, bij moderne programmeerstijlen, de gegevensstructuren minstens even belangrijk zijn als de volgorde waarin instructies worden uitgevoerd.
b) Programmastroomschema's maken een weinig efficiënt gebruik van de papier oppervlakte, wat tot gevolg heeft dat complexe programma's niet op een blad van redelijke afmetingen kunnen voorgesteld worden. Daarbij komt dat, om het papier efficiënter te gebruiken, men de neiging zal hebben uiterst summiere teksten te schrijven in de ruiten, wat quasi automatisch tot onnauwkeurigheden zal leiden.
c) Ondanks het feit dat er veel programma's bestaan die automatisch een programmastroomschema tekenen vertrekkende van een programma, bestaan er geen bevredigende programma's die de tegengestelde transformatie kunnen verrichten (wat logisch is vermits programmastroomschema’s geen informatie bevatten over de gegevens die in het programma kunnen verwerkt worden). Wanneer programmastroomschema's dan aangewend worden als hulp bij het ontwerpen van programma's, moet de vertaling van het schema in een uitvoerbaar programma met de hand gebeuren, wat een bron van moeilijk op te sporen fouten kan zijn.
d) Programmastroomschema's leggen geen enkele structuur op, zij laten toe programma's voor te stellen, en dus te ontwerpen, waarin voortdurend van een eind naar het ander gesprongen wordt. Dergelijke programma's zullen uiteraard onduidelijk en weinig betrouwbaar zijn.

(Naar aanleiding van het uitzicht van het schema van dergelijke programma's, spreekt men van "spaghetti programma's").


1.3.3. Gestructureerde programmastroomschema's.
Klassieke programmastroomschema's laten toe een willekeurige opeenvolging van instructies voor te stellen: ruiten en lijnen komen overeen met resp. voorwaardelijke en onvoorwaardelijke sprongen die toelaten van gelijk waar in een programma naar gelijk waar elders te springen. Dergelijke vrijheid is duidelijk onverenigbaar met het principe van modulaire programma's. Het is moeilijk te bepalen wat er al gebeurd is op het ogenblik dat een module wordt uitgevoerd en het is zelfs mogelijk dat er naar het midden van een module gesprongen wordt.
In het voorbeeld dat weergegeven is in fig. 1.4 ziet men een sprong van een deel van een programma naar een ander: de module "get help" kan bereikt worden in geval van een defekt reserve wiel, of in geval van de onbeschikbaarheid van gereedschappen. Het is a priori niet evident dat de aard van de hulp die nodig is dezelfde is in beide gevallen!
De gestruktureerde programmeerstijl beperkt sterk de vrijheid van de programmeurs: zij moeten hun programma's opbouwen met behulp van modules die één beginpunt en één eindpunt hebben, dus met modules die in een klassiek programmastroomschema kunnen voorgesteld worden door een rechthoek.

In plaats van spronginstructies beschikken zij dan over twee gespecialiseerde controle instructies, één voor selekties en één voor herhalingen.


B
ij de selectieinstructie wordt één tak uit meerdere alternatieven gekozen, in functie van de waarde van een expressie. Fig. 1.6 geeft het klassieke programmastroomschema waarmee de selectieinstructie zou kunnen voorgesteld worden.
Fig.1.6. Veralgemeende selectieinstructie.
Bij de herhalingsinstructie wordt een verzameling instrukties herhaaldelijk uitgevoerd. Telkens wordt nagegaan of een bepaalde voorwaarde al of niet voldaan is. Zolang die voorwaarde niet voldaan is wordt de herhaling verder gezet. Fig 1.7 geeft het klassieke programmastroomschema waarmee de herhalingsinstruktie zou kunnen voorgesteld worden. Men dient op te merken dat ook deze programmastructuur één beginpunt en één eindpunt heeft, en dus, op een algemener niveau ook kan voorgesteld worden door een rechthoek.
F
ig.1.7. Veralgemeende herhalingsinstructie.
Wanneer men programmastroomschema's gebruikt als hulpmiddel bij het ontwerpen van programma's en men gestruktureerd wil werken, zou men zich de discipline moeten opleggen alleen maar gewone rechthoeken, en de strukturen van fig. 1.6 en 1.7 te gebruiken. Om te vermijden dat programmeurs geneigd zouden zijn van deze discipline af te wijken hebben Nassi en Schneidermann bijzondere programmastroomschema's bedacht waarbij het niet mogelijk is iets anders dan de toegelaten strukturen voor te stellen. Fig 1.8 geeft het NS diagrammen voor een selektie en fig 1.9 voor een herhaling.
F
ig.1.8. Nassi-Schneidermann diagram voor een selectie.
F
ig.1.9. Nassi-Schneidermann diagram voor een herhaling.
In plaats van de gegeneraliseerde selectie en herhalings instructies gebruikt men meestal meer beperkte varianten van deze instructies: Voor de selectie beperkt men zich vaak tot twee alternatieven en voor herhalingen plaatst men de beëindigingsvoorwaarde meestal in het begin of bij het einde eerder dan midden in de opdracht die herhaald wordt.
Ter illustratie van gestructureerde opdrachten geven fig. 1.10 en 1.11 het globale schema en gedeeltelijke verfijningen voor het lekke band probleem. In fig. 1.10 dient men op te merken dat, vermits het niet mogelijk is vanuit twee verschillende plaatsen naar één enkele "get help" module te springen, men twee afzonderlijke "get help" modules voorzien heeft, die dan aan de specifieke eisen van de toestand kunnen aangepast worden. Wanneer de twee modules toch identiek zouden uitvallen, zou men kunnen denken dat deze gestructureerde benadering eerder inefficiënt is, maar dat is niet waar want verder zal getoond worden dat, wanneer identieke modules op meerdere plaatsen voorkomen, één enkele kopie van de module kan volstaan, zonder dat daarom de logische structuur van het programma moet gewijzigd worden. Dit kan door modules op te vatten als deelprogramma's die een naam hebben, en kunnen opgeroepen worden van gelijk waar in het programma.
F
ig 1.10. NS diagram voor het herstellen van een lekke band met verfijning van “Fetch Tools” en “Repair Yourself”.
Nassi-Schneidermann diagrammen zijn een goed alternatief voor klassieke programmastroomschema's, maar men mag niet vergeten dat ze maar één van de fundamentele tekortkomingen van programmastroomschema's, namelijk het gebrek aan opgelegde structuur, opvangen.

Fig 1.11. Verfijning van de "change wheel" module.

1.3.4. Gegevensstroomschema's (data-flow charts).


Complementair aan de beschrijving van de opeenvolging van de instructies tijdens de uitvoering van een programma kan men ook beschrijven wat er met de gegevens gebeurt. Hiervoor kan men zgn. gegevensstroomschema's gebruiken waarin, voor elk gegeven, de opeenvolgende bewerkingen die het ondergaat voorgesteld zijn.
Gegevensstroomschema's zijn bijzonder nuttig op het systeemniveau om de uitwisselingen van gegevens tussen verschillende programma’s op een overzichtelijke wijze weer te geven. Zij worden ook aangewend, in combinatie met programmastroomschema's, om bepaalde programmafouten op te sporen en om een optimale volgorde van instructies te zoeken teneinde het best mogelijk gebruik te maken van alle middelen die voorhanden zijn in een computer.
Fig 1.12 geeft, ter illustratie, een soort van gegevensstroomschema waarin aangetoond wordt wat er allemaal met het defekte wiel, met het reserve wiel en met de gereedschappen gebeurt in het geval dat zowel het reserve wiel als de gereedschappen bruikbaar zijn.
Indien bepaalde gegevens op verschillende wijzen kunnen behandeld worden in een programma, kan men dat niet op een eenvoudige wijze weergeven in de gegevensstroomschema's en is men dikwijls verplicht voor elk geval een afzonderlijk schema te tekenen. Dit is de reden waarom in het voorbeeld van de lekke band alleen maar het meest gunstige geval voorgesteld werd.
F
ig. 1.12. Data-flow diagram voor het probleem van een lekke band.
1.4. Aanpasbaarheid van programma's.
In het eerste deel van dit hoofdstuk werd reeds vermeld dat programma's dikwijls moeten aangepast worden omdat hun specificaties gebrekkig waren of omdat de context waarin de programma's gebruikt worden veranderd is.
Zoals reeds besproken in hoofdstuk 5 van deel 1 blijkt dat de totale kostprijs van een professioneel software pakket hoofdzakelijk bepaald wordt door het testen alvorens het in gebruik kan genomen worden en door de vele kleine aanpassingen die nodig blijken gedurende de normale levensduur van een software pakket. Hieruit kan men besluiten dat het gemak waarmee men programma's kan testen en wijzigen een doorslaggevende invloed zal hebben op de totale kostprijs van de programma's.
De voornaamste voorwaarde voor testbaarheid en aanpasbaarheid is verstaanbaarheid. Dit is evident wanneer verschillende personen instaan voor het ontwerpen, het testen en het onderhoud, maar eveneens wanneer een zelfde persoon al deze taken op zich neemt aangezien de grote aanpassingen meestal verschillende jaren na het oorspronkelijk ontwerp gebeuren.
Om verstaanbaar te zijn moet een programma goed leesbaar en gedocumenteerd zijn.
1.4.1. Leesbaarheid van uitvoerbare code.
De leesbaarheid van een programma wordt bepaald door de structuur van het programma en door de keuze van de namen die in het programma gebruikt worden.
Om goed leesbaar te zijn, moet de code van een programma goed gestructureerd zijn, d.w.z. dat het programma moet opgebouwd zijn uit modules die klein genoeg zijn om gemakkelijk verstaanbaar te zijn, en dat alleen maar gestructureerde controle instructies mogen aangewend worden. Algemeen neemt men aan dat een module, om verstaanbaar te zijn, niet meer dan een blad van een listing in beslag mag nemen.
De meeste moderne programmeertalen laten toe de hiërarchische structuur en de organisatie van de controle instructies te verduidelijken door gebruik van verschillende kantlijnen; dergelijke "intanding" dient dan ook gebruikt te worden telkens ze mogelijk is. Computerprogramma's zijn beschikbaar om programma's automatisch in te tanden.
Een oordeelkundige keuze van de namen van de variabelen en modules kan enorm tot de leesbaarheid bijdragen. Voluit geschreven beschrijvende namen zijn te verkiezen boven korte, betekenisloze namen of dubbelzinnige afkortingen. Programmeertalen waarbij namen onbeperkt lang mogen zijn zullen algemeen toelaten duidelijkere programma's te maken dan andere talen waarbij de namen beperkt zijn tot 6, of zelfs soms tot 2 karakters.
Sommige programmeurs staan weigerachtig tegenover lange namen tengevolge van het meerwerk bij het intypen van programma's. Zij zouden zich moeten herinneren dat een programma een maal geschreven wordt, terwijl het tientallen, honderdtallen, of zelfs duizendtallen malen gelezen wordt.
1.4.2. Kommentaar.
Kommentaar is tekst die men aan een programma toevoegt om het programma duidelijker te maken, maar die niet door de computer verwerkt wordt.

Het effekt van een programma waaruit men alle kommentaar verwijderd heeft, moet hetzelfde zijn als dat van het oorspronkelijke programma.


Bij programmeertalen die geen behoorlijke structuratie en geen beschrijvende namen toelaten, is kommentaar de enige mogelijkheid om een beetje leesbaarheid in te voeren. Bij andere talen kan kommentaar aangewend worden om subtiele constructies te verklaren, of om richtlijnen te geven aan personen die het programma zouden willen wijzigen.
Het belangrijkste nadeel van kommentaar is verbonden aan het feit dat de computer kommentaar niet verwerkt: niets belet foutieve kommentaar, en niets verplicht een programmeur die een programma wijzigt ook het kommentaar te wijzigen.
Elk programma dat niet strikt voor eenmalig persoonlijk gebruik bestemd is, zou minimaal volgend kommentaar moeten bevatten:

1. Naam en adres van de auteur;

2. Copyright status;

3. Korte samenvatting van wat het programma doet, en hoe het moet gebruikt worden;

4. Historiek van alle wijzigingen, met overeenstemmende versie nummers.
Het is wenselijk dat het versie nummer niet alleen in het kommentaar zou te vinden zijn, maar ook zou voorkomen in alle geschreven dokumenten die door een programma geproduceerd worden. Dit om te voorkomen dat men naar de oorsprong van onverwachte resultaten zou zoeken in een verkeerde versie van het programma.
Opmerking:
Onervaren programmeurs hebben dikwijls de neiging kommentaar te gebruiken om te bewijzen dat zij de programmeertaal machtig zijn.

Teksten in de stijl:


A:=1; (* GEEF AAN A DE WAARDE 1 *)
zijn niet uitzonderlijk. Kommentaar moet niet alleen zeggen WAT men doet, maar ook WAAROM men het doet.
1.4.3. Externe dokumentatie.
Alle hulpmiddelen voor het specificeren en het ontwerpen van programma's kunnen uiteraard ook gebruikt worden als documentatie om informatiesystemen en programma's beter verstaanbaar te maken. Jammer genoeg heeft nog niet elke programmeur toegang tot programmeeromgevingen waarin men grafismen zoals programmastroomschema's vrij kan mengen met de tekst van programma's, met als gevolg dat de dokumentatie meestal los van het programma bewaard wordt, en dat bij programma aanpassingen, de dokumentatie meestal niet mee aangepast wordt. Dit potentieel gevaar moet echter niet als uitvlucht aangewend worden om geen dokumentatie aan een programma toe te voegen. De tekst van de specificaties waarvoor het programma ontworpen werd, de gebruikte algoritmen, programmastroomschema's met de algemene struktuur van het systeem en gegevensstroomschema's met de globale gegevensstromen zouden als een minimale onontbeerlijke documentatie moeten beschouwd worden.
1.5. Referenties.
Frederick P. Brooks,Jr.: The mythical man-month.

Addison Wesley, 1975.


Philip Gilbert: Software Design and Development.

Science Research Associates, 1983.


Harold J. Rood: Logic and structured design for computer programmers

PWS Publishers, Wadsworth, 1985.




J.Tiberghien - Informatica I - Afgedrukt op: 22/08/2016 -

Deel 2, Hoofdstuk 1, pag.







De database wordt beschermd door het auteursrecht ©opleid.info 2019
stuur bericht

    Hoofdpagina