Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Seminar aus Softwareentwicklung: Programmierstile Christian Zeilinger

Ähnliche Präsentationen


Präsentation zum Thema: "Seminar aus Softwareentwicklung: Programmierstile Christian Zeilinger"—  Präsentation transkript:

1 Seminar aus Softwareentwicklung: Programmierstile Christian Zeilinger

2 Übersicht Einführung und Beispiele von Softwarefehler Was bedeutet Defensives Programmieren Design by Contract Erfolgreiches Verwalten von Resourcen Self-Describing Data Die Kunst des Testens Robustheit, Christian Zeilinger Folie

3 Einführung Es gibt keine perfekte Software! !! Leider Tatsache: Also, was tun? Sich damit abfinden, oder gar verzweifeln? Robustheit, Christian Zeilinger Folie

4 Robustheit, Christian Zeilinger Folie Die schlimmsten Softwarefehler 1985: Software-Fehler in einem Röntgenapparat 1996: Explosion der Ariane 5 am 4. Juni 1999: Verglühen eines Mars Climate Orbiters Rechtzeitig gefundener Fehler: F-16 T+36: Fehler im Inertial Reference System Hauptcomputer weist Triebwerke an, eine große Korrektur durchzuführen Rakete bricht aufgrund aerodynamischer Kräfte auseinander (Selbstzerstörung) SO NICHT!!!

5 Defensives Programmieren Definition Robustheit: Fähigkeit von Softwaresystemen, auch unter außergewöhnlichen Bedingungen zu funktionieren Defensiv zu programmieren bedeutet, die Programme in Hinblick auf Robustheit zu gestalten Deshalb: Alle Annahme über Eingaben, Systemzustände usw. prüfen und bei Fehlern handeln (Assertions, Exceptions,…) Zum Beispiel: Die Variable x muss hier positiv sein Dieser Zeiger darf hier (eigentlich) nicht NULL sein Robustheit, Christian Zeilinger Folie

6 Design by Contract Bedingungen, die gelten müssen, damit ein System funktionieren kann Beispiel im realen Leben: Paketzustelldienst Bedingungen der Zustellfirma: -maximale Größe und Gewicht des Paketes -Bezahlung der Dienstleistung im Voraus Bedingungen von Seiten des Klienten: -Sorgfältiger Umgang mit der Fracht (keine Beschädigungen,…) -Ankunft des Gutes am gewünschten Zielort innerhalb einer gewissen Zeitspanne Robustheit, Christian Zeilinger Folie

7 Design by Contract Preconditions Bedingungen, die gelten müssen, damit eine Methode (Komponente) ausgeführt werden kann Postconditions Bedingungen, die nach dem Ausführen einer Methode gelten müssen (impliziert auch Resultate) Invarianten Bedingungen, die aus Sicht des Rufers immer erfüllt sein müssen Beispiele: Class-Invarianten, Loop-Invarianten Lazy Code Robustheit, Christian Zeilinger Folie

8 Design by Contract /* class invariant: * count enspricht der Anzahl der gesetzten Integer-Werte array ist ein Feld von Werten * die gesetzt werden können, wobei jeder noch nicht gesetzter Wert -1 entspricht. */ public class IntegerArray { ………………… public int Max { get { int max = -1; /* Loop-Invariante: * Vor jedem Durchlauf gilt: max = max(array[0:i-1]) (auch nach dem Ende der Schleife)*/ for(int i=0; i max) max = array[i]; return max;} public int this[int index] { get { return array[index];} // Precondition: 0 <= index < size set { array[index] = value;/* Nach der Ausführung dieser Anweisung ist die Klasseninvariante * verletzt, da count ungleich der der Anzahl der gesetzten Werte*/ count++;//Erst jetzt gilt die Klasseninvariante wieder } // Postcondition: Wert gesetzt } …………………… } Robustheit, Christian Zeilinger Folie

9 Design by Contract Überprüfung der Kontrakte Mit Hilfe von Tools Tool für Java: iContract @invariant) Assertionen Methodenaufruf mit Übergabe der Bedingung - Beispiel: assert(x > 0); Bedingung erfüllt: okay Bedingung verletzt: Fehler -> Programmabbruch Exceptions Sprachliche Unterstützung, um mit einfachen Mitteln: -dem Rufer einen Ausnahmefall mitzuteilen (throw) -ein (kollektives) Errorhandling zu bewerkstelligen (try …… catch) Robustheit, Christian Zeilinger Folie

10 Design by Contract using System.Diagnostics.Debug; public class IntegerArray { ………………… public int this[int index] { get { Debug.Assert(index >0 && index < array.Length); //Prüfung der Precondition return array[index]; } set { Debug.Assert(index >0 && index < array.Length); //Prüfung der Precondition array[index] = value; count++; } public IntegerArray(int size) { Debug.Assert(size > 0);//Prüfung der Precondition array = new int[size]; for(int i=0; i

11 Design by Contract Exceptions #include //without Exceptions int main() { int xMin, xMax, yMin, yMax, error = 0; FILE *file = fopen("file.cfg", "rb"); if (f != NULL) { error = 1; } else if(xMin = fgetc(file) == EOF) { error = 1; } else if(xMax = fgetc(file) == EOF) { error = 1; } else if(yMin = fgetc(file) == EOF) { error = 1; } else if(yMax = fgetc(file) == EOF) { error = 1; return -1; } if (error == 0) { printf("%d,%d,%d,%d", xMin,xMax,yMin,yMax); } else printf("Error reading file.cfg"); fclose(file); } using System; //using Exceptions using System.IO; class Test { static void Main() { int xMin, xMax, yMin, yMax; try { FileStream str = new FileStream("file.cfg", FileMode.Open); xMin = str.ReadByte(); xMax = str.ReadByte(); yMin = str.ReadByte(); yMax = str.ReadByte(); Console.WriteLine("{0},{1},{2},{3}", xMin,xMax,yMin,yMax); } catch(IOException) { Console.WriteLine("Error reading file.cfg"); } finally { //Code der in jedem Fall ausgeführt wird str.Close(); } Robustheit, Christian Zeilinger Folie

12 Resource-Balancing Hauptspeicher, Threads, Dateien, Timer,… sind limitiert Verhaltensmuster: allocate – use – deallocate using System.IO; class Budget { FileStream fileStr = null; void ReadBudget(string fileName, out int budget) { fileStr = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite); budget = (new BinaryReader(fileStr)).ReadInt32(); } void WriteBudget(int budget) { fileStr.Seek(0, SeekOrigin.Begin); (new BinaryWriter(fileStr)).Write(budget); fileStr.Close(); } public virtual int Update(string fileName, int newBudget) { int oldBudget; ReadBudget(fileName, out oldBudget); //Altes auslesen WriteBudget(newBudget); //Neues schreiben return newBudget; } class NewBudget : Budget { public override int Update(string fileName, int newBudget) { int oldBudget; ReadBudget(fileName, out oldBudget); if (newBudget > 0) { //nur mit positiven neuem Budget überschreiben! WriteBudget(newBudget); return newBudget; } return oldBudget; } Robustheit, Christian Zeilinger Folie

13 Resource-Balancing Finish What You Start! using System.IO; class Budget { protected void ReadBudget(FileStream fileStr, out int budget) { budget = (new BinaryReader(fileStr)).ReadInt32(); } protected void WriteBudget(FileStream fileStr, int budget) { fileStr.Seek(0, SeekOrigin.Begin); (new BinaryWriter(fileStr)).Write(budget); } public virtual int Update(string fileName, int newBudget) { int budget; FileStream fileStr = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite); ReadBudget(fileStr, out budget);//Altes Budget auslesen if (newBudget > 0) { WriteBudget(fileStr, newBudget);//eventuell mit neuem Budget überschreiben budget = newBudget; } fileStr.Close(); return budget; } Robustheit, Christian Zeilinger Folie

14 Kundendaten: Hans Maier, 03/04/1976, 02/07/2001, 01/12/2002, 20 Christoph Huber, 01/02/1979, 01/01/2000, 11/02/2002, 10 Hannes Dorfer, 09/09/1958, 01/01/2000, 01/01/2002, 5 Self-Describing Data Problem: Mysteriöse Daten! Linux-Verzeichnisausgabe mittels dir: total 44 -rw-r--r-- 1 pr17 pr 4810 Dec 4 14:37 ETRC -rw-r--r-- 1 pr17 pr 4810 Dec 4 14:36 ETRC.BAK drwxr-xr-x 2 root root 512 Oct TT_DB -rw-r--r-- 1 pr17 pr 0 Dec 4 17:02 out.txt drwxr-xr-x 3 pr17 pr 512 Dec 4 14:19 round drwxr-xr-x 2 pr17 pr 512 Nov 7 15:12 test drwxr-xr-x 2 pr17 pr 512 Dec 4 14:25 traces1 drwxr-xr-x 2 pr17 pr 512 Dec 4 14:29 traces2 drwxr-xr-x 2 pr17 pr 512 Dec 4 14:33 traces3 drwxr-xr-x 2 pr17 pr 512 Nov 12 17:35 ueb13 drwxr-xr-x 2 pr17 pr 512 Nov 20 16:51 ueb24 drwxr-xr-x 2 pr17 pr 512 Dec 3 15:35 ueb32 drwxr-xr-x 2 pr17 pr 512 Dec 3 17:43 ueb33 drwxr-xr-x 2 pr17 pr 512 Dec 4 12:30 ueb42 drwxr-xr-x 3 pr17 pr 512 Dec 4 12:17 ueb43 Linux-Prozessübersicht mittels: ps –ef | grep pr17 pr :00:58 ? 0:00 /system/apps/gup/bin/lamd -H P n 0 -o 0 pr :04:16 pts/2 0:00 -tcsh pr :03:19 ? 0:00 /usr/local/bin/tcsh -c sftp-server pr :00:48 pts/2 0:00 -tcsh pr :03:19 ? 0:00 sftp-server ??? Robustheit, Christian Zeilinger Folie

15 Self-Describing Data Name-Value Pairs: Daten + Schema Beispiel: Kundendaten %nameHans Maier %birthday03/04/1976 %firstTransaction02/07/2001 %discountStartDate01/12/2002 %discountPercent20 %nameChristoph Huber ……… Speichereffizienz? Robustheit, Christian Zeilinger Folie

16 Self-Describing Data Komprimierte Speicherung von Name-Value Pairs Beispiel: Kundendaten naHans Maier|bi03/04/1976|ft02/07/2001|ds01/12/2002|di20 naChristoph Huber| Zusatzinformationen in einem Data Dictionary: ABBREVIATIONNAMEUNIT nanametext bibirthdaydate ftfirstTransactiondate dsdiscountStartDatedate didiscountpercent Herkunft der Daten und Geschichte von Veränderungen Wer? Wann? Wieso? Robustheit, Christian Zeilinger Folie

17 Self-Describing Data Name-Value Pairs in der Programmierung Bsp.: AddProduct(1001, C# and.NET Reference, 5, 29.90, 20, 10); Was bedeuten die einzelnen Werte? Programmierdisziplin (Kommentare): AddProduct(1001,//Produktnummer C# and.NET Reference,//Bezeichnung 5,//Stückzahl 29.90,//Verkaufspreis netto 20,//Mehrwertsteuer (in %) 10);//maximaler Rabatt Sprachliche Unterstützung AddProduct(pNr = 1001, name = C# and.NET Reference, count = 5, price = 29.90, MWSt = 20, discount = 10); Robustheit, Christian Zeilinger Folie

18 Die Kunst des Testens Fehler gefunden -> Test war erfolgreich Ging alles gut -> Erfolgloser Test Testen bedeutet: Ein Programm mit der Absicht auszuführen, Fehler zu finden! Testen kann NICHT zeigen, dass ein Programm fehlerfrei ist. Robustheit, Christian Zeilinger Folie

19 Die Kunst des Testens Testen im Software-Lebenszyklus –Test der Spezifikation –Modultest –Integrationstest –Systemtest –Abnahmetest Systematisch Testen –inkrementelles Testen –beginnend mit den einfachen und grundlegenden Teilen –Welchen Output erwartet man sich? –Vergleich verschiedener Implementierungen –Coverage? Teste während der Codeerstellung Robustheit, Christian Zeilinger Folie

20 Die Kunst des Testens White-Box-Testing vs. Black-Box-Testing ? ? Robustheit, Christian Zeilinger Folie

21 Die Kunst des Testens Abklären, was getestet werden soll z.B.: Methode: String ToUpperCase(String str, int startIndex, boolean unicode); Wahl geeigneter Inputs –Äquivalenzklassen str: null, im ASCII-Code, im Unicode; unicode: true, false startIndex =N –Randbereiche startIndex: -1, 0, 1, N-2, N-1, N; str: null, 1-Zeichen, 2-Z., N-Zeichen –Reduktion der Testeingaben unmögliche Kombinationen: str.length == 0 und unicode == true nur für einen Parameter eine ungültige Äquivalenzklasse wählen Festlegen der erwarteten Ausgabe Durchführen des Test Vergleich der Ausgabe mit der erwarteten Robustheit, Christian Zeilinger Folie

22 Die Kunst des Testens Testautomation –Code-Review –Erzeugung von Eingabewerten Generische Daten Intelligente Daten –Stress-Tests –Regressionstesten Testabbruch –wenn bestimmte Anzahl von Fehlern entdeckt wurde 1 Fehler / Anweisungen Es bleiben immer Restfehler!!! –wenn bei gleichmäßiger Testanstrengung die Fehlerentdeckungsrate deutlich abnimmt Robustheit, Christian Zeilinger Folie

23 Zusammenfassung Robustheit, Christian Zeilinger Folie Defensives Programmieren steigert die Robustheit von Softwareprodukten Design by Contract trifft Aussagen über notwendige Bedingungen zur Ausführung von Software Korrektes Resource-Balancing ist von hoher Notwendigkeit Selbstbeschreibende Daten helfen bei der Analyse und tragen zum allgemeinen Verständnis bei Ausreichende Tests sind der Schlüssel zu robusten Programmen

24


Herunterladen ppt "Seminar aus Softwareentwicklung: Programmierstile Christian Zeilinger"

Ähnliche Präsentationen


Google-Anzeigen