RTP Real-Time Programmatuur hoofdstuk 4: het beheersen van complexiteit: programming in the large Yolande Berbers Programmatuur voor real-time controle slide 1 RTP karakteristieken van een RTS (copie van slide van H1) groot en complex niet gewoon proportioneel met het aantal lijnen code, wel aan de variëteit die in de code voorkomt verandert continu omdat de omgeving continu verandert kan variëren van enkele honderden lijnen assembler of C tot 20 miljoen lijnen Ada-code (geschat voor het ruimtestation Freedom) Yolande Berbers Programmatuur voor real-time controle slide 2 RTP decompositie en abstractie decompositie “verdeel en heers”-principe systematisch opsplitsen van een complex probleem in kleinere en kleinere entiteiten totdat componenten geïsoleerd kunnen worden die begrepen en opgelost kunnen worden door individuen of kleine groepen top down ontwerp abstractie geeft de mogelijkheid om details van componenten naar een latere fase te verschuiven en om de essentie van componenten te specifiëren bottom up ontwerp Yolande Berbers Programmatuur voor real-time controle slide 3 RTP evolutie in programmeertechnieken procedurele programmering modules voor informatieverberging data abstractie object georiënteerde programmering Yolande Berbers Programmatuur voor real-time controle slide 4 RTP kenmerken van programmeertechnieken procedurale programmering centraal aandachtspunt: gegevensstructuren en procedures die hierop werken programmeringsparadigma: kies gegevensstructuren, procedures en algoritmen taal ondersteuning: procedures, functies, parameters vb: Fortran77, Algol, Pascal, C grootste probleem: bereik en zichtbaarheid van gegevensstructuren Yolande Berbers Programmatuur voor real-time controle slide 5 RTP kenmerken van programmeertechnieken gegevensverberging (information hiding) centraal aandachtspunt: module (gegevens + operaties op deze gegevens) programmeringsparadigma: kies goede modules taal ondersteuning: ondersteuning voor modules vb: Ada, Modula2 en in zekere opzichte C grootste probleem: een module kan niet meerdere keren geïnstantieerd worden (een module voor een lijst implementeert één lijst) Yolande Berbers Programmatuur voor real-time controle slide 6 RTP kenmerken van programmeertechnieken data abstractie centraal aandachtspunt: modules worden types synoniemen: abstracte gegevenstypes, gebruikersgedefinieerde types, klassen waarvan variabelen (objecten) geïnstantieerd worden programmeringsparadigma: kies de types; voorzie deze van operaties vb: Ada, C++, Java Yolande Berbers Programmatuur voor real-time controle slide 7 RTP kenmerken van programmeertechnieken data abstractie (vervolg) taal ondersteuning: alle mechanismen die toelaten om types door een gebruiker gedefinieerd op dezelfde manier te gebruiken als ingebouwde types mechanismen voor het creëren (en vernietigen) van objecten mechanismen voor het initialiseren van objecten objecten gebruikt als parameters, als functieresultaat toekenningen, vergelijkingen, overladen van operatoren ... grootste probleem: het is niet mogelijk om een bestaand type aan te passen Yolande Berbers Programmatuur voor real-time controle slide 8 RTP kenmerken van programmeertechnieken object-georiënteerde programmering centraal aandachtspunt definieer basisklassen en algemene eigenschappen door over-erving (inheritance) andere klassen afleiden programmeringsparadigma kies goede klassen met goede operaties maak gemeenschappelijke dingen expliciet door over-erving taal ondersteuning klassenmechanismen met over-erving polymorfisme: operatie hangt af v dynamisch type parameter vb: Simula67, Smalltalk-80, C++, Eifel, Ada95, Java Yolande Berbers Programmatuur voor real-time controle slide 9 RTP modules informele definitie van module verzameling logisch samenhangende objecten en operaties encapsulatie een wel bepaalde functie isoleren in een module, en een precieze specificatie maken voor de interface modules geven ondersteuning voor gegevensverberging aparte compilatie abstracte gegevenstypes C: zeer zwakke ondersteuning voor modules Ada en Java: expliciete ondersteuning via packages C++ : dynamische ondersteuning voor modules Yolande Berbers Programmatuur voor real-time controle slide 10 RTP gegevensverberging Pascal (en andere eenvoudige programmeertalen): globale declaraties van een variabele die door meerdere procedures gedeeld wordt een variabele die gebruikt wordt bij elke oproep van een bepaalde procedure nadelen gevoelig aan fouten (bv gebruik van globale variabele daar waar het niet mag) moeilijk onderhoudbaar: slecht zicht op wat bij elkaar hoort stroeve ontwikkelingsmogelijkheden: iets wijzigen aan de globale variabelen vraagt de hercompilatie van heel de code Yolande Berbers Programmatuur voor real-time controle slide 11 RTP gegevensverberging een module structuur zorgt voor beperkte zichtbaarheid door de mogelijkheid te bieden om gegevens te verbergen in ‘lichaam’ van de module biedt een manier om de toegang tot de variabelen van de module te controleren voorbeeld: implementatie van een dynamische FIFO-queue interface: 3 routines toevoegen van een element weghalen van een element testen op het leeg zijn van de queue interne gegevens (bv pointer naar de queue) mogen niet zichtbaar zijn buiten de module Yolande Berbers Programmatuur voor real-time controle slide 12 RTP gegevensverberging: package in Ada package heeft twee delen specificatie interface: dit is zichtbaar er buiten lichaam: dit is de implementatie, is onzichtbaar er buiten het lichaam bevat een initialisatie-deel beide moeten in hetzelfde declaratieve deel staan er mag wel iets tussen staan bv spec. pack. A, spec. pack. B, lichaam pack. A, lichaam pack. B op deze manier kunnen A en B elkaar oproepen routines (en ge-exporteerde variabelen) kunnen bereikt worden via naam_package.naam_routine implementatie van slechts één instantie van de queue de queue wordt gecreëerd in het initialisatie-deel Yolande Berbers Programmatuur voor real-time controle slide 13 RTP gegevensverberging: package in Ada specificatie interface: deze entiteiten zijn zichtbaar er buiten package Queuemod is function Empty return Boolean; procedure Insert (E: Element); -- Element moet zichtbaar zijn procedure Remove (E: out Element); end Queuemod; voorbeeld van oproep: lichaam : dit is de implementatie, zie volgende slide Yolande Berbers Queuemod.Insert (El); Programmatuur voor real-time controle slide 14 RTP gegevensverberging: gegevensverberging: package in Ada package in Ada (vervolg) packagebody Queuemod is type ... Q: Queue_Ptr_T; procedure Create is begin ... end Create; function Empty return Boolean is begin ... end Empty; procedure Insert (E: Element) is begin ... end Insert; procedure Remove (E: out Element) is begin ... end Remove; begin Create; end Queuemod; Yolande Berbers Programmatuur voor real-time controle slide 15 RTP gegevensverberging: package in Ada use: om de naamgeving niet te zwaar te maken wanneer veel elementen uit een package gebruikt worden naam_package.naam_routine wordt naam_routine declare use Queuemod; begin if not Empty then Remove (E); end if; end; Yolande Berbers Programmatuur voor real-time controle slide 16 RTP gegevensverberging in C C: geen taalconstructies voor gegevensverberging modules kunnen nagebootst worden door code in verschillende bestanden te plaatsen per module een ‘header-file’, deze eindigt op ‘.h’ per module een ‘body-file’, deze eindigt op ‘.c’ het header-bestand wordt ingelast in het .c-bestand geen formele relatie tussen deze bestanden, alleen naamconventie nadelen: geen initialisatie-deel (initialisatie zal ergens expliciet moeten staan) minder testen door de compiler zijn mogelijk bv geen test op volledigheid specificatie tov lichaam en omgekeerd: het ontbreken van een routine wordt slechts opgemerkt bij het linken Yolande Berbers Programmatuur voor real-time controle slide 17 RTP gegevensverberging in C header-bestand (.h bestand): dit bestand definieert de functionele interface van de module int Empty(); void insertE (element E); void removeE (element *E); dit header-bestand moet ingelast worden in elk bestand dat van de module wenst gebruik te maken (via #include-instructie) implementatie staat in een .c bestand, zie volgende slide Yolande Berbers Programmatuur voor real-time controle slide 18 RTP gegevensverberging in C gegevensverberging in C (vervolg) #include “queuemod.h” struct ... void create() { ... } int empty() { ... } void insertE (element E) { ... } void removeE (element *E) { ... } Yolande Berbers Programmatuur voor real-time controle slide 19 RTP gegevensverberging in C queuemod.h int Empty(); void insertE (element E); void removeE (element *E); queuemod.c #include “queuemod.h” put_in.c #include “queuemod.h” take_out.c #include “queuemod.h” …. …. …. int empty() { ... } void insertE (element E) { ... } element E1, E2; insertE(E1); insertE(E2); element E3; if !empty() removeE(&E3) …. …. …. Yolande Berbers Programmatuur voor real-time controle slide 20 RTP tekortkomingen van modules modules zijn geen eerste-klas-taalelementen moduletypes kunnen niet gemaakt worden je kunt geen verschillende instanties van module creëren je kunt geen pointer naar een module laten wijzen Yolande Berbers Programmatuur voor real-time controle slide 21 RTP aparte compilatie voordelen van het apart compileren van modules een module kan geschreven en getest worden, onafhankelijk van rest van programma eens getest kan de module in een bibliotheek geplaatst worden, eventueel reeds gecompileerd aparte compilatie ondersteunt projectbeheer voordeel dat niet alles telkens gehercompileerd moet worden (dat geldt natuurlijk vooral voor ‘programming in the large’) aparte compilatie ondersteunt bottom-up ontwerp vooral bottom-up ontwerp van specificaties is interessant Yolande Berbers Programmatuur voor real-time controle slide 22 RTP aparte compilatie in C queuemod.h int Empty(); void insertE (element E); void removeE (element *E); queuemod.c #include “queuemod.h” put_in.c #include “queuemod.h” take_out.c #include “queuemod.h” …. …. …. int empty() { ... } void insertE (element E) { ... } element E1, E2; insertE(E1); insertE(E2); element E3; if !empty() removeE(&E3) …. …. …. Yolande Berbers Programmatuur voor real-time controle slide 23 RTP aparte compilatie in Ada with-constructie: gebruik van een package uit bibliotheek (een beetje te vergelijken met #include van C) een with-constructie kan in een andere package staan: zo ontstaat een hiërarchie van modules vb: module Dispatcher maakt gebruik van module Queuemod package Dispatcher is ... -- nieuwe zichtbare entiteiten end Dispatcher; with Queuemod; package body Dispatcher is ... -- verborgen entiteiten end Dispatcher; Yolande Berbers Programmatuur voor real-time controle slide 24 RTP aparte compilatie in Ada voordelen specificatie en lichaam zijn expliciet in de bibliotheek bibliotheek is deel van Ada-omgeving met tools specificatie kan geschreven worden vóór het lichaam logische consistentie kan reeds door compiler getest worden specificatie kan geschreven worden door project-leiders Yolande Berbers specificatie is een deel van ontwerpen uitwerken van specificatie is vaak programming in the small fout in specificatie heeft grotere gevolgen dan fout in lichaam: alle modules die de specificatie gebruiken moeten eventueel gewijzigd worden (bij fout in een lichaam: enkel dit lichaam hercompileren) Programmatuur voor real-time controle slide 25 RTP aparte compilatie Ada aparte compilatie is deel van de taal bibliotheekomgeving is deel van taal consistentie van specificaties en types gebeurt over bibliotheekeenheden C aparte compilatie is geen deel van taal C-bestand worden apart gecompileerd: object modules object modules worden gelinked bij het linken wordt niet gechecked op specificatieconsistentie en types Yolande Berbers Programmatuur voor real-time controle slide 26 RTP abstracte gegevenstypes uitbreiding van idee dat gebruikers van een type niets hoeven te weten van de precieze voorstellingskeuze van dit type (bv lijst, enkel of dubbel gelinkt, circulair of niet, ..) lost één van de tekortkomingen van modules op ADT (abstract data type) = module dat een type definieert type bepaalt: objecten en operaties definitie van een type impliceert dat er variabelen van dit type kunnen gedeclareerd worden een creatie-routine is hier absoluut noodzakelijk alle OO-talen bieden dit (dus ook Java) Yolande Berbers Programmatuur voor real-time controle slide 27 RTP abstracte gegevenstypes extra moeilijkheid wanneer gecombineerd met aparte compilatie normaal wensen we dat de interne voorstelling van het type verborgen wordt, zich dus in het lichaam bevindt module dat gebruik maakt van een ADT moet het volgende kennen: de operaties (= specificatie, de interface) de grootte van het ADT (dit is nodig voor de compilatie van de gebruikmakende module) mogelijke oplossing: gebruik van een indirectie altijd een pointer gebruiken naar het ADT: een pointer heeft een vaste grootte (vaak gebruikt in C) in Ada: interne voorstelling wordt bij specificatie gevoegd als limited private als private (dan zijn ook toekenning en vgl mogelijk) Yolande Berbers Programmatuur voor real-time controle slide 28 RTP abstracte gegevenstypes in C voorbeeld van gebruik van indirectie in C: als extra parameter wordt hier nu altijd een pointer naar het object gebruikt int empty(queue_ptr_t Q); void insertE (queue_ptr_t Q, element E); void removeE (queue_ptr_t Q, element *E); Yolande Berbers Programmatuur voor real-time controle slide 29 RTP abstracte abstractegegevenstypes gegevenstypesin inAda Ada package Complex_Arithmetic is type Complex is private; function ”+” (X, Y: Complex) return Complex; function ”-” (X, Y: Complex) return Complex; function Comp (A, B: Float) return Complex; function Real_Part (X: Complex) return Float; private type Complex is record Real_Part: Float; Imag_Part: Float; end record; end Complex_Arithmetic; Yolande Berbers Programmatuur voor real-time controle slide 30 RTP abstracte gegevenstypes in Ada with Complex_Arithmetic; use Complex_Arithmetic; …. C1, C2, C3: Complex; A, B: float; …. C2 := Comp(A, B); C3 := C1 + C2; if C1 = C2 then …. end if; …. Yolande Berbers Programmatuur voor real-time controle slide 31 RTP object-georiënteerd programmeren verder uitbreiding van ADT (variabelen van de ADT worden objecten genoemd) 4 extra kenmerken uitbreidbaarheid van type (over-erving) automatische initialisatie van objecten (constructors) automatische destructie van objecten (destructors) soort operatie wordt pas bij uitvoering bepaald (polymorfisme) probleem bij real-time programma's: polymorfisme maakt het niet mogelijk om via de code te weten welke operatie opgeroepen zal worden: moeilijk om nodige tijd te schatten ondersteund in Ada en Java Ada: object-oriëntatie van Ada zullen we niet gebruiken in deze cursus Java: zie MI, IPS of POO Yolande Berbers Programmatuur voor real-time controle slide 32 RTP OOP en Java sleutelwoord extends geeft aan dat een klasse van een andere is afgeleid public class Coordinate { .. } // voor 2-dimensionaal werken public class ThreeDimension extends Coordinate { … } // voor 3-dimensies nieuwe velden kunnen toegevoegd worden extra operaties kunnen gedefinieerd worden bestaande operaties kunnen ge-herdefinieerd worden, en mogen in hun definitie gebruik maken van oorspronkelijke operatie abstracte klasse hier kunnen geen objecten van gedeclareerd worden moet via over-erving concreet gemaakt worden finale klasse hiervan kan men niet over-erven Yolande Berbers Programmatuur voor real-time controle slide 33 RTP herbruikbaarheid herbruikbaarheid is veelbelovend voor softwareproductie, maar niet zo eenvoudig overerving is een goed middel ander middel: een sjabloon type is generisch en wordt pas bepaald bij instantiatie uitwerking in Ada, C++ en Java generic modules in Ada template in C++ interfaces in Java: werkt iets anders (zie volgende slides) componenten kunnen geïnstantieerd worden van een sjabloon voorbeeld: een ADT dat een queue van elementen beheert, het type van de elementen wordt in het sjabloon nog niet bepaald Yolande Berbers Programmatuur voor real-time controle slide 34 RTP Java: interfaces interfaces om relaties te leggen buiten klasse-hierarchie zijn altijd abstract: geen declaratie van instanties van interface speciale vorm van klasse met methods en constanten meerdere andere klassen kunnen een interface implementeren public interface Ordered { boolean lessThan (Ordered O); }; lessThan neemt als par. elk object dat Ordered interface impl. Yolande Berbers Programmatuur voor real-time controle slide 35 RTP Java: klasse die interface impl. class ComplexNumber implements Ordered { protected float realPart; protected float imagPart; public boolean lessThan(Ordered O) // interface implementation { ComplexNumber CN = (ComplexNumber) O; // cast the parameter if((realPart*realPart + imagPart*imagPart) < (CN.getReal()*CN.getReal() + CN.getImag()*CN.getImag())) { return true; } return false; }; public ComplexNumber (float I, float J) // constructor { realPart = I; imagPart = J; }; public float getReal() { return realPart;}; public float getImag() { return imagPart; }; } Yolande Berbers Programmatuur voor real-time controle slide 36 RTP Java: interfaces public class ArraySort { public static void sort (Ordered oa[], int size) //sort method { Ordered tmp; int pos; for (int i = 0; i < size - 1; i++) { pos = i; for (int j = i + 1; j < size; j++) { if (oa[j].lessThan(oa[pos])) { pos = j; } sort is een routine die een } tmp = oa[pos]; array van objecten kan oa[pos] = oa[i]; sorteren van elke klasse die oa[i] = tmp; de interface Ordered }; implementeert }; Yolande Berbers Programmatuur voor real-time controle slide 37