editorial

Seit rund 70 Jahren gibt es Software Programmierer. In dieser Zeit sind viele Computer Sprachen und Frameworks entstanden, einen wirklichen Fortschritt haben sie aber nicht gebracht. Oft brachten sie Einschränkungen um vermeintlich bessere Software zu erzwingen. Tatsache ist aber, dass wir heute immer noch mit denselben Problemen zu kämpfen haben, wie vor zig Jahren: Die Software verkommt, kann immer schwerer gepflegt werden und muss ab einem gewissen Zeitpunkt durch komplett neue Software ersetzt werden, obwohl sich die fachlichen Anforderungen kaum verändert haben. Warum haben wir es nicht geschafft, uns in dieser Hinsicht weiter zu entwickeln? Aufgrund der Veränderungen, mit denen wir in unserem direkten Umfeld konfrontiert sind, scheint dies gerade zu grotesk. Wir, die Software Entwickler, haben es nicht geschafft, die Zeit zu nutzen und das Problem zu lösen. Auf die Gründe hierfür aber auch auf mögliche Lösungen möchte ich in diesem folgenden Artikel eingehen.

Die folgenden Erkenntnisse sind nicht auf meinem Erfahrungsschatz gewachsen, noch konnte ich sie im vollen Umfang über die Zeit beobachten. Vielmehr gewinne ich sie über Vorträge Bücher und Online Seminare. Die Quellen Angabe hierzu befindet sich am Ende des Artikels, aber die Namen der der Personen, die mich am meisten beeinflusst haben, kann ich hier schon einmal aufzählen: Robert 'Uncle Bob' Martin, Kevlin Henney, Peter Hruschka, Gernot Starke, Frank Buschmann und einige mehr. Maßgeblich sind aber einige talks von Uncle Bob. Weil diese aber naturgemäß in Englischer Sprache gehalten wurden und einige Kollegen das Deutsche besser konsumieren können, habe ich es mir zur Aufgabe gemacht, dieses Thema mit eigenen Worten auf einer fremden Grundlage zu erörtern. Gegenüber dem Original von Uncle Bob kann ich dabei also nur verlieren.

Uncle Bob

  • Robert C. Martin (1952)
  • Books
    • Agile Software Development: Principles, Patterns and Practices (2002)
    • Clean Code: A Handbook of Agile Software Craftsmanship (2009)
    • The Clean Coder: A Code of Cunduct for Professional Programmers (2011)
    • Clean Architecture: A Craftsman's Guide to Software Structure and Design (2017)
  • Co-Author of Agile Manifesto

Artikel lesen

1. Warum ist es jetzt wichtig, gute Architektur zu machen?

Das Durchschnittsalter der Software Entwickler ist weltweit in den jungen 30ern. Die Computer-Industrie ist mit maximal 70 Jahren relativ jung. Die Anzahl der Software-Entwickler verdoppelt sich rund alle 5 Jahre. Viele ältere Programmierer wandern in das Management oder in die Wirtschaft ab. Es ist aus demographischer Sicht nicht damit zu rechnen, dass in naher Zukunft viele erfahrene Software Entwickler eine Wende schaffen, hin zu Software, die aufgrund ihrer Struktur langlebig, leicht zu adaptieren und einfach zu warten ist.

Computer vor rund 35 Jahren

4K RAM, 12 Bit, 32K Disk, 1kW Power, 20.000$, 300.000 instructions a second

Computer heute

4 Core at 2,6GHz, 64 Bit, 16GB RAM, 1TB SSD, 85W Power, 100 Mal kleiner, 3.000$, 10 billions instructions a second

Ein Entwickler muss mit diesem Tempo mithalten und die entsprechenden technischen Herausforderungen annehmen. Dabei fällt es schwer sich auch um die Transformation zu einer besseren Software(-Architektur) zu kümmern.

Die Verantwortung wächst, denn Software ist heutzutage in jedem Ding. In einem durchschnittlichem Auto läuft Software mit einem Umfang von 100 million lines of code. Selbst in den unscheinbarsten Geräten läuft Software. Die Auswirkung von Fehlern in Software wird immer weit reichender. Wenn die Software Entwickler nicht wollen, dass jemand anderes mittels Regulation die Verantwortung übernimmt, müssen sie sich selbst um Standards und Codexe kümmern. Bei komplexer Software wird hier die Architektur eine immer entscheidendere Rolle spielen.

2. Was ist Architektur?

Wenn man auf die Dateistruktur von Software sieht, sieht man meist zuerst die Struktur des verwendeten Frameworks hinter der sich die Architektur der eigentlichen Anwendung versteckt. Das Framework sollte aber bei der Architektur eine untergeordnete Rolle spielen, da es Mittel zum Zweck ist, sich schnell ändert und eine große externe Abhängigkeit darstellt.

Hat das Web die Software Architektur verändert?

If you believe the web constrains your architecture, you have lost the war from the beginning. (Robert C. Martin)

Das Web ist nur eine neue Art der Ein- bzw. Ausgabe.

Wenn man sich den Bauplan für ein Gebäude ansieht, erkennt man meist den Verwendungszweck sofort. (z.B. Bibliothek, Kirche, etc.). Warum ist das bei Software nicht auch so? Stattdessen sehen wir das Framework, also die Hämmer und Nägel mit der sie gebaut wurde. Auf einem Bauplan ist von Hämmern und Nägeln keine Rede.

The architecture of an application is driven by its usecases. ('Object-Oriented Software Design' von Ivar Jacobsen)

Der Begriff des Usecase wurde in den Jahren immer verwaschener, da er für Tools und wirtschaftliche Entscheidungen mißbraucht wurde.

Ein usecase beschreibt all die Wege, auf denen man ein System benutzen muss, um ein bestimmtes Ziel für einen speziellen Benutzer zu erreichen. Alle usecases für ein System beschreiben alle nützlichen Möglichkeiten, ein System zu benutzen und beschreiben den Wert, den das System darstellt.

3. MVC Architektur - ursprünglich

MVC im kleinen

Die MVC (Model View Controller) Architektur wurde von Trygve Reenskaug erfunden und war ursprünglich nicht als Web-Architektur gedacht, sondern vielmehr für viel kleinere Einheiten wie buttons etc.

Wie in der folgenden Skizze zu sehen ist, verwenden View und Controller das Model. Das View hat das Model subscribed, so dass bei einer Änderung durch den Controller im Model das View sich selbst darum kümmern muss, wie es dies mit bekommt.

4. MVC Architektur - heute im Web

MVC im Großen

Bei modernen MVC Architekturen, wie sie heute eingesetzt werden, verwenden viele Controller und viele Views viele Business Objekte (Models). Dadurch ist nicht klar abgegrenzt, welche Funktionalität liegt im Controller/View und welche beim Model.

Aufgrund dieser ungenauen Zuordnung ist das MVC nicht das Allheilmittel für gute Architektur. Im Kleinen werde ich später auf eine Lösung mit einem Model View Presenter zurück kommen.

5. Welche Rolle spielt die Datenbank bei einer Architektur?

Die Datenbank ist ein Detail. Sie ist eine Möglichkeit Daten relativ persistent abzulegen. Die Datenbank ist damit ein Mittel und darf nicht die Architektur bestimmen. Datenbanken wurden erfunden, um einen schnellen Zugriff auf gefilterte verteilte Daten zu bekommen unter der Prämisse, dass man einen langsamen persistenten Speicher und einen kleinen flüchtigen Speicher hat.

Diese Voraussetzung gibt es heute nicht mehr. Heutzutage ist aufgrund der verschwindenden Unterschiede zwischen SSD Platten und RAM diese Voraussetzung nicht mehr gegeben. Es ist sogar eine quasi unendliche Menge an RAM vorstellbar.

Wenn die Tabellenstruktur in Frage gestellt wird, kann man sich ganz andere Möglichkeiten überlegen. Anstelle des State könnte man die Transactions speichern. Möchte man den aktuellen State eines Datums, muss man nur alle Transactions dieses Datums durchlaufen und gelangt zu der Information. Ein System, das nach diesem Prinzip arbeitet, ist zum Beispiel ein SCCS (Source Code Control System) wie Git oder SVN.

6. Welche Rolle spielt ein framework bei einer Architektur?

Die Rolle eines Frameworks ist leider viel zu oft zu groß. Bestimmt das Framework die Architektur der Software ist die Abhängigkeit so groß, dass es nicht ausgeschlossen ist, dass bei Änderungen des Frameworks auch Änderungen in der Architektur einhergehen. Das Framework nimmt keine Rücksicht auf die Software. Man spricht auch von einer one way marriage oder einem Harem. Vertraue nie auf ein Framework (selbst wenn du es selbst geschrieben hast).

"You can date it, but you should not marry it."

7. Was macht eine gute Architektur aus?

Plugin Pattern

Eine gute Architektur ermöglicht es, weitreichende Entscheidungen erst spät entscheiden zu müssen. Wenn man diese Entscheidungen möglichst spät trifft, hat man die maximal mögliche Information, um alle Aspekte berücksichtigen zu können.

Eine gute Architektur maximiert die Anzahl der nicht getroffenen Entscheidungen.

Ein Mögliches Modell hierfür ist das Plugin Modell.

Dabei bestimmt der usecase die Architektur und die business Logik. Die UI, die Datenbank und das Framework verhalten sich nur wie Plugins, von denen die Business Logik nichts weiß und nicht abhängig ist.

8. interactor und entities

interactor und entities

Ziel ist es also, die business Logik unabhängig von Framework, Datenbank und Ein-/Ausgabe zu machen.

Bleibt man beim Plugin Pattern, kann man die Fachlichkeit auf zwei Typen von Objekten verteilen:

  • interactor
  • entities

Im interactor wird businss Logik zusammengefasst, die spezielle Regeln für eine Anwendung enthält. Der interactor sollte die maximale Unabhängigkeit haben. Er verwendet die Entities und zwei boundaries, die sich über Interfaces definieren.

Die boundaries ihrerseits werden von einem delivery mechanism bedient, über den sie nichts wissen. Das eine boundary sammelt die Daten vom delivery mechanism, bereitet sie auf und übergibt sie in Form eines Request Models an den interactor. Das andere bekommt vom interactor die Antwort in Form von Response Models, bereitet sie auf und lässt sie vom delivery mechanism abholen.

In den entities wird business Logik zusammengefasst, die Regeln für mehr als eine Anwendung enthalten.

Der Benutzer interagiert über ein delivery mechanism mit dem boundary, das die Aufgabe hat, die Ein- und Ausgaben aufzubereiten und den interactor über Request Models zu bedienen, bzw Response Models als Antwort von ihm zu erhalten.

Der delivery mechanism kann als model view presenter umgesetzt werden. Hier im Kleinen kann das MVC Pattern angewendet werden. Der Presenter greift auf das boundary zu, erhält das Response Model, bereitet die Daten darin für das View Model auf und schreibt sie dort hinein. Das View muss nur noch auf die Daten im Model zugreifen und sie ausgeben.

9. Was ist mit der Datenbank?

entity gateway

Die Datenbank darf nicht Teil der Anwendung sein. Innerhalb der Anwndung haben wir es mit entities zu tun. Ein Entity Gateway kümmert sich um das Mapping zwischen entities und Datenbank.

Das bedeutet, dass sich in der gesamten Anwendung keine sql Anweisung befindet.

10. Was ist mit MVC?

model - view - presenter (MVVC)

Das MVC Pattern findet sich da, wo es ursprünglich gedacht war: Bei der Ausgabe.

Der Presenter holt sich vom boundary die Daten, bereitet sie auf und schreibt sie in das view model. Das view fragt das view model ab und gibt die Daten aus.

11. Testbarkeit

Der interactor kann einzeln getestet werden: Man gibt ihm ein Request Model und validiert das Response Model. Entities können verwendet oder besser gemockt werden.

Der Presenter kann einzeln getestet werden: Man gibt ihm ein Response Model und validiert das View Model.

Test Driven Development (TDD) oder kann ich auch die Unittests nachliefern? Wenn ich die Unittests nachliefere, merke ich eventuell, dass meine Anwndung nicht so einfach mit unittests abzudecken ist, aufgrund von Architektur Entscheidungen. Das führt zu Löchern in der Testabdeckung. Aufgrund der Löcher kann ich aber den Tests nicht bedingungslos vertrauen. Das wiederum führt zu Angst vor dem refactoring. Und das führt wiederum dazu, dass das refactoring nicht gemacht wird. Und das führt dann zu rotten code.

Der einzige Ausweg ist TDD. Nur wenn ich TDD mache, kann ich die Architektur so gestalten, dass eine 100% Code Abdeckung gewährlistet ist. Nur dann kann ich meinem Code vertrauen.

Unittests sind außerdem eine sehr gute Code Dokumentation, weil sie die Anwendung des Codes demonstrieren.

12. 3 Grundregeln von TDD

  1. Schreibe die Tests vor der Entwicklung!
  2. Bevor du eine Zeile Code entwickelst, musst du einen Test schreiben, der sie verifiziert.
  3. Du darfst nicht mehr Code entwickeln, als wie es nötig ist, den Test zu bestehen.

13. Fazit

  • Kontrolliere die Pfeilrichtungen in deiner Architektur.
  • Die Pfeile deuten vom Detail hin zum Abstrakten.
  • Die Frage, ob ich den usecase testen kann, muss ich mit ja beantworten können.