

Discover more from INUVEON
Softwareentwicklung unterschätzt
Fragst du dich auch oft, warum die Entwicklung von Software manchmal so lange dauert. Liegt es an den Technologien oder ist es eher der Tatsache geschuldet, wie wir an die Sache rangehen?
Es ist eine der größten Herausforderungen in der Entwicklung von Software: Keep it simple!
Bildquelle: Adobe Stock, Anze
Oft stehen wir vor der Herausforderung, gleichzeitig Features abliefern zu müssen und trotzdem wartbaren und gut strukturierten Code zu produzieren. Zweiteres lebt vor allem von der Einfachheit. Oft ist das im ersten funktionierenden Wurf gar nicht so leicht möglich. Zeit, um zu reflektieren und den Code zu verbessern, wird in vielen Vorgehensmodellen überhaupt nicht berücksichtigt. Vergessen wird dabei allerdings, dass genau das oft der Schuss ins eigene Knie ist. Komplexer Code ist unwartbarer Code. Genau das kann aber später durchaus teuer werden und damit Zeit, Nerven und Ressourcen kosten. Dann nutzen auch aufwendige Dokumentationen nichts. Generell vertrete ich die Auffassung, dass Code, der dokumentiert werden muss, damit er verstanden wird, nur schlechter Code sein kann. Sorry, das klingt vielleicht hart. Aber leider ist es so.
Code wird unübersichtlich, wenn zu wenig über Modellierung nachgedacht wurde und dadurch zu viele unnötige Abhängigkeiten entstehen. Oftmals wird auch versucht, wiederverwendbaren Code abzuliefern, obwohl die Notwendigkeit gar nicht besteht. Was ich damit meine ist, das es durchaus angebrachter ist, über Vereinfachungen in der Implementierung nachzudenken, als Code unnötig komplex zu machen, weil technische Verbesserungen eingebaut werden, die aber keinen erkennbaren Mehrwert bringen.
Software-Entwicklung ist komplex, häufig aber auch unnötig komplex, weil die Beteiligten dazu neigen, Dinge in Anforderungen hineinzuinterpretieren, die nicht angefordert worden und damit irrelevant sind. Ich meine damit keinesfalls, dass Entwickler nicht mitdenken sollen. Ganz im Gegenteil. Kommunikation mit den Beteiligten ist ein essenzieller Aspekt, damit gute Software überhaupt entstehen kann. Ich habe oft erlebt, dass Anforderer meinten, ein Feature zu benötigen, welches sie aber bei genauerer Betrachtung gar nicht brauchten. Die Implementierung wäre sehr aufwendig und teuer, aber schlussendlich unnötig gewesen. Es war also gut, dass ich hartnäckig hinterfragt habe. Es gibt nichts Schlimmeres als Zeit in ein unnötiges Features zu investieren, welches am Ende die Lesbarkeit und Qualität des Codes verschlechtert.
Aber zurück zu den Gegebenheiten: Die Erstellung von Software wird unterschätzt und meiner Ansicht nach leider immer noch zu häufig auf das Beherrschen von Programmiersprachen und der Fähigkeit, bestehende Komponenten richtig konfigurieren zu können, reduziert. Es ist genau die Art und Weise, wie Head-Hunter nach sogenannten Kandidaten für ein Projekt suchen. Für gewöhnlich fragen sie nach Tools, Technologien und die Beherrschung von Programmiersprachen. Oder noch pauschaler: “Kannst du Azure?” “Hä, what?” Manchmal sind zusätzlich branchenspezifische Kenntnisse von Interesse. Oder auch Abschlüsse und Zertifizierungen von Technologie-Anbietern wie Microsoft oder Amazon. Alles schön und gut, aber in der Praxis, um brauchbare Lösungen zu schaffen, meist wenig hilfreich. Diese Herangehensweise ist exakt das, was unser westliches Schulsystem hervorbringt. Nicht der stets Hinterfragende, Mitdenkende und Kreative wird mit guten Noten belohnt, sondern derjenige, der Definitionen und nachlesbares Wissen am besten auswendig gelernt hat.
Wäre ich auf der Suche nach Verstärkung im Projekt, wäre nicht eine dieser Fragen irgendwie besonders relevant. Mich würden andere Eigenschaften viel mehr interessieren. Es ist nicht wichtig, ob jemand auswendig auf Anhieb weiß, wie das Terraform-Skript für das Rollout eines Fargate-Services auf AWS genau aussehen muss. Das kann man in der Dokumentation nachlesen. Wissen dieser Art basiert nicht auf Konstanz, weil der Hersteller jederzeit Änderungen vornehmen können. Wichtiger ist, dass die Konzepte dahinter verstanden wurden und derjenige in der Lage ist, Know-how im richtigen Moment abzurufen und umzusetzen. Manche Manager versprechen sich von dem Zusammenwürfeln auf verschiedene Wissensgebiete spezialisierter Personen einen Benefit, aber die große Vision wird dabei oft aus den Augen verloren, weil jeder autonom vor allem auf seinen technischen Bereich fokussiert ist. Das ist nicht grundsätzlich falsch oder schlecht, aber führt dazu, dass zu wenig offenen in den kreativen Austausch gegangen wird. Der Blick auf das Ganze sollte nie verloren gehen. Manchmal müssen wir uns mehr darauf besinnen, dass Softwareentwicklung nicht aus dem stupiden Abarbeiten von Tickets und das Produzieren von Code besteht. Sie ist vor allem eine kreative Aufgabe, die eine hervorragende Kommunikation mit anderen Beteiligten unabdingbar macht. Meine Kriterien für die Suche nach guten Mitstreitern in einem Projekt wären vor allem Kommunikations- und Kritikfähigkeit, Flexibilität und Lernbereitschaft und die Bereitschaft, sich auf sich ändernde Gegebenheiten einzulassen.
Das Ziel muss allgegenwärtig sein. Es bringt nichts, auch nur eine Zeile Code zu schreiben, wenn nicht klar, was der Nutzen ist. Aber genau das passiert, wenn Programmierer nur programmieren. Es geht nicht um Schuldzuweisungen, sondern darum, dass diese Situationen immer wieder zustande kommen, weil der Wert von Software-Entwicklung unterschätzt und wie oben schon erwähnt leider oft auf das Beherrschen einer Programmiersprache reduziert wird.
Jeder im Team muss die Vision des Produktes oder Projektes verstehen und verinnerlichen. Die Modelle müssen gut durchdacht werden. Das ist viel entscheidender, als zu glauben, man könne durch mehr Manpower schneller fertig werden. Das Gegenteil ist der Fall. Je mehr beteiligt sind, desto schwieriger wird es, einerarbeiten gemeinsames Verständnis zu entwickeln. Ein Team braucht auch Zeit, sich aufeinander einzustellen und eine gemeinschaftliche Idee zu erarbeiten. Das geht eben nicht über das Verteilen von Tickets im Scrum-Meeting. Prozess ist wichtig. Aber Prozess auf Biegen und Brechen nur um des Prozesses Willen ist keine gute Idee.
Meine größte Inspiration der letzten 15 Jahre bessere Software zu schreiben, ist Domain-Driven Design (kurz: DDD). Mich hat dieser Ansatz dazu gebracht, vollkommen anders an die Entwicklung von Software heranzugehen. Ich habe erkannt, dass viele Probleme dadurch entstehen, dass Modelle unvollständig und inkonsistent sind oder manchmal gar nicht erst existieren. Das ist dann der Fall, wenn einfach nach dem Motto: “Mach mal einfach, damit es geht” agiert und große Projekte realisiert werden. Tritt ein Bug auf, wird irgendwo ein “If” hinzugefügt und später ein weiteres, bis keiner mehr versteht, warum eigentlich. Es ist am Ende so, als hätte jemand mit dem Bau einer Garage begonnen, aber sich später überlegt, auf demselben Fundament einen Wolkenkratzer zu bauen. Dass dies nicht funktionieren kann, ist sicher jedem klar. Aber in der Entwicklung von Software wird oft erwartet, dass genau das funktionieren sollte.
Bildquelle: Adobe Stock, Kruwt
Im DDD-Ansatz geht es nicht darum, ein System irgendwie zum Laufen zu bringen, sondern wirklich zu verstehen, was gebaut werden soll. Ein Schlüssel dafür sind verständliche Modelle der Problemdomäne und die Auseinandersetzung mit dem konkreten spezifischen Problem. Dies bedeutet Vertiefung in fachliche Belange. Habe ich diesen Ansatz verinnerlicht und kann mich fokussieren, spielt es keine Rolle, in welcher Branche ich gerade arbeite. Es ist irrelevant. Ich habe weiter oben geschrieben, dass Projekt-Agenten oft nach Branchenerfahrung fragen. Was soll die nützen, wenn der Kandidat vorher in einer Branche tätig war, nie aber wirklich Core-Domains modellieren musste und nie wirklich verstanden hat, was er baut, sondern immer nur Jira-Tickets abgearbeitet hat. DDD ist der Schlüssel, einen anderen Blick auf die Entwicklung von Software zu bekommen, Domänen zu verstehen und spezifische Lösungen zu erarbeiten, um unnötige Komplexität zu vermeiden. Es gibt keine Universallösung für alles. Wäre das so, könnten wir einen Algorithmus schreiben, um Softwarelösungen automatisch zu erstellen. Das geht aber eben nicht.
Der Subtitel “Tackling complexity in the heart of software” von Eric Evans Buch “Domain-Driven Design” hatte mich sofort gecatcht, denn das ist der Kern des Problems, mit dem auch ich sooft zu kämpfen hatte. Egal, wie sehr wir uns anstrengten, die Komplexität wuchs stets schnell an, manchmal in Wochen, mal in Monaten oder wenigen Jahren. Änderungen wurden riskant, Wissen war implizit und Abhängigkeiten zwischen den Komponenten und eingesetzten Frameworks nicht erkennbar.
Die Herausforderung liegt nun darin zu sensibilisieren für das, was wir als Developer machen und eigentlich tun sollten. Es geht nicht darum, in kurzer Zeit so viel Code wie möglich zu produzieren und irgendetwas irgendwie zum Laufen zu bringen. Die Aufgabe ist, genau zu verstehen, was gebaut werden soll. Aspekte wie Kommunikation, Diskussion und vor allem Modellierung müssen mehr in den Vordergrund rücken. Technische Lösungen können nur aus der intensiven Auseinandersetzung mit den fachlichen Problemen hervorgehen und nicht anders herum. Es bringt also nichts, wenn sich Unternehmen darum bemühen, vorab Konzernrichtlinien zu entwerfen, die dann zur Lösung aller zukünftigen Probleme genutzt werden sollen. Das ist kontraproduktiv. Entwickler sollten konzeptionell verstehen lernen und dann konkretisieren und in der Lage sein, unterschiedliche Technologien und Programmiersprachen zu nutzen. Das häufig angeführte Argument der Verantwortlichen, man müsse unternehmensweite Vorschriften haben und Technologien festlegen, weil sonst die Gefahr bestehen würde, dass bei Ausfall von Ressourcen keine anderen übernehmen könnten, halte ich für Unsinn. Das Risiko liegt nicht in der Nutzung unterschiedlicher Technologien, sondern viel mehr in fehlender Modellierung, die aus ungenügenden Wissen über die Domäne resultiert. Es ist also an der Zeit, den Blickwinkel zu ändern.
PS: Im nächsten Beitrag wird es wieder viel Code geben.
Softwareentwicklung unterschätzt
Ja, Softwareentwicklung wird unterschätzt - aber von allen Beteiligten😁 Kunden unterschätzen sie, weil sie nicht verstehen, dass etwas so Immaterielles so schwer zu verändern sein kann. Manager unterschätzen sie aus demselben Grund und auch noch, weil sie glauben, top talent eingekauft zu haben, das doch schnell&zuverlässig sein muss. Und Softwareentwickler unterschätzen sie, weil sie auf die Herstellung von Softwareverhalten getrimmt sind; deshalb die Obsession mit Technologien.
Nach 14 Jahren Clean Code Fokus glaube ich, das lässt sich nicht ändern - weil darin eine Wahrheit steckt. Entwicklung (!) bedeutet, dass man nicht weiß, wie (!) (gar, ob!) Anforderungen erfüllbar sind. Dieses Problem zu lösen, saugt dann alle Energie auf. An Nachhaltigkeit nicht zu denken.
Verhaltensanforderungen überhaupt zu erfüllen braucht ein anderes Bewusstsein als sie nachhaltig zu erfüllen. Beides muss geschehen, nur weitgehend getrennt.
Das braucht unterschiedliche Mindsets, deshalb evtl unterschiedliche Leute, deshalb unterschiedliche Phasen/Zeiten des Fokus. In TDD steckt diese Wahrheit in der Trennung red-green-refactor:
- red: Problem verstehen
- green: funktionale Lösung finden
- refactor: nachhaltige Lösung erarbeiten
Diese Trennung im Kleinen muss ins Große überführt werden.
Für green existieren Begriffe wie Prototyp od Spike, aber die treffen es nicht genau. Sie gehören zu green, doch sie beziehen sich nicht auf Produktionscode. Deshalb sind sie in Ungnade gefallen. Nachhaltigkeit wird solange nicht selbstverständlich hergestellt werden, solange die Phasen nicht gut begrifflich unterschieden werden. Wo uns die Worte fehlen, fällt das Denken u Kommunizieren schwer.
Vorschlag:
- red code: Code, der dem Problemverständnis und dem Lösungsentwurf dient. Prototyp, Spike, Test. All das ist kein Produktionscode.
- green code: Produktionscode, der die Lösung kurzfristig implementiert; funktionale u nicht-funktionale Anforderungen sind erfüllt.
- white code: Produktionscode, der nachhaltig ist. White code entsteht durch Refactoring von green code. Oder auch mal durch einen rewrite.
Produzenten dieser Codes stehen im Austausch miteinander. Sie dürfen einander nicht ignorieren, aber auch nicht behindern.
Ja, ich denke, diese Trennung muss sein. Sie folgt dem Single Responsibility Principle: jede Entscheidung sollte gekapselt werden. In den Phasen sind die Entscheidungen/Prinzipien sehr unterschiedlich. Die Ziele sind anders. Keines hat Vorrang; alle müssen erreicht werden. Nicht nur Yin und Yang, auch Yong😂