If you don't read German, you can still read
some of the publications linked to below, which center around my work
on "Modern Programming Methods".
Theoretiker in der Informatik streben nach besonders eleganten Programmen, während die Praktiker gern wartbare Programme haben (d.h. erweiterbar, portierbar, und korrigierbar). Eine Erkenntnis der vorliegenden Arbeit ist, dass beide Parteien eigentlich vom Selben reden, nämlich von einfachen Programmen.
In der Arbeit wird die formale Theorie der Verfeinerung benutzt, um eine neue einheitliche Sicht auf die Programmierung zu etablieren. Die notwendigen theoretischen Grundlagen werden dazu in eigenen Kapiteln kurz erläutert. (Diese Ausführungen sind allein schon wertvoll, weil sie theoretische Erkenntnisse aus praktischer Sicht betrachten.) Kern der Arbeit ist aber eine neue Betrachtung der Elemente Objektorientierter Programmiersprachen, die ihre Querverbindungen aufzeigt und es uns ganz explizit erlaubt, immer die einfachste Implementierung zu wählen – und darauf kommt es ja an.
Die Arbeit behandelt Themen, die für jeden Informatiker relevant sind, auf eine Weise, die für jeden Informatiker verständlich ist. Trotzdem erreicht die Arbeit aber noch lange nicht das Ziel einer Schritt-für-Schritt Anleitung; der Leser sollte Aussagen stets kritisch hinterfragen, Argumentationen nachvollziehen und auf Beispiele seiner Erfahrung anwenden. Erst dann wird er reich belohnt: durch eine Inspiration zu einem besseren und sehr viel produktiveren Programmierstil. Oder um es mit den Worten von Gerald Weinberg zu sagen: „The material which follows is food for thought, not a substitute for it.“ (The Psychology of Computer Programming)
Mehr Informationen zu den Inhalten finden sich der meiner Themenbeschreibung Einleitung der Arbeit, der Liste neuer Erkenntnisse auf Seite 102 und schließlich den ↓Thesen am Ende der Arbeit.
Volltext der Diplomarbeit (PDF)
Resizable Arrays in Dessy, voller Quelltext und Dokumentation der Array-Fallstudie, August 2003
Dessy Design Documents: imperative (summary only), functional (complete with sources)
Formalisations of the Diplomacy Rules, drei Spezifikationen der Diplomacy-Fallstudie, Februar 2004
Modularity without Abstraction is no more than Syntactic Sugar, Dezember 2003
Disciplined Exceptions, Bertrand Meyer, 1988
Error Management is Risk Management, Robert Will, Januar 2004
Errors and Exceptions – Rights and Responsibilities, Johannes Siedersleben, 2003
Ausnahmen mit Methode, Robert Will, Februar 2004
Bei der Programmierung geht es manchmal um das Formalisieren von Anforderungen in einer Programmiersprache und manchmal um das Herleiten einer effizienteren Implementierung aus einer eindeutigen, aber einfacheren Spezifikation. Meistens geht es aber um beides gleichzeitig: Formalisieren und Operationalisieren!
Für jeden der beiden Teilbereiche gelten ganz unterschiedliche Methoden und daher ist es die erste Aufgabe des Programmieres beide zu trennen. Selbst-spezifizierender Code (d.h. formalisierte Anforderungen) soll als solcher gekennzeichnet werden, und der ganze Rest soll eine separate, einfache und präzise Spezifikation bekommen.
Ob ein Programmteil eine formale Spezifikation hat oder nicht – Tests braucht er in jedem Fall.
Alle äußeren Qualitätsmerkmale von Software außer der Effizienz gehen in die funktionale Spezifikation ein, die Implementierung misst sich nur an der Spezifikation und inneren Qualitätsmerkmalen.
Von allen formalen Theorien entspricht die Verfeinerung am besten den modernen Programmiermethoden. Programme und Spezifikationen sind Bool'sche Ausdrücke, die Berechnungen beschreiben. Programme unterscheiden sich prinzipiell nur durch ihre Effizienz von Spezifikationen.
Programmentwurf besteht darin, jeden Programmteil so einfach wie möglich zu gestalten. Einfachere Implementierungen sind leichter zu erstellen, zu warten und sie bieten auch Fehlern weniger Platz und machen Tests effektiver.
Wenn man Schnittstellen explizit dokumentiert, neigt man dazu sie besser zu entwerfen, und sie werden tendenziell einfacher.
Ein Software-Entwurf kann nur in Bezug auf eine konkrete Spezifikation und im Vergleich mit Alternativen bewertet werden.
Je nachdem ob der ``Formalisieren''- oder der ``Operationalisieren''-Teil des Programmierens überwiegt, entspricht der Zweck einer Routine (und auch einer Klasse) eher einer Definition oder einem Lemma in der Mathematik.
Abstrakte Datentypen unterscheiden wir in unveränderliche (Elemente einer Algebra, die durch Funktionen ineinander umgewandelt werden) und veränderliche (kleine Maschinen, deren Zustand durch Befehle verändert wird). Die unveränderlichen Objekte sind prinzipiell einfacher zu benutzen, alle Methoden der funktionalen Programmierung können auf sie angewendet werden. Die veränderlichen Objekte mit ihren Referenzen untereinander machen das Gesamt-Datenmodell eines Programms aus.
Vererbung dient dazu, gemeinsame Spezifikationen und Implementierungen auszufaktorieren. Über externe Vererbung kann ein Kunde mehrere Zulieferer transparent über die gleiche Schnittstelle benutzen. Über interne Vererbung kann sich eine Klasse zusätzliche Funktionalität holen, ohne dass ihre Kunden davon betroffen sind.