Mastodon

Software Engineering - My experiences

This text is only available in german.

Nach meinem 6-monatigem Praktikum in einem großem deutschen Unternehmen möchte ich in diesem Bericht meine Erfahrungen zusammen fassen. Dabei spielen Thema und Umfeld meiner Aufgabe keine Rolle; dieser Bericht bezieht sich vor allem auf die sehr umfangreichen Gebiete der Teamarbeit und der Softwareentwicklung. Ich möchte also, ohne Anspruch auf Allgemeingültigkeit, meine Erfahrungen unsortiert und unpriorisiert formulieren. Die Zahlen vor den einzelnen Punkten kommen direkt aus /dev/random.

1. “Es gibt kein endgültiges Konzept.”

Eine meiner ersten Erfahrungen steht in starkem Widerspruch zu dem, was man in einigen Büchern lesen und Vorlesungen hören kann: Es gibt nicht DAS Konzept, nach dem implementiert wird. Meines wurde besonders in den ersten Wochen stetig neu angepasst, verbessert und verfeinert. Am Anfang betraf das die Lösungsidee an sich, später änderten sich nur noch Implementierungsdetails.

Ist es also einer Software erlaubt, sich weiterzuentwickeln, wird sich das umgesetzte Konzept mit jeder Version vom ursprünglichen entfernen.

2. “Mach es generischer!”

Mein erstes Objektmodell konzentrierte sich sehr stark auf das Problem und die Fachobjekte, war also sehr speziell. Das ist an sich nicht schlecht, nur war abzusehen, dass dieses Modell sehr schwer erweiterbar ist. Es wurde also generalisiert. Somit fielen einige Objekte zusammen, das Modell wurde kleiner und übersichtlicher. Änderungen, die tatsächlich noch während des Projektes auftraten, konnten viel einfacher eingepflegt werden.

Jede Idee ist stets generischer formulierbar. Mit steigendem Abstraktionsniveau fallen Fragmente zusammen, sodass das Prinzip einfacher wird.

3. “Mach es spezieller!”

Erfahrung 2 impliziert, dass ein möglichst abstraktes Objektmodell das Ziel jedes Designs ist. Natürlich ist das nicht der Fall.

So habe ich mein Konzept einem anderen, nicht an der Planung beteiligten Kollegen vorgestellt. Dieser schlug vor, sehr viele Objekte zusammenzufassen und so ein neues, hoch-abstraktes Konzept zu entwickeln. Dieses würde zwar weniger Objekte aufweisen, aber deutlich schlechter lesbar sein. Die Fachlichkeit, also das, was das Modell eigentlich umsetzen soll, sprach einfach nicht mehr aus den Objekten.

Für wen soll das Objektmodell also sein? Soll es so abstrakt, performant und maschinennah wie möglich sein, um die Transition in den Computer einfacher zu machen? Oder soll das Modell stattdessen dem Menschen dienen, der die Software zwei Jahre nach Auflösung des ursprünglichen Projektteams warten soll? (Das wird passieren!)

4. “Der Unterschied zwischen einem guten und einem schlechten Programmierer liegt deutlich über dem Faktor 10.”

Beim Einstellungsgespräch wurde ich gefragt, ob ich Java programmieren könnte. Natürlich programmierte ich seit dem ersten Semester in dieser Sprache, besuchte entsprechende Vorlesungen und schrieb kleinere Projekte darin. Mit gutem Gewissen sagte ich also vorsichtig “Ja”. Schon nach kurzer Zeit stellte sich heraus: Ich kann kein Java, jedenfalls nicht im Maßstab des Teams und im Sinne des Wortes “halbwegs beherrschen”. Wahrscheinlich kann kein Absolvent irgendeine Programmiersprache.

Der Produktivitätsunterschied, unabhängig von der notwendigen fachlichen Einarbeitung, liegt laut Tom De Marco beim Faktor 10. Als ich das in seinem Buch “Der Termin” (übrigens uneingeschränkt empfehlenswert) gelesen habe, habe ich es nicht geglaubt. Jetzt bin ich der Meinung, dass der Unterschied nur im günstigsten Fall beim Faktor 10 liegt. Meistens sollte er deutlich darüber liegen.

Was an dieser Stelle vielleicht noch anzumerken ist: Ich stimme De Marco zu, dass bei einem solchen Unterschied die Lösung natürlich NICHT darin liegen kann, zehn schlechte anstatt eines guten Programmierers in ein Projekt zu setzen. Diese würden ihre ohnehin schlechte Performance nur noch verschlechtern, da der organisatorische Overhead wie Koordination, Arbeitsplätze etc. viel größer wäre. Der nächste Punkt dokumentiert eine alternative Lösung.

5. “Der Entwickler altert sehr sehr schnell. Aber es gibt einen Jungbrunnen.”

Sämtliche von mir besuchten Übungen und Vorlesungen haben im besten Fall an der Oberfläche von dem gekratzt, was man offensichtlich als Softwareentwickler braucht. Das hat zum einen damit zu tun, dass es nicht der Anspruch einer Universität ist, Entwickler auszubilden. Zum anderen liegt es aber auch daran, dass neue Entwicklungen unglaublich schnell erscheinen, von der Community bewertet werden und dann entweder wieder verschwinden oder sich zu etwas Größerem entwickeln. Damit ein Entwickler langfristig produktiv arbeiten kann, muss er mit dieser Entwicklung Schritt halten. Das ist durch eine ständige Weiterbildung, z.B. durch vom Arbeitgeber bezahlte Schulungen, in der Abteilung vorhandene Fachliteratur und aktuelle Fachzeitschriften möglich.

Das Abo einer Fachzeitschrift kostet, grob überschlagen, 100 € im Jahr. Ist auch nur in einer dieser Zeitschriften ein Plugin, Bibliothek oder Algorithmus, der auch nur einem einzelnen Teammitglied lächerliche zwei Stunden Arbeit spart, hat sich das Abo damit amortisiert. Natürlich wird es über den genannten Zeitraum bei einer Teamstärke größer eins entsprechend größere Effekte geben.

Das bloße Auslegen von Büchern und Zeitschriften ist jedoch noch nicht die ganze Lösung. Dem Team muss Zeit gegeben werden, diese auch zu lesen. Zusätzlich dazu können die Teamsitzungen zur Weiterbildung genutzt werden: 10 Minuten zur Vorstellung einer neuen Technik durch ein Teammitglied (ungleich Teamleiter; es muss ein Entwickler sein) sind in jeder noch so Deadline-geplagten Zeit unterzubringen. Dabei soll kein kompletter Überblick über ein Themenfeld gegeben, aber Vor- und Nachteile sowie Einsatzfähigkeit aufgezeigt werden. Verspricht das Vorgestellte Arbeitserleichterung, werden Entwickler sich von ganz allein damit beschäftigen.

6. “Es gibt mindestens $AnzahlMitarbeiter Projekte in einem Projekt.”

Jeder Mitarbeiter hat (und muss haben) seine eigene Ansicht des Projektes und der Abläufe. Zusätzlich hat jedes Teammitglied in seinem Teilbereich eine viel stärkere “Auflösung” der Prozesse. So erscheint es nur auf den ersten Blick unlogisch, dass das Projekt als Ganzes inklusive seiner Abläufe von jedem Teammitglied anders gesehen wird. Teilweise gibt es nur leichte Abweichungen in den Erklärungen, teilweise ganz erhebliche Unterschiede.

Das Auftreten und der Umfang dieses Phänomens scheinen in direktem Zusammenhang zur Komplexität und zur Anzahl der Mitarbeiter eines Projektes zu stehen. Ich selbst habe in einem sehr kleinen Software-Projekt mit drei Studenten diese Erfahrung nicht gemacht. In einem Verein, in dem ca. zehn Menschen zum Kern gezählt werden können, traten erste Unterschiede in zum Beispiel der Erklärung der ablaufenden Prozesse auf. Da ließ man mal etwas weg, dichtete etwas anderes dazu, im großen und Ganzen kam dann aber doch das richtige heraus. Während meines Praktikums, das Team bestand aus 14 Entwicklern und die Software war meiner Ansicht nach recht komplex (350.000 LOC ohne Kommentare und Leerzeichen), gab es schon erhebliche Verallgemeinerungen.

Diese Beobachtung ist, denke ich, neutral zu bewerten. Es ist nicht negativ, wenn Mitarbeiter unterschiedlicher Auffassung über ein Projekt sind, solange eine gewisse Schnittmenge in den Konzepten existiert.

7. “Mach Kaffeepausen mit den Kollegen!”

Das liest sich auf den ersten Blick kontraproduktiv und schreit nach Erklärung.

In vielen Projekten, vielleicht sogar den meisten, gibt es so gut wie keine Entwicklerdokumentation. Der Großteil des Wissens ist intrinsisch, befindet sich also in den Köpfen der Mitarbeiter (noch ein Grund, sie nicht einfach so rauszuwerfen). Der beste Weg des Wissensaustausches ist, neben dem sehr kostspieligen Anfertigen einer vernünftigen Entwicklerdoku, mit den Menschen zu reden. Die meisten Ratschläge, entscheidende Bibliotheken, Architektur- und Programmierrichtlinien sowie Shortcuts für die Entwicklungsumgebung habe ich beim Kaffee / Tee / Gespräch mit den Kollegen bekommen. Zusätzlich werden in solchen Situationen aktuelle Probleme bereichsübergreifend besprochen und können durch den neuen Input und durch das einfache Schildern des Problems selbst gelöst werden. Ich habe das oft erlebt und werde Kaffee- und Gesprächspausen zu einer Angewohnheit machen.

Natürlich möchte ich an dieser Stelle alle Teamleiter beruhigen: Wenn den ganzen Tag geredet wird, entsteht trotzdem kein Code. Es muss also noch gearbeitet werden. ;)

8. “Softwareentwicklung ist nicht-deterministisch.”

Ein Computer macht genau das, was man ihm sagt. Nicht mehr, nicht weniger. Auf den ersten Blick impliziert dies, dass es zur Lösung eines Problems genau eine Anordnung von Befehlen gibt, die das Problem lösen werden. Das stimmt jedoch absolut nicht. Es gibt für jedes Problem mindestens drei Mal so viele Lösungen, wie einem auf Anhieb einfallen.

So schön der Gedanke auch ist, einfach einen anderen Weg zu wählen, wenn eine Idee in eine Sackgasse läuft. Leider erhöht diese Vielfalt andererseits den Wartungsaufwand, da die Gedanken des ursprünglichen Entwicklers erstmal verstanden werden möchten.

9. “ Der genutzte Softwareentwicklungsprozess muss schriftlich vor dem Beginn eines Projektes allen Entwicklern vorliegen.”

Wie ich bereits erwähnte, habe ich während meines Praktikums mehr als einen Prototyp geschrieben. Die letzte Änderung umfasste ganz und gar die Architektur des ganzen Programmes. Natürlich sollte die klar sein, noch bevor man überhaupt eine Zeile codet. Niemandem fiel auf, dass ich in einer ganz anderen Architektur dachte und entwickelte, da es keinen Prozess gab, der eine solche Prüfung unterstützt hätte. Bei gängigen Softwareentwicklungsprozessen gibt es an verschiedenen Punkten Überlegungen bezüglich der Architektur. Da “mein” Projektteam schon seit Jahren sehr gut miteinander arbeitet, braucht es keinen schriftlich festgehaltenen Prozess mehr. Jeder kennt seine Aufgaben, jeder kennt die Abläufe, jeder kennt die kleinen sozialen Fallen, in die man nicht tappen sollte. Leider ist das neu ankommenden Kollegen natürlich alles nicht klar.

Meine Erfahrung ist also: Es gibt immer einen Prozess, auch wenn er nicht schriftlich festgehalten wird. Neue Kollegen werden sich, wenn das der Fall ist, sehr schwer mit der Einarbeitung tun und es wird noch Monate nach einer Teamumstellung ungünstige Situationen geben. Eine Funktionalität wird neu implementiert, ob wohl sie in einer dem ganzen Team bekannten Bibliothek auf Nutzung wartet. Bestimmte Use-Cases werden von den Anforderungen nicht erfasst, da sie viel zu “normal” sind und sie jeder kennt. Jeder, außer der neue Kollege.

Es ist also wichtig, dass man wenigstens einen Grundsatz der Prozesse und “Normalitäten” dokumentiert. Dennoch ist es ebenso wichtig, dies nicht in einem mehrere hundert Seiten starken “Hand”buch umzusetzen. Dieses Buch wird niemand lesen, bis auf den Autor.

10. “Eine sich weiterentwickelnde Software muss in bestimmten Abständen komplett neu geschrieben werden.”

Ich möchte diesen Bericht mit einer der interessantesten und kontroversesten Erfahrungen schließen: Der notwendigen Neuentwicklung in regelmäßigen Abständen.

Das von mir mitbearbeitete Projekt existiert seit fast einem Jahrzehnt und ist längst über sämtliche Anforderungen im ursprünglichen Pflichtenheft hinausgewachsen. Nicht nur wurden etliche Anforderungen zusätzlich umgesetzt, es wurden genau so viele geändert. All diese Vorgänge haben aus der Software, sofern ich das mit meinem sehr begrenzten Einblick beurteilen kann, einen riesigen, komplizierten Spaghetti-Code-Haufen gemacht, dessen Wartungsfähigkeit mir persönlich ein Rätsel ist. Ich übertreibe das jetzt bewusst, doch wird es wohl das Schicksal jeder derart alten Software sein. Meiner Meinung nach ist es nicht möglich, dieses Projekt umfangreich umzuschreiben oder bei einer Neukonzeptionierung große Teile des Codes “mitzunehmen”. Das funktioniert nur sehr begrenzt.

Kein Konzept kann alle in der Zukunft auftretenden Änderungen berücksichtigen. Spätestens neue Anforderungen können und werden wahrscheinlich das ursprüngliche Konzept zerstören. Je mehr solcher Anforderungen eingepflegt werden, desto dringender wird die komplette Neukonzeptionierung des Projektes, verbunden mit kompletter Neuimplementierung.

Ich visualisiere mir diesen Punkt mit einem starken Gummiband, welches man über Jahre dehnt. Am Anfang lässt es sich sehr leicht ziehen, doch verlangt jeder weitere Zentimeter ein Vielfaches der Kraft des vorherigen.


Wie gesagt soll dies ein Einblick in meine Erfahrungen sein. Ich bin mir sicher, dass etliche andere (und vor allem erfahrenere) Entwickler andere Erfahrungen gemacht haben, was OK ist. Jedes Projekt ist anders, jedes Team entwickelt sich. Ich bin gespannt, wie ich über diese Punkte in einem halben Jahr, nach Abschluß meiner Diplomarbeit, denke. Vielleicht gibt es dann einen neuen Bericht …