2015-01-22 digital life Software-Analogien Softwarekrebs Ich suche zur Zeit einen Fehler in einem Programm. Der Code (Java) ist nicht von mir. Der damalige Entwickler ist nicht mehr verfuegbar. Das Programm wird bislang noch nicht eingesetzt weil dieser Fehler da ist. Fehlersuchen erfordert zuerst das Verstehen des Soll und dann des Ist. Die Differenz dazwischen ist der Fehler ... in der Theorie! Denn Programme erfuellen quasi nie die gewuenschten Anfor- derungen. Es gibt tolerierbare Abweichungen, die z.B. die tech- nische Implementierung deutlich vereinfachen zulasten eines leicht abweichenden Konzeptes dahinter, und es gibt klassische Fehler, bei denen Ist und Soll offensichtlich unerwuenscht abweichen. So weit zum vereinfachten Bild der Welt, wie wir sie gerne sehen wollen. Wie ich in diesen Tagen feststellen muss gibt es noch eine weitere Ebene. Diejenigen, die Software als Kunst sehen, wuerden sie ``Stil'' nennen. Diejenigen die Software als Ingenieursleis- tung sehen, wuerden sie ``Architektur'' nennen. Mathematiker wuerden sie vielleicht ``Struktur'' nennen. Man koennte aber ebenso ``Problemverstaendnis'' dazu sagen. So vielfaeltig die Be- griffe sind, so schwierig ist es auch das Problem zu greifen. Zuerst ist da die Zielnutzergruppe des Programms, die zu berufs- blind ist um dem Programmierer vermitteln zu koennen, wie das zu loesende Problem in sich strukturiert ist. Es gelingt ihnen nicht, die logische Essenz, die Natur der Dinge, herauszudestil- lieren. Dann geht in der Kommunikation zwischen Fachseite und Entwickler immer etwas verloren. Das sollte man nicht vergessen. Der Programmierer (der in diesem Fall ein Alleinentwickler war) legt nicht genug Wert darauf wiederum die Kernstruktur herauszuarbeiten und davon den Aufbau des Programms leiten zu lassen. Weiter gibt es keine, zu wenige oder unproduktive Feed- backschleifen zwischen Entwickler und den Nutzern. Unstimmig- keiten, Kompliziertheit und Co. werden nicht ausreichend angegangen, nicht frueh schon ausgemerzt. (Die wichtigste Frage waere: ``Warum ist das so?'' Die sollte tausendmal gestellt wer- den.) Am Ende kommt ein Programm heraus, das nicht so ist wie es sein sollte. Soll und Ist weichen ab, vor allem auf dieser Stil/Architektur/Problemverstaendnis-Ebene. Sehen das der Entwickler und die Anwender auch so? Oder ist die Abweichung auf dieser Ebene vielleicht nur subjektiv? Ich will mich hart gegen diese Subjektivitaet stellen. Der hier gemeinte Stil und die hier gemeinte Architektur haben nur in sofern etwas mit Vorliebe und Schoenheit zu tun, als dass Vorliebe und Schoenheit oft die Folgen von objektiv guten Eigen- schaften sind. (Symmetrie bedeutet Stimmigkeit, Einfachheit, Klarheit ... das alles ist wiederum objektiv wichtig.) Stil und Architektur haben einen soliden Kern, der kaum subjektiv gepraegt ist (mindestens aber fuer einen ganzen Kulturkreis gleich ist). Dazu gehoert z.B. der grundsaetzliche Aufbau von Texten aus Einleitung, Hauptteil und Schluss. Dazu gehoeren das Fundament und Dach eines Gebaeudes in der Architektur. Dazu gehoeren hierarchische Verkehrswegenetze, Beschilderungssysteme, klare Begriffsverwendungen (Glossare), etc. In all diesen Bereichen ist der subjektive Anteil gering. Man ist sich vielmehr weitgehend einig, dass all dies auf eine der bewaehrten und dur- chdachten Arten realisiert werden sollte. Insbesondere ist man sich einig, dass es fast sicher zu groesseren Problemen fuehren wird, wenn man diese Aspekte ignoriert: Ein Bauwerk ohne Dach, ein Text ohne Einleitung, eine Stadt ohne Schilder, usw. Man ist sich aber auch einig, dass faehige Personen mit viel Erfahrung nach reichlicher Ueberlegung es wagen duerfen, an einzelnen Stel- len bewusst gegen die bewaehrten Konzepte zu verstossen, insofern sie die Folgen andersweitig abfangen koennen. Man ist sich ebenso einig, dass sich alle anderen, vor allem alle Unerfahrenen, an die Regeln halten sollten. (Interessanterweise ist der Wunsch, gegen die Regeln zu verstossen, umgekehrt proportional zur Faehigkeit, einen solchen Verstoss zu handhaben.) Warum sollte die Softwareentwicklung eine Ausnahme davon sein? Warum sollten dort diese Regeln nicht gelten muessen? Ich sehe keinen Grund dafuer. Das mir vorliegende Programm befolgt die Regeln nicht. Es ist leider ein Musterbeispiel fuer Verstoesse, bzw. eher fuer Ig- noranz und Unkenntnis. Woher kommt die? Sie kommt zum einen aus der Informatik selbst. Von ein bisschen blindem, uebertriebenem Informations-Hiding und Modularisierung bei der Objektorientierten Programmierung abgesehen habe ich in meinem Studium niemanden von der Notwendigkeit von guter Archi- tektur, von gutem Stil, von Schoenheit und Eleganz reden hoeren (... von mir selber abgesehen, wie ich anmerken will). Wie soll es da einem Informatiker wichtig werden? Der andere Grund ist die Koerperlosigkeit von Software. Jeder von uns hat ein intuitives Gefuehl fuer die Statik von Gebaeuden (un- ten breit, oben schmal), das lernen wir schon als Kleinkind mit den Baukloetzchen. Jeder von uns kann zwei materielle Dinge in- tuitiv vergleichen. Jeder von uns erkennt z.B. die Symmetrie von Dingen. All diese Faehigkeiten koennen wir nur schwer auf Software anwenden. Ein stimmiges, durchdachtes Softwaregebaeude ist also aeusserlich kaum von einer Softwarebruchbude zu unter- scheiden. Fuer Nichtprogrammierer auch innerlich nicht. Aber selbst fuer Programmierer geht das innerlich nicht auf den ersten Blick. Gleichzeitig ist aber der Unterschied zwischen gutem und schlechtem Code wie der Unterschied zwischen einer organisierten Stadt (mit hierarchischen Verkehrswegen und strukturierten Vier- teln) und einem Ghetto. (Ich verwende hier den Begriff ``Ghetto'' als Ort des Chaos und der Notlage infolge fehlender Infrastruktur und Organisiertheit.) Es ist wie wenn man auf der gruenen Wiese eine Stadt plant und dann ein Ghetto baut. Natuerlich will niemand ein Ghetto haben, es ist nur eines geworden, bevor man es gemerkt hat, und dann hatte man keine Zeit mehr oder sah keine Notwendigkeit mehr die Scheisse aufzuraeumen. Die Softwareentwicklung ist wie die Stadtplanung, nur dass man oefter auf der gruenen Wiese beginnt. Analogien sind unbedingt noetig, da sonst Software unver- staendlich bleibt und damit die Ghettos nicht als solche erkannt und verhindert werden. Vergleiche haben immer ihre Schwachstel- len, dennoch denke ich, dass dieser mehr hilfreich als schaedlich ist: Die Notwendigkeit fuer Infrastruktur und Organisation bei Software waechst mit der Anzahl der Codezeilen in der gleichen Weise wie bei einer Stadt mit der Anzahl ihrer Bewohner. Dieses Bild passt erstaunlich gut, wenn man die Anzahl der Codezeilen und Bewohner gleichsetzt. Ein Script mit 50 Zeilen ist fast selbsterklaerend. Bei so wenig Code kann wenig so schief laufen, dass es ernsthafte Folgen haette (solange nicht mutwillig missbraucht wird). Auch ein Dorf mit 50 Einwohnern funktioniert fast ohne formale Organisation -- jeder kennt jeden. Bei 2.000 Zeilen bzw. Einwohnern ist die Situation schon anders. Da gibt es einen Buergermeister, Einkaufsmoeglichkeiten, Vereine, Freizeitangebote, oeffentliche Gebaeude, Baugebiete mit unter- schiedlicher Altersstruktur, usw. Auch ein 2.000-Zeilen-Programm braucht zentrale Infrastruktur: Einheitliche Datentypen, Fehler- behandlung, einen Coding-Style. Ein 10.000-Einwohner-Ort bzw. -Zeilen-Programm kommt mit nur dieser Infrastruktur an seine Grenzen. Mit Teilorten, Gewerbege- bieten, einem umfassenden Vereinswesen reicht der Ansatz, der bei 2.000 Einwohnern noch genuegte kaum mehr. So auch bei Software. 2.000 Zeilen kann man noch in eine Datei stecken, 10.000 Zeilen nicht mehr sinnvoll. Man verwendet also ein Buildsystem. Die An- zahl der Abhaengigkeiten von Fremdcode waechst meist. Informa- tionsflows muessen geplant angelegt werden. Die Interfaces muessen genauer und einheitlicher definiert werden. Dokumentation wird noetig. 100.000 Einwohner -- jetzt haben wir schon eine ausgewachsene Stadt. Der Unterschied zwischen Orten mit 10.000 und 100.000 Einwohnern entspricht dem zwischen Programmen mit 10.000 und 100.000 Zeilen Code: Statt einem Bauhof mit einer Handvoll Gemeindearbeitern sind Stadtwerke mit gut hundert Angestellten noetig. Statt Grund- und Realschule gibt es mehrere Gymnasien und eine Universitaet. Ein Nahverkehrsnetz muss eingerichtet werden. Der Muell wird nicht mehr in die naechste Stadt gefahren, sondern jetzt kommt der Muell des Umlandes hier in der eigene Muellver- brennungsanlage an. Und noch eine weitere Groessenordnung: 1 Million Einwohner. Damit ist man Landeshauptstadt, mit allen Konsequenzen. Software mit 1 Mio. Codezeilen spielt ebenfalls in einer anderen Liga. Nor- malerweise steht dann ein Unternehmen im Hintergrund, das Entwickler bezahlt. Vermutlich hat das Projekt dann auch mehrere Subprojekte hervorgebracht, die nur bestimmte Infrastrukturaufga- ben uebernehmen und selbst schon wieder tausende Codezeilen gross sind ... Ein Ghetto ist ein zu Ort mit zu wenig Infrastruktur. Ghettos sind normalerweise Sackgassen: einmal dort angelangt geht es weiter abwaerts, bis man es komplett aufgibt. Der Grund ist, dass das Code- bzw. Einwohnerwachstum ueblicherweise schneller ist als der Ausbau der Infrastruktur voran kommt. Jeder ernsthafte Ret- tungsversuch in dieser Situation erfordert massiv intensive Schritte zum grundlegenden Ausbau der Infrastruktur und zum Ein- fuehren von durchdringender Organisation. Solche Massnahmen sind bei Software ebenso schwierig umzusetzen wie bei Staedten. Darum werden sie selten angegangen. In der Folge beginnt Programmcode in der Realitaet eine Art Zerfall zu erfahren, wenn das auch fuer etwas, das grossteils mathematischen Formeln und einer musikal- ischen Komposition gleicht, eigentlich wesensfremd ist. Es bliebe ihm auch wesensfremd, wenn der Fokus auf Architektur, Stil und aehnliche Aspekte groesser waere. Indem man die Software aber als Wegwerfprodukt mit kurzer Lebenszeit ansieht, nimmt man den bereits waehrend der Entwicklung einsetzenden Verfall in Kauf. Das ist eine Philosophiefrage ... deren Bewertung aber voraussetzt, zu erkennen, dass ein frisch fertig gestelltes Pro- gramm ueblicherweise bereits vom Zerfall angefressen wird und aufgrund der fehlenden stabilisierenden Strukturen bald darunter leiden wird, ohne Aussicht auf Besserung, hoechstens auf Verlang- samung, bis zum Zusammenbruch. Die Folge dieser Philosophie ist das Beguenstigen von Softwarekrebs. Wenn ich von Stil rede und diese grossen Bilder zeichne, dann wird das Vielen zu wolkig sein. Im Konkreten haben sie doch kein Gefuehl dafuer, was das was ich meine bedeutet. Deshalb jetzt noch greifbarere Bilder aus dem Kleinen: Ein Programm zu schreiben ist wie in Buch zu schreiben in dem es keine Art von Verstaendnisschwierigkeiten oder Doppeldeutigkeit geben darf. Alles muss exakt auf den Punkt gebracht werden, in der richtigen Reihenfolge und mit guter Wortwahl. Jede Stelle an der der Leser nicht genau versteht was gemeint ist, ist ein Bug. Solch ein Text laesst sich nicht einfach so runterschreiben; er muss vielfach ueberarbeitet werden. Der Textaufbau muss der zu machenden Aussage entsprechen. Andernfalls wird der Leser eher missverstehen. Findet man erst spaeter heraus was man eigentlich sagen will (wie das beim Programmieren ueblich ist), dann muss der Text neu arrangiert werden. (Dieser Schritt wird oft unter- lassen ... mit schmerzlichen Folgen.) Meist zeigt sich erst im Lesen des Entwurfs, durch einen selbst oder durch andere, wo Um- bauten noetig sind. Das Ziel muss immer sein, fuer den Leser zu schreiben ... und insbesondere bei Programmcode ebenso fuer den nachfolgenden Entwickler, der das Programm umbauen und erweitern muss. Zum Abschluss noch ein Beispiel wie sich schlechter Code an- fuehlt, in Analogie zu einem Backrezept. (Code dieser Art ist durchaus verbreitet, wie jeder Programmierer bestaetigen wird.) Da steht irgendwo, dass wir drei Zuckerloeffel voll zum Teig ge- ben sollen. Wenn wir aufgepasst haben, dann erinnern wir uns vielleicht, dass gar keine drei Loeffel Zucker in der Zutaten- liste waren. Da die Zutatenliste aber hunderte Objekte umfasst und auf mehrere Stellen verteilt ist (und manchmal Zutaten gar nicht aufgenommen werden), erinnern wir uns selten. Vorhergehende Aha-Effekte haben uns aber gelehrt, dass wir bei diesem Code nie auf irgendetwas vertrauen sollte, sondern immer alles kontrol- lieren muessen. Deshalb schauen wir sicherheitshalber alle Zuta- tenlisten durch, ob irgendwo die drei Loeffel Zucker aufgefuehrt sind. Vielleicht ist der Zucker auch in Gramm angegeben, oder es ist eine groessere Menge, von der drei Loeffel uebrig bleiben. Damit ist es noetig alle Anweisungen zwischen der Zutatenliste und der aktuellen Anweisung nach einer Verwendung des Zuckervor- rats durchzuschauen. Aber da ist nichts -- kein Zucker. Mit etwas Glueck stossen wir aber in der Zutatenliste auf drei Loeffel Salz, die sonst nirgends genutzt werden (Wir haben das gesamte Rezept danach durchsucht.) ... Ah! Ein scheint wohl ein her- zhaftes Gebaeck zu werden. Warum uns das zuvor niemand gesagt hat ...? Ob das so richtig ist? Naja, nehmen wir's halt hin. Warum aber der Zuckerloeffel fuer das Salz verwendet wird, das koennen wir uns beim besten Willen nicht erklaeren. Vermutlich ist es ``nur'' eine ``kleine'' Ungenauigkeit. (So ein Problem loest man ueblicherweise nicht indem man den Zuckerloeffel durch den Sal- zloeffel ersetzt, wie sich das gehoert (Wir wuerden das natuer- lich so machen.), nein, es geht ja viel schneller wenn man nur eine Notiz anfuegt, dass man den Zuckerloeffel zum Salzschaufeln verwenden soll.) Spaeter wundern wir uns lange, bis wir herausfinden, dass mit der Tasse (die immer wieder uebergelaufen ist) eine Schale gemeint ist, die man aber letztlich gar nicht brauchen wuerde, wenn man die Zutaten in einer anderen Reihenfolge zusammenschuetten wuerde. Und schliesslich stellen wir fest, dass die wirre Anleitung fuer die Glasur (auf einem Salzgebaeck!?), die Verzierungen, oder was auch immer dieser letzte Schritt sein soll, gar nicht funk- tionieren kann: Sie ist noch nicht fertig geschrieben. Es sind nur Bruchstuecke zusammenkopiert und Anfaenge formuliert worden. Irgendwie hatten wir uns ja auch schon gewundert warum der Schreibstil so ungleich war ... Es ist notwendig, dass Nichtprogrammierer verstehen was Softwareentwicklung bedeutet, denn andernfalls werden sie kein Verstaendnis fuer die unbedingte Notwendigkeit von gutem Stil ha- ben. Aber auch die Masse der Programmierern muss sich diesbezueglich fortbilden. Ein hervorragender Weg dafuer fuehrt durch die Buech- er ``The Elements of Programming Style'' (Kernighan & Plauger) und ``The Practice of Programming'' (Kernighan & Pike) und durch die aktive Teilnahme in Free-Software-Projekten. Im Vergleich zu den Faehigkeiten, die man auf diesem Weg erlangen kann, bietet ein Informatikstudium nur Grundlagen. http://marmaro.de/apov/ markus schnalke