- Peter Naurs „Programming as Theory Building“ betrachtet Programmieren nicht als Tätigkeit zur Erzeugung von Programmtexten, sondern als Tätigkeit, bei der Programmierer eine Theorie über das Problem und seine Lösung bilden.
- „Theorie“ bedeutet hier nicht einfach abstrakte Aussagen oder dokumentierte Entwurfsbeschreibungen.
- zu verstehen, welche Bedeutung ein Problem in der realen Welt hat,
- erklären zu können, wie die Programmstruktur dieser Realität entspricht,
- begründen zu können, warum so entworfen wurde, und
- bei neuen Anforderungen beurteilen zu können, wie sie sich in die bestehende Struktur integrieren lassen.
- Daher ist das zentrale Wissen eines Programms nicht vollständig in Code oder Dokumentation enthalten, sondern im Kopf der Programmierer, die das Programm verstehen.
Programmieren und Wissen
- Naur sieht Programmieren als die Tätigkeit, Aktivitäten der realen Welt auf formale Symbolmanipulationen abzubilden, die ein Computer ausführen kann.
- In dieser Sicht ist auch die Änderung eines Programms Teil des Programmierens.
- Denn wenn sich Aktivitäten der realen Welt ändern, muss sich auch das Programm ändern.
- Das Wesen des Programmierens sind nicht Dokumente oder Code-Artefakte, sondern das spezifische Wissen, das Programmierer aufbauen.
- Dokumentation ist wichtig, aber unterstützend.
- Sie kann die Theorie nicht vollständig ersetzen.
- Sie ist eher ein Werkzeug, das die Theoriebildung unterstützt.
Fall 1: Compiler-Übergabe und Scheitern
- Gruppe A entwickelte einen Compiler für die Sprache L.
- Gruppe B erhielt den Compiler-Code, die Dokumentation und Ratschläge von A, um einen Compiler für die erweiterte Sprache L + M zu bauen.
- Code und Dokumentation wurden ausreichend bereitgestellt, aber B konnte bei einigen Entwurfsfragen die Stärke der bestehenden Struktur nicht nutzen und schlug patchartige Lösungen vor.
- A erkannte das Problem sofort und präsentierte einfachere und natürlichere Lösungen innerhalb der bestehenden Struktur.
- Der Kern dieses Falls:
- Programmtext und Dokumentation allein übertragen die tieferliegende Theorie des Entwurfs nicht.
- Das „Warum“ des bestehenden Entwurfs und „wie man ihn erweitern sollte“ lassen sich durch Dokumentation allein nicht hinreichend vermitteln.
- Später schwächten andere Programmierer, die den Compiler ohne Anleitung von A änderten, die ursprünglich starke Struktur allmählich durch formlose Ergänzungen.
- Das zeigt die Grenzen von Programmtext und Dokumentation bei der Bewahrung der zentralen Entwurfstheorie.
Fall 2: Großes Echtzeitsystem
- Vorgestellt wird der Fall eines industriellen Echtzeitsystems mit rund 200.000 Zeilen Code.
- Die Programmierer, die für Installation und Fehlerdiagnose zuständig waren, waren seit den frühen Entwurfsphasen über lange Zeit eng mit dem System verbunden.
- Bei der Fehlerdiagnose verließen sie sich hauptsächlich auf ihr unmittelbares Systemverständnis und auf kommentierten Code.
- Externe Betriebsprogrammierer mit Dokumentation und Schulung stießen dagegen wiederholt auf Schwierigkeiten.
- Erfahrene Programmierer des Herstellers lösten diese Probleme leicht.
- Schlussfolgerung:
- Wartung und Änderung großer Programme hängen wesentlich von dem Wissen der Menschen ab, die lange mit dem Programm verbunden waren.
- Dokumentierte Erklärungen allein können dieses Wissen nicht vollständig ersetzen.
Ryles Begriff der „Theorie“
- Naur übernimmt den Theoriebegriff von Gilbert Ryle.
- Eine Theorie zu haben bedeutet nicht einfach, Aussagen zu kennen.
- Es ist ein Zustand, in dem man etwas tun kann,
- es erklären kann,
- Fragen dazu beantworten kann und
- die eigenen Urteile rechtfertigen kann.
- Intelligente Tätigkeit lässt sich nicht notwendig auf das Befolgen von Regeln reduzieren.
- Denn auch das Befolgen von Regeln muss selbst intelligent ausgeführt werden.
- Wenn man wiederum Regeln dafür bräuchte, wie Regeln zu befolgen sind, entstünde ein unendlicher Regress.
- Daher umfasst intellektuelle Tätigkeit nicht bloß das Ausführen von Regeln, sondern auch die Fähigkeit, Ähnlichkeiten zwischen Situationen zu erkennen und angemessen zu reagieren.
Theorie lässt sich nicht vollständig in Regeln ausdrücken
- Wer eine Theorie besitzt, erkennt bedeutungsvolle Ähnlichkeiten zwischen verschiedenen Situationen der realen Welt.
- Solche Ähnlichkeiten lassen sich jedoch nur schwer vollständig in eindeutige Kriterien oder Regeln fassen.
- Beispiele:
- Ähnlichkeit von Gesichtern
- Ähnlichkeit von Melodien
- Ähnlichkeit von Weingeschmack
- Genauso lässt sich auch im Programmieren nur schwer auf einfache Regeln reduzieren, wie neue Anforderungen der bestehenden Struktur ähneln und wo sie integriert werden sollten.
- Das ist der Kern impliziten Wissens.
Welche Theorie Programmierer haben müssen
- Ein Programmierer mit einer Theorie des Programms sollte Folgendes können.
1. Die Entsprechung zwischen realer Welt und Programm erklären können
- Er sollte erklären können, welchem Vorgang oder Begriff der realen Welt jeder Teil des Programms entspricht.
- Umgekehrt sollte er auch erklären können, wie bestimmte Aktivitäten der realen Welt im Programm dargestellt werden.
- Um beurteilen zu können, was relevant und was irrelevant ist, braucht es ein Verständnis der realen Welt als Ganzes.
2. Begründen können, warum das Programm so ist, wie es ist
- Er sollte erklären können, warum die Struktur des Programms und die Details seiner Implementierung genau so entworfen wurden.
- Diese Begründung kann Regeln, Schlussfolgerungen, Entwurfsprinzipien und quantitative Abschätzungen nutzen.
- Letztlich hängt die Entscheidung, welches Prinzip anzuwenden ist, jedoch von der unmittelbaren Einsicht des Programmierers ab.
3. Auf neue Änderungsanforderungen konstruktiv reagieren können
- Er sollte erkennen können, welchen Funktionen oder Strukturen des bestehenden Programms neue Anforderungen ähneln.
- Auf dieser Grundlage sollte er Änderungen so entwerfen können, dass sie sich natürlich in die bestehende Theorie einfügen.
- Diese Fähigkeit lässt sich nur schwer durch dokumentierte Verfahren ersetzen.
Programmänderungen und Kosten
- Software wird zwangsläufig geändert.
- weil im Gebrauch neue Anforderungen entstehen
- und weil sich die Bedingungen der realen Welt verändern.
- Häufig nimmt man an, dass die Änderung eines bestehenden Programms billiger sei als ein Neubau.
- Aus Naurs Sicht ist diese Erwartung jedoch nicht immer berechtigt.
- Die Kosten von Programmänderungen sind nicht die Kosten der Textbearbeitung.
- Die zentralen Kosten liegen darin, die Theorie des bestehenden Programms zu verstehen
- und neue Anforderungen in diese Theorie zu integrieren.
- Deshalb lässt sich nicht allein daraus, dass Code ein leicht editierbarer Text ist, schließen, dass Änderungen einfach sind.
Grenzen der Flexibilität
- Die Behauptung, man solle Programmen im Voraus Flexibilität für künftige Änderungen einbauen, ist nur teilweise berechtigt.
- Flexibilität gibt es nicht umsonst.
- Man muss entscheiden, auf welche zukünftigen Situationen man sich vorbereiten will,
- Parameter und Strukturen entwerfen
- und Implementierungs-, Test- und Erklärungskosten tragen.
- Ihr Nutzen hängt von ungewissen zukünftigen Ereignissen ab.
- Deshalb kann Flexibilität keine allgemeine Lösung für den Umgang mit Änderungen sein.
- Entscheidend ist nicht, im Voraus Strukturen für jede Veränderung einzubauen, sondern auf Grundlage der Theorie des Programms angemessen urteilen zu können, wenn Veränderungen eintreten.
Gute und schlechte Änderungen
- Selbst Änderungen, die dasselbe äußere Verhalten erfüllen, können auf viele Arten implementiert werden.
- Nach außen können sie alle korrekt erscheinen.
- Aus Sicht der Programms-Theorie gibt es jedoch große Unterschiede.
- Manche Änderungen erweitern die bestehende Theorie auf natürliche Weise.
- Andere funktionieren wie aufgesetzte Patches auf der bestehenden Struktur.
- Wenn sich letztere häufen, wird das Programm allmählich zu einem Flickwerk.
- Die langfristige Überlebensfähigkeit eines Programms hängt davon ab, wie gut jede Änderung in der bestehenden Theorie verankert ist.
Leben, Tod und Wiederbelebung von Programmen
Das Leben eines Programms
- Ein Programm lebt, solange die Programmierer mit der Theorie des Programms es noch aktiv kontrollieren.
- Sie können auf Änderungsanforderungen intellektuell reagieren.
Der Tod eines Programms
- Wenn das Team mit der Theorie des Programms auseinanderfällt, stirbt das Programm.
- Ein totes Programm kann weiterhin laufen und nützliche Ergebnisse liefern.
- Sein Tod zeigt sich jedoch dann, wenn es auf Änderungsanforderungen nicht mehr angemessen reagieren kann.
Die Wiederbelebung eines Programms
- Darunter versteht man den Versuch eines neuen Teams, die Theorie des bestehenden Programms neu aufzubauen.
- Naur hält das im strengen Sinne für unmöglich.
- Denn aus Dokumentation und Code allein lässt sich die Theorie des ursprünglichen Teams nicht vollständig rekonstruieren.
- Selbst wenn Wiederbelebung möglich ist, ist sie teuer und schwierig und führt wahrscheinlich zu einer anderen Theorie als der ursprünglichen.
- In manchen Fällen kann es besser und billiger sein, das Problem durch ein neues Team neu zu lösen, als den bestehenden Code zu retten.
Kritik an Methodologien
- Naur versteht Programmiermethodologien als „Mengen von Regeln, die festlegen, in welcher Reihenfolge Programmierer welche Arbeiten ausführen sollen“.
- Aus Sicht der Theoriebildung erfassen Methodologien in diesem Sinn das Wesen des Programmierens nicht.
- Gründe:
- Theoriebildung hat keine festgelegte Reihenfolge.
- Eine Theorie ist ihrem Wesen nach keine lineare Kombination von Teilen.
- Notationen oder Dokumentformate können die Theoriebildung unterstützen, sind aber nicht die Theorie selbst.
- Daher kommt man zu dem Schluss, dass es für die primäre Tätigkeit des Programmierens keine universell richtige Methode gibt.
Das bedeutet nicht, dass Methodologien völlig wertlos sind
- Was Naur zurückweist, ist Methodologie als Verfahren, das mechanisch gutes Design garantiert.
- Methodologien, Entwurfstechniken, Notationen und Verifikationstechniken können einen pädagogischen Wert haben.
- Programmierer, die mit guten Beispielen, Strukturierungsprinzipien und Verifikationstechniken vertraut sind, bilden mit höherer Wahrscheinlichkeit bessere Theorien.
- Welche Technik wann und in welcher Reihenfolge angewendet wird, sollte jedoch dem Urteil des Programmierers überlassen bleiben, der das tatsächliche Problem versteht.
Die Stellung des Programmierers
- Wenn man Programmieren wie industrielle Produktion betrachtet, werden Programmierer wie austauschbare Teile behandelt.
- Dahinter steht die Sicht, dass jeder bei Befolgung von Verfahren und Regeln zum gleichen Ergebnis kommen könne.
- Naur weist diese Sicht zurück.
- Wenn das zentrale Produkt eines Programms die Theorie ist, die Programmierer besitzen, dann sind Programmierer keine leicht austauschbaren Arbeitskräfte.
- Sie ähneln eher einem Berufsstand, der die Gesamtheit der Aktivitäten mit Computerbezug verantwortungsvoll weiterentwickelt und verwaltet.
- Daher sollten Programmierern dauerhafte Stellung und Verantwortung gegeben werden.
- Auch Ausbildung sollte über bloße Grammatik, Notation und Datenverarbeitungstechniken hinausgehen und die Fähigkeit zur Theoriebildung fördern.
XP-Metapher und Theoriebildung
- Die „Metapher“ in XP lässt sich aus Naurs Perspektive der Theoriebildung gut erklären.
- Eine gute Metapher hilft dem Team, ähnliche Annahmen über die Struktur des Programms zu machen.
- Beispiele:
- das Programm als „Fließband“ verstehen
- das Programm als „Restaurant“ verstehen
- Eine gute Metapher ist nicht bloß ein Vergleich.
- Sie hilft Entwerfenden zu beurteilen, welche Struktur zu erwarten ist,
- wo neuer Code hinzugefügt werden sollte
- und wie er mit Code anderer zusammenpassen muss.
- Je größer das Team und je mehr Parallelität in der Arbeit, desto wertvoller wird eine geteilte Metapher.
- Ohne gemeinsame Theorie entwickelt jeder Programmierer seine eigene, und das System wird zunehmend inkonsistent und komplex.
Die Rolle der Dokumentation
- Dokumentation kann dem aktuellen Zustand eines Programms nur schwer vollständig folgen.
- Das bedeutet jedoch nicht, dass Dokumentation unnötig ist.
- Ihr Zweck ist nicht, alles festzuhalten, sondern dem nächsten Programmierer zu helfen, eine angemessene Theorie zu bilden.
- Gute Dokumentation aktiviert Erinnerung und Erfahrung der Lesenden und öffnet die richtigen Denkpfade.
- Solche Dokumentation überlebt länger als Dokumente, die lediglich die aktuellen Klassen, Funktionen und Module auflisten.
Aufbau guter Entwurfsdokumentation
- Erfahrene Entwerfende beginnen Dokumente meist mit folgenden Punkten.
- die zentrale Metapher
- eine Erklärung des Zwecks der Hauptkomponenten
- ein Diagramm der zentralen Interaktionen zwischen den Hauptkomponenten
- Diese drei Punkte helfen dem nächsten Team sehr dabei, eine Entwurfstheorie zu bilden.
- Auch der Quellcode selbst ist ein Mittel zur Vermittlung von Theorie.
- konsistente Benennung
- einfache Struktur
- vorhersehbare Muster
- Minimierung unnötiger Ausnahmen
- Ein großer Teil von „sauberem Code“ hängt damit zusammen, wie leicht Leser eine konsistente Theorie über das System bilden können.
Noch keine Kommentare.