Managed hosting door True

Software-ontwikkeling met componenten

Beheer is complex

 

Software zal zich steeds vaker voordoen als 'componentware': een verzameling samenwerkende componenten. Ontwikkeling van software wordt dan het samenstellen van componenten volgens een aantal bouwprincipes. Hiermee doen tevens nieuwe ontwerpkeuzen hun intrede, zo betoogt research consultant Denis Verhoef.

Al sinds de jaren zeventig denkt men na over de vraag hoe de kwaliteit van software te bepalen en vervolgens te verbeteren. Ook de vraag hoe de produktiviteit van IT-afdelingen vergroot kan worden, blijft actueel. De aandacht verschoof daarbij van methoden, technieken en computer aided software engineering (jaren tachtig) naar object-oriëntatie en client/server-architecturen (jaren negentig).
De markt van software-ontwikkeling is de laatste tijd voldoende veranderd om een nieuw onderzoek naar de stand van zaken te rechtvaardigen. Eind 1995 zagen de Tool Vision-onderzoeksresultaten het licht [1]. Vastgesteld werd hoe software-ontwikkelaars aankijken tegen (ontwikkelingen in) de markt en hoe specifieke ontwikkeltools gebruikt en beoordeeld worden. De basis van dit artikel bestaat uit een aantal gesignaleerde trends. Verder werden ervaringen uit een aantal projecten gebruikt om een visie op applicatie-ontwerp te presenteren, gebaseerd op ontwerpen met componenten.

Trends

Het Tool Vision-onderzoek toont aan dat veel software-ontwikkelaars hergebruik van bestaande ontwerpen en code steeds belangrijker gaan vinden. Zo'n 21 procent van de software-ontwikkelaars hergebruikt code. Meer dan de helft (54 procent) van de onderzochte groep software-ontwikkelaars verwacht dat in de toekomst te gaan doen. Voor bestaande ontwerpen liggen de percentages iets lager (13 procent nu, tegen 41 procent in de toekomst), maar ook hier is een sterk stijgende lijn waar te nemen.
Verder komt het gebruik van object-oriëntatie (oo) en client/server-technologie (c/s) naar voren als belangrijke trends. Steeds meer organisaties schaffen specifieke tools aan en maken gebruik van gerichte oo- en c/s-ontwikkelaanpakken. 56 Procent van de onderzochte doelgroep zegt dat c/s-technologie een strategische keuze voor de organisatie is (geweest), 24 procent heeft een oo-aanpak als strategische keuze omarmd. Ook hier liggen de percentages voor de toekomst beduidend hoger: client/server scoort dan 81 procent, object-oriëntatie 64 procent.
Deze trends worden - uiteraard - weerspiegeld in de manier waarop leveranciers hun software-ontwikkeltools profileren, met namen als Quick -, Power -, Smart - en Visual Objects. De voordelen die in de folders genoemd worden zijn velerlei: snel kunnen inspelen op veranderingen in bedrijfsprocessen, hogere betrouwbaarheid door hergebruik van bewezen componenten en vlot kunnen traceren van de consequenties van codeveranderingen met als resultaat kwaliteits- en produktiviteitswinst. Het ontwerpen en bouwen van software betekent steeds meer het bouwen, assembleren en 'customisen' van een aantal componenten. Overigens worden vaak ook termen als bouwblok, object en bouwsteen gehanteerd, min of meer als synoniem voor component.
Wat daarbij precies onder componenten wordt verstaan, of onder assembleren en 'customisen', is niet altijd even duidelijk. Men kan veel verschillende vragen stellen om het begrip 'component' af te bakenen; niet iedere vraag is voor iedereen even belangrijk.
Is een component altijd een stuk code, of is een stuk code één van de verschijningsvormen in een ontwikkelfase van een component? Kan een deel van een ontwerp dus ook een component zijn?
Hebben componenten een bepaalde minimale of maximale grootte? Is een radiobutton nog een component, is een complex gestructureerde en omvangrijke gegevensverzameling nog een component?
Kan een component aan een bepaalde ontwikkeltechnologie gebonden zijn (een Access-form, een Smalltalk-library, een Oracle-tabel) of juist niet (de functionaliteit van een spelling-checker)?
Kan een functie die een aangeboden getal met drie kan vermenigvuldigen als component worden aangemerkt? Is het abstracte datatype 'integer' met zijn operaties niet een veel beter voorbeeld van een component?
Is een component altijd onder te brengen in een gelaagde software-architectuur en is dus iedere component �f een datacomponent �f een functiecomponent �f een gebruikers-interface-component? Of is dat een onnodige inperking?
Veel vragen, veel meningen en daarmee een leeg begrip.

Het begrip 'component'

In dit artikel willen we eerst het begrip component handen en voeten geven. In principe laten we ons daarbij door bovenstaande vragen zo weinig mogelijk beperken. Software-ontwikkelafdelingen moeten zelf de vrijheid hebben om uit te maken welke beperkingen zij willen opleggen aan hun ontwikkelprocessen, gegeven de wensen en technologie bij hun klanten en bij zichzelf.
Wanneer we inhoud geven aan het begrip 'component,' baseren we ons op een model van componenten dat in samenwerking met de KU Nijmegen is ontwikkeld ten behoeve van het Ministerie van OCW [2]. Na een preciezere definiëring van het begrip component wordt ingegaan op de complexiteit van componenten en van het beheren ervan, op de flexibiliteit en op de distributie van componenten. Methodische en organisatorische consequenties als het inrichten van component-ontwikkelteams en het invoeren van beloningsstructuren voor hergebruikers of voor de bouwer van de meest hergebruikte component laten we hier buiten beschouwing. Ook hierop wordt in referentie [2] uitgebreider ingegaan.
Een eerste, tentatieve, definitie van component is: een bepaalde samenhangende en af te bakenen functionaliteit. Deze eerste definitie is breed. Ze is duidelijk geïnspireerd door de modularisatieprincipes flexibiliteit (ontkoppeling tussen componenten) en zelfstandigheid (samenhang binnen componenten). Het basismodel van componenten is op deze definitie gebaseerd. De geboden functionaliteit is in dit model terug te vinden als de verzameling van request types die de component kan afhandelen. Voor ieder van deze diensten is soms aanvullende informatie nodig. Hiertoe heeft een component een aantal input-parameters. Veel 'request types' zullen tot een resultaat leiden in de vorm van het toekennen van een waarde aan één of meer output-parameters.
De eenvoud en dus de kracht van dit basismodel kan worden geïllustreerd aan de hand van een aantal voorbeelden.
Het eerste voorbeeld beschrijft een component die een aangeboden getal met 3 kan vermenigvuldigen. Het toekennen van een waarde aan de input-parameter - een getal van het type 'integer' - leidt altijd tot de toekenning van een waarde aan de output-parameter 'resultaat', ook van het type 'integer'.
Een ander voorbeeld betreft spellingscontrole, zie figuur 1. De functionaliteit van deze component bestaat uit drie 'request types'. 'Check' controleert de spelling van een aangeboden woord en retourneert een booleanwaarde. 'Geef Alternatieven' resulteert in een lijst van sterk gelijkende woorden en 'Voeg Toe' zorgt ervoor dat de interne woordenlijst van deze component met het aangeboden woord wordt uitgebreid.
Het laatste voorbeeld betreft de component 'window-klasse', met een groot aantal request-types. 'Resize', 'drag', 'minimize', 'close', 'plaats tekst' en 'geef kleur' bewerken allemaal een bepaald venster op de desktop. De input-parameter 'in-win' legt vast welk venster (window) het betreft. Deze parameter is dus een specifieke instantie van de window-klasse. Het request-type 'create' heeft geen enkele invoerwaarde nodig maar leidt tot de creatie van een nieuwe instantie van window-klasse' die aan de output-parameter 'uit-win' wordt toegekend. Dit voorbeeld laat zien dat sommige 'request-types' een specifieke (en benoemde) instantie van de component window-klasse' betreffen, maar dat andere ('create') de window-klasse zelf betreffen.
Uiteraard zijn er vele andere voorbeelden denkbaar, variërend van sorteerroutines, complexe rapportagemodules en geavanceerde generieke bouwstenen waarbij ook de typering van parameters zelf als een parameter te beschouwen is.

Bouwen met componenten

Dit stekkermodel van componenten biedt een goed uitgangspunt om verschillende manieren van samenstellen van componenten te beschrijven. We onderkennen drie verschillende bouwprincipes: instantiatie, concatenatie en aggregatie. Instantiatie (ook wel customising of parameterisatie genoemd) komt neer op het vaststellen van een bepaalde input-parameter op een bepaalde waarde. In het voorbeeld van de window-klasse leidt het vastzetten van de input-parameter 'in-win' op de waarde win1 tot een component die overeenkomt met een specifieke window-instantie. Een printmodule waarbij de parameter kleur wordt vastgezet op de waarde 'z/w' leidt tot een (specifiekere) zwart-wit-printer. Instantiatie leidt dus tot een specifiekere component.
Concatenatie is het koppelen van een aantal componenten op basis van data-afhankelijkheden. De output-parameter van de ene component wordt als het ware gekoppeld aan de input-parameter van een andere component. Zo ontstaat een schakelschema van componenten om een complexere functionaliteit te realiseren. Bij concatenatie moet precies gespecificeerd worden hoe de afzonderlijke stekkers op elkaar aansluiten. Het 'piping'-mechanisme van Unix is een goed voorbeeld van een (lineaire) concatenatie van componenten.
Het derde bouwprincipe - aggregatie - is vergelijkbaar met if-then-else- of case-statements, waarbij op basis van de evaluatie van een bepaalde voorwaarde een bepaalde subcomponent wordt gekozen. Het gebruik van deze drie bouwprincipes wordt toegelicht aan de hand van een voorbeeld: het bouwen van een stopwatch met gebruikmaking van twee basiscomponenten, zie figuur 2.
De ene basiscomponent is een geheugenmanager voor getallen, die een 'read' en een 'write' biedt en getallen kan wegschrijven en uitlezen. De andere basiscomponent is het datatype 'integer'. Deze component biedt twee 'request'-types, namelijk 'zero' en 'incr'. 'Zero' leidt tot de toekenning van het getal 0 aan de output-parameter resultaat, 'incr' leidt tot de ophoging van een aangeboden waarde (input-parameter 'een-getal').
De complexe component 'stopwatch' biedt drie request-types: 'display' (het uitlezen van de stopwatch), 'reset' (het weer starten van de stopwatch) en 'count' (het ophogen van de stopwatch-waarde met één). Figuur 2 toont dat de stopwatch te zien is als de aggregatie van drie subcomponenten. De keuze van de subcomponent hangt af van het request-type. Bij request-type 'display' wordt de stopwatch-waarde uitgelezen. Hiervoor wordt een instantiatie van de geheugenmanager gebruikt. Het request-type van de geheugenmanager is vastgezet op 'read' en de in te lezen variabele van de geheugenmanager is vastgezet op de stopwatch-waarde 'n'. De twee andere request-types, 'reset' en 'count', gebruiken een concatenatie van componenten. Bij de 'reset' zijn twee componenten gekoppeld: 0 (een instantiatie van integer op request-type 'zero') en write(n) (een instantiatie van de geheugenmanager). De 'count' gebruikt een concatenatie van drie componenten.

Complexiteit

Hiermee is een algemeen model verkregen voor (het bouwen met) componenten. Het voorbeeld van de stopwatch demonstreert dat componenten een complexe samenstelling kunnen zijn van elementaire componenten. Veel applicatiedomeinen zijn van nature complex en dan is het ontwerp van een bevredigende set componenten die de structuur van het applicatiedomein weergeeft cruciaal. In zulke gevallen is ook het beheer van zo'n set componenten geen eenvoudige opgave, omdat ook de opbouw van componenten uit andere componenten vastgelegd moet worden.
Software-architecturen dragen bij aan de beheersbaarheid van een ontwerp en implementatie. Een voorbeeld van een software-architectuur is het n-lagenmodel van de Gartner Group. Vaak wordt dit gehanteerd voor het onderkennen van scenario's voor partitionering van een systeem over client- en server-componenten. Ook voor logisch software-ontwerp is het nuttig om een opbouw te kiezen van een systeem in een aantal lagen [6]. Een voorbeeld van lagen (van beneden naar boven) in een software-architectuur is het volgende:
- De gegevensbeheer-laag: deze betreft de data;
- De data-I/O-logica-laag is gericht op datamanipulatie. Implementaties van componenten uit deze laag als SQL-select statements of opgeslagen procedures zijn goed denkbaar;
- De bedrijfsregels-laag dekt de applicatielogica af;
- De flow control-laag is gericht op volgorden van aanroep van bedrijfs-objecten uit de onderliggende laag en is te zien als werkstroom-functionaliteit;
- Gebruikers-I/O-logica betreft scherm-navigatie en verschillende vormen van controle op ingevoerde data zoals elementaire data-type-checking of range-checking;
- Presentatiebeheer betreft de wijze van presenteren aan de gebruiker.
Het maken van een goede keuze voor een architectuur is belangrijk en bepaalt het ontwerp van een applicatie.
Vaak is de complexiteit gelegen in de databeheer-laag en de data-I/O-logica-laag. Typische voorbeelden van applicatiedomeinen met complex gestructureerde componenten in deze lagen zijn cad/cam (complexe ontwerpschema's), documentaire informatiesystemen (complex opgezette documenten) en repository-bouw (complexe repository-structuren). Andere voorbeelden zijn geografische informatiesystemen (abstracte datatypen) en multimedia-toepassingen (Blob's).
Bepaalde constellaties van componenten komen vaak voor. In kringen van oo-ontwikkeling bestaat veel aandacht voor ontwerppatronen die voor bepaalde probleemtypen min of meer standaardoplossingen in de vorm van patronen aanbieden. Zie hiervoor de uitgebreide catalogus van ontwerppatronen in het werk van Gamma en anderen [7]. Florijn en van Elswijk [8] duiden op interessant onderzoek: het maken van ontwerphulpmiddelen voor oo-ontwerppatronen, waarbij de oplossingsstructuur van een ontwerppatroon kan worden afgebeeld op concrete klassen, liefst in verschillende programmeertalen.
De verschillende manieren van het opbouwen of constelleren van componenten is één van de redenen waarom ook het beheer ervan complex is. Tegelijkertijd is een goede inrichting van het beheer van een verzameling componenten essentieel om hergebruik te realiseren. Al in 1987 formuleerde de hergebruik-goeroe Prieto-Diaz dit als volgt: 'To reuse a software component, you first have to find it'. Referentie [1] biedt aanwijzingen voor het ontsluiten van informatie over componenten.

Vijf dimensies

De complexiteit van componentbeheer wordt toegelicht aan de hand van het model dat binnen Philips Research is ontwikkeld voor het beheer van gegevens in ontwerpomgevingen in het algemeen [3]. Dit model leent zich ook voor gegevensbeheer bij software-ontwerp. Kern van het model is dat componentenbeheer vijf orthogonale dimensies bevat: versie, 'view', configuratie, status en variant.
- Ontwerpers passen componenten in de loop van de tijd in verschillende ontwerpstappen aan, waardoor een component verschillende versies kan hebben. Het is belangrijk te weten welke versie van welke component aanwezig is en waar die versie gebruikt wordt.
- Veel componenten zijn te complex om ze op maar één manier te representeren en dus worden vaak verschillende views beschreven van één en dezelfde component. Views van een component kunnen soms automatisch in andere 'views' worden omgezet (formaatconversie, compilatie).
- Zoals we al eerder zagen, kunnen componenten uit andere componenten samengesteld zijn; daarom moet de configuratie (samenstelling) van componenten beheerd worden. We hebben hiertoe drie verschillende bouwmechanismen geïntroduceerd. Bij nieuwbouwtrajecten is de keus van geschikte componenten van belang om daarmee grotere componenten te kunnen bouwen. Zeer actueel is de omgekeerde benadering: het modulariseren van bestaande software in kleinere componenten ten behoeve van software-renovatietrajecten.
- Vanuit de organisatie van software-ontwikkeling speelt ook de status van componenten een rol bij beheer. Voorbeelden van een status - afhankelijk van de inrichting van het software-ontwikkeltraject - zijn 'schets', 'ongetest' en 'geschikt voor gebruik'.
- Ten slotte kunnen er verschillende varianten van een component bestaan, bijvoorbeeld voor verschillende gebruikers-interface-standaarden of voor verschillende besturingssystemen.
Een ontwerpvraag bij het inrichten van een componentbeheersomgeving is de manier van identificeren van een component. Vrij naar een stelling van Ter Hofstede [5]: 'Identificatie is een sleutelbegrip in component modelling'.
Het is bij het assembleren en 'customisen' van software op basis van componenten een belangrijke afweging welke complexiteit benodigd is en of dat haalbaar is in tijd en geld.

Flexibiliteit

De flexibiliteit van een systeem komt overeen met de onderhoudsinspanning die nodig is bij veranderingen in zijn omgeving. Dat kan zijn de wijziging van een rentepercentage, de invoering van een nieuw produkt of een nieuwe set rekenregels voor het uitrekenen van subsidies of belastingen. De problemen rond 'het jaar 2000' en 'de Euro' zijn inmiddels maar al te bekende consequenties van inflexibel opgezette software. Vaak is abstractie de oplossing: beschouw het rekenpercentage, het produkt of de set rekenregels als een in te stellen parameter van het systeem, in plaats van alles hard te coderen wat met het huidige percentage of het huidige produkt samenhangt. Flexibiliteit hangt dus direct samen met het eerder geïntroduceerde instantiatiemechanisme. Het voorbeeld van het gebruik van een set rekenregels als parameter om in te spelen op de regelmatig wijzigende wetgeving is overigens bepaald niet fictief: de Utopics-bouwstenenarchitectuur - genomineerd voor de Sun/Computable IT-award 1996 - kenmerkt zich door deze vorm van flexibiliteit.
Uiteraard is hard coderen of het presenteren van een vrijheidsgraad een ontwerpkeuze. Het spectrum kent twee extremen: volledig maatwerk aan de ene kant (alle aandacht voor een hard gecodeerde systeemstructuur, weinig systeeminhoud) en shells als dbms'en en case-produkten aan de andere kant (weinig systeemstructuur, veel systeeminhoud). In extremo kan flexibel ontwerpen leiden tot een onderliggende gegevensstructuur, zoals is weergegeven in figuur 3. Deze structuur is inderdaad voor veel domeinen van toepassing, maar vereist bijzonder veel invulwerk, als parameters van een waarde voorzien moeten worden.
De voordelen van een flexibele systeemopzet zijn duidelijk: een lage onderhoudslast en een grote bestendigheid. Tegenover de voordelen staan ook nadelen. In het algemeen leidt een flexibelere (en daarmee abstractere) systeemopzet tot een steile leercurve voor de gebruikers. In het extreme geval wordt de eindgebruiker zelf programmeur omdat hij de hele systeemvulling nog moet regelen en bedolven wordt onder een vloed van in te stellen parameters. Eigenlijk treedt hier natuurlijk de wet van behoud van ontwerplast op: de systeeminhoud moet mee-ontworpen worden. In zijn lezenswaardige rubriek in Database Magazine [5] presenteert René Veldwijk een anekdotische casus waarbij de noodzaak tot een eenvoudige expressieparser uiteindelijk leidde tot de bouw van een complete C-compiler in Cobol. Hoe flexibel en generiek software wordt ontwikkeld is een kwestie van afweging tussen de voor- en nadelen.
Nieuwe generaties client/server-ontwikkelomgevingen ondersteunen een andere vorm van flexibiliteit, waarbij de systeempartitionering ontkoppeld wordt van het systeemontwerp. De vraag welke component waar draait, wordt dus los gezien van de vraag uit welke componenten het systeem eigenlijk bestaat. Idealiter zou men van ieder codesegment dat kandidaat is om als zelfstandige component beschouwd te worden een aantal segmentkarakteristieken moeten kunnen vaststellen. Te denken valt aan: hoe rekenintensief is deze kandidaatcomponent, is er sprake van multi-user-gebruik, is grafische presentatie een onderdeel? Op basis van een aantal in te stellen parameters (zoals het aantal systeemgebruikers en de gewenste responstijd) en op basis van de karakteristieken van de kandidaatcomponenten vindt dan de uiteindelijke systeempartitionering plaats. Vervolgens wordt een keuze gemaakt voor de componenten en de platforms waarop ze draaien.

Distributie

Naast de beslissing welke componenten ontwikkeld moeten worden, hoe complex ze moeten en kunnen zijn en hoe generiek ze opgezet moeten en kunnen worden, spelen er ook diverse distributiegerelateerde vraagstukken. Welke componenten willen we zelf maken? Welke kunnen we uit een publiek domein halen (bijvoorbeeld via het Internet), en welke zelf-ontwikkelde componenten stellen we als ontwikkelorganisatie zelf publiekelijk beschikbaar?
Door de huidige middleware-ontwikkelingen beginnen technologische barrières voor het hergebruiken van componenten - zoals de taal, de netwerklocatie, het besturingssysteem of het dbms - steeds meer weg te vallen. Weerstanden tegen hergebruik zullen dus in toenemende mate cultureel bepaald zijn. Vanuit de ontwikkelorganisatie wordt het belangrijk om 'not invented here' niet als syndroom te beschouwen maar als voordeel te exploiteren. Algemene componenten zullen via search engines op het net te vinden zijn. Denk bijvoorbeeld aan sorteerroutines, communicatie-interfaces, gui-objecten en routines om de datum te verifiëren. Ook intercompany-componenten zullen publiekelijk en grootschalig beschikbaar gesteld moeten worden. In de ideale situatie kan telebankieren in eigen applicaties worden ingebed, is actuele koersinformatie te benutten en kunnen klantregistratiesystemen van organisaties in één logistieke keten geïntegreerd worden. Verder worden systemen voor naleving van wet- en regelgeving per land publiek gemaakt en kunnen controlesystemen voor kredietwaardigheid benut worden. Anders gezegd: een deel van de repository verschuift naar het Internet, en repositories bevatten binnen de eigen organisatie alleen nog die componenten die bedrijfseigen zijn en een directe toegevoegde waarde leveren aan de eigen bedrijfsprocessen.
 
Dr ir T.F. (Denis) Verhoef is research consultant bij het IT-innovatiebureau ID Research te Leusden.
e-mail DVerhoef@idr.nl.

Literatuur

[1] D. Verhoef, E. van der Winden: ToolVision: nationaal onderzoek software-ontwikkeltools. ID Research, Leusden, 1995.
 
[2] D. Verhoef, T. van der Weide: Systeemontwikkeling met bouwstenen, een ideaal in de praktijk. Informatie, Kluwer Bedrijfswetenschappen, Deventer (juni 1996).
 
[3] P. van den Hamer: CAD Frameworks and Design Data Management. Philips Research Laboratories.
 
[4] A.H.M. ter Hofstede: Information Modelling in Data Intensive Domains, dissertatie Katholieke Universiteit Nijmegen, 1993.
 
[5] R. Veldwijk: Tien geboden voor beter database-ontwerp: 10. Gij zult kritisch staan tegenover adviezen van goeroe's. Database Magazine (december 1995) p. 88.
 
[6] Gartner Group: Three-Tier Computing Architectures and Beyond, Note R-401-134 (25.08.1995).
 
[7] E. Gamma, R. Helm, R. Johnson en J. Vlissides: Design Patterns, Elements of reusable object-oriented software. Addison-Wesley, Reading, Massachusetts, 1995.
 
[8] G. Florijn, M. van Elswijk: OO-ontwerptrend: Design Patterns. Kluwer Bedrijfswetenschappen, Deventer, Informatie (april 1996) pp. 22-26.

Dit artikel is afkomstig van Computable.nl (https://www.computable.nl/artikel/1329469). © Jaarbeurs IT Media.

?


Lees meer over


 

Stuur door

Stuur dit artikel door

Je naam ontbreekt
Je e-mailadres ontbreekt
De naam van de ontvanger ontbreekt
Het e-mailadres van de ontvanger ontbreekt

×
×
Wilt u dagelijks op de hoogte worden gehouden van het laatste ict-nieuws, achtergronden en opinie?
Abonneer uzelf op onze gratis nieuwsbrief.