Die Zeiten, als embedded System einfache, dedizierte und überschaubare Aufgaben zu erledigen hatten, sind längst vorbei. Funktionen wie Bluetooth-Anbindung, Safety, Security, weitreichende Konfigurationsmöglichkeiten und Zusammenfassung von mehreren Systemen zu einem Größeren (weil die µCs leistungsfähiger geworden sind) lassen die Code-Basis schnell anwachsen. Wenn die zugrunde liegende Software-Architektur nicht dafür ausgelegt ist, wird jede weitere Änderung oder Erweiterung zu einem Vabanque-Spiel.
Vergleicht man das Ganze mit dem Bau eines Hauses dann kommt auf das Fundament und die darüber liegenden Stockwerke noch ein Balkönchen dran, da noch eine Gaube, … und in kürzester Zeit nimmt die Architektur ähnliche Auswüchse an wie unser Titelbild.
Abhängigkeiten kann man zwar in einem Diagramm darstellen. Aber welche Änderung sich im Detail wie auswirkt, lässt sich im Vorfeld nicht mehr mit Sicherheit bestimmen.
Zu guter Letzt hält sich die Begeisterung des Managements in engen Grenzen, wenn infolgedessen Zeit und Kosten aus dem Ruder laufen.
Anforderungen an eine Architektur
Einfache Software
Als Akronym der Wahl gilt KISS (Keep it simple, stupid): Die Software muss einfach sein. Eine komplexe Architektur erzwingt komplexen Code – und damit wird die Software in jeglicher Hinsicht teuer (aufwändige Codierung, umständliche Unit-Tests, zeitaufwändige Fehlersuche). In den meisten Fällen ist die einfachere Lösung auch die bessere (Sparsamkeitsprinzip auch bekannt als „Ockhams Rasiermesser“).
Fokussierung
Die grundlegenden Konzepte der Architektur sollten einfach sein, so dass die knappe Zeit für die komplexen Themen verwendet werden kann. Bei einem Hochhaus plant man auch nicht jede Etage anders, oder?
Wartbarkeit/Erweiterbarkeit
Wer kann schon zu Projektbeginn vorhersagen, welche Änderungen oder neuen Features noch kommen werden. Spätestens, wenn es an ein Nachfolgeprodukt mit einem Blumenstrauß an neuer Funktionalität geht, rächt es sich gnadenlos, wenn Softwarekomponenten nicht erweiterbar oder austauschbar sind oder Verantwortlichkeiten nicht klar abgegrenzt bzw. Komponenten verteilt sind.
Testbarkeit
In einem früheren Blogbeitrag habe ich bereits die Werbetrommel für das Simulieren von Software gerührt. Man kann Software, die direkt auf einem „bare metal“ SDK aufsetzt, auch Unit-testen (siehe Blogbeitrag). Aber eine Abstraktionsschicht (z.B. für Zugriff auf GPIOs) erleichtert das Leben nochmals ein gehöriges Stückchen.
Verteilte Entwicklung
Software ist wohl nur in sehr wenigen Fällen noch das Ergebnis einer One Man Show. Wenn einfache Features Änderungen an vielen Modulen zur Folge haben, treten sich die Entwickler zwangsweise gegenseitig auf die Füße und müssen immer wieder Merge-Konflikte auflösen. Davon abgesehen, dass das natürlich ordentlich nervt, kostet es unnötig Zeit (und dann sind wir schon wieder bei den Kosten. Jetzt nerve ich :).
Fazit auch hier wieder: Modularität und klare Abgrenzung von Funktionalität und Zuständigkeiten erleichtern die Arbeit.
Cliffhanger
Mit diesem Beitrag will und kann ich das Thema Softwarearchitektur natürlich nicht erschöpfend behandeln. Wozu auch – schließlich gibt es dazu regalmeter- bzw. gigabyteweise Literatur. Mir geht es erst einmal darum, einen Denkanstoß zu geben, sich im Vorfeld schon Gedanken zu machen (in der Medizin-Software ist das eh gefordert), wie das „Häuschen“ mal aussehen soll, wo die Zimmer liegen, wie man von einem Zimmer zum anderen und zu den Etagen gelangt. Und dass es zu dem Zeitpunkt noch nicht wichtig ist, wie die Wände gestrichen werden oder ob es doch goldene Wasserhähne sein sollen.
In einem nachfolgenden Beitrag werde ich konkrete Maßnahmen vorstellen, wie man die geforderten Ziele erreichen kann.
In der Zwischenzeit loht ein Blick auf arch42. Die Autoren bieten nicht nur Material für Einsteiger oder zum Vertiefen, sondern auch eine Dokumentenvorlage in verschiedenen Formaten (Word, LaTeX, asciidoc, Markdown, EnterpriseArchitekt, Confluence) und in mehreren Sprachen.