SOLID – ein Schritt zu mehr Professionalität in der Software-Branche

 Schon vor vielen Jahren saß ich mal in einer Straßenbahn, wir standen an einer Haltestelle, es ging nicht weiter. Plötzlich hörten alle Motoren auf zu summen, alle Lichter gingen aus – und nach einiger Zeit wieder an. An der Anzeige über dem Fahrer blinkte die Firmware-Versionsanzeige auf. Was war passiert? Offenbar war die Straßenbahn „abgestürzt“ und der Fahrer hatte sie in seiner Not einfach neu gebootet.

Graue Vergangenheit? Leider nicht. Seit heute Morgen „hängt“ die News-App in meinem Smartphone – ärgerlich, aber zum Glück nicht weiter tragisch. Gravierender war da schon dieses Erlebnis: Ich fahre mit meinem Neuwagen auf der Autobahn. Plötzlich fällt die Tachoanzeige auf 0, ebenso wie der Drehzahlmesser und die Außentemperaturanzeige. Also: Fuß vom Gas und vorsichtig Richtung Standstreifen steuern. Ah, die Bremse geht zum Glück noch. Nach einigen bangen Sekunden belebt sich alles wieder von selbst. Und es ist auch nie wieder vorgekommen.

Richtig beruhigt hat mich die Tatsache, dass der Reboot in solchen Situationen inzwischen offenbar automatisch erfolgt, allerdings nicht. Wahrscheinlich haben die meisten von Ihnen auch schon solche oder ähnliche Situationen erlebt. Instabile Software berührt und beeinträchtigt unser Leben.

Wie aber erstellt man stabile und trotzdem änderbare Software? Das ist ein weites Feld, und besonders bei parallelen Echtzeitsystemen, wie sie auch in modernen PKWs laufen, gibt es da keine einfache Antwort. Doch auch bei weniger kritischen Systemen stellt sich diese Frage.

Von Befürwortern agiler Softwareentwicklung hört man als Antwort im Wesentlichen: „Macht konsequent Pair Programming und Test-Driven Development! Dann entsteht quasi von alleine solide Software!“ Doch diese Antwort ist unvollständig. Denn einerseits habe ich genug schlecht gemachtes TDD und ineffektives Pair Programming erlebt. Und andererseits gibt es solide Software, die anders entwickelt wurde. Was ist also das Geheimnis flexibler und stabiler Software?

Ich glaube, dass ein Schlüssel dazu in den SOLID-Prinzipien liegt. Was das ist? Das Akronym SOLID ist eine von Michael Feathers gefundene Merkhilfe für fünf grundsätzliche Prinzipien objektorientierten Designs. Die Prinzipien selbst stammen von Robert C. Martin (auch Uncle Bob genannt). In seinem sehr lesenswerten Buch „Agile Software-Development: Principles, Patterns and Practices“ beschreibt er elf Prinzipien:

    Ebene 1: fünf Prinzipien auf Klassenebene,
    Ebene 2: drei Prinzipien, die den Inhalt von Packages betreffen,
    Ebene 3: drei Prinzipien, die das Verhältnis von Packages in einem System adressieren.

Um die fünf Prinzipien auf Ebene 1, die sogenannten SOLID-Prinzipien, geht es mir heute. Sie lauten:

    S – Single Responsibility Principle
    O – Open-Closed Principle
    L – Liskov Substitution Principle
    I – Interface Segregation Principle
    D – Dependency Inversion Principle.

Zusammen legen sie die Basis für ein robustes, wartbares und langfristig erweiterbares Software-System.

Vielen Entwicklern ist heute klar, dass gute Unit-Tests der Schlüssel für qualitativ hochwertige Software sind. Aber nur allzu oft stehen sie bei der Einführung von Unit-Tests vor schier unüberwindbaren Hindernissen. Niemand hatte beim Design des Codes leichte Testbarkeit im Sinn. Natürlich bekommen sie dann von den Agilisten zu hören: „Wenn dein Code nicht testbar ist, hast du ein Design-Problem.“ Refactoring ist angesagt. Aber auf welches Ziel soll man sich dabei zu bewegen? Ohne eine klare Antwort bleibt Refactoring letztlich eine ziellose Zeitverschwendung.

Die Antwort darauf liefern die SOLID-Prinzipien. Software, die in Einklang mit diesen Design-Prinzipien entwickelt wurde, kann gar nicht anders, als gut testbar zu sein. Denn sie besteht aus lose gekoppelten Bausteinen mit einem starken inneren Zusammenhang. Klassen mit einer klaren Aufgabe und kleine, fokussierte Interfaces machen es leicht, benötigte Drittklassen durch Platzhalter (Mocks) zu ersetzen. So wird es möglich, einzelne Klassen und Methoden isoliert zu testen. Das Zusammenspiel der SOLID-Prinzipien führt also zu testbarer Software.

Und auch andersherum wird ein Schuh draus. Vielleicht haben Sie sich gefragt, warum viele Agilisten gebetsmühlenartig wiederholen, wie wichtig TDD für ein gutes Software-Design ist. Klar ist es hilfreich, automatisierte Tests für den neuen Code zu haben, und es macht Sinn, vorher darüber nachzudenken, was man haben möchte, ehe man den Code schreibt. Aber der Effekt von TDD geht weit darüber hinaus. Gute Unit-Tests und einfache Testbarkeit haben eine positive Auswirkung auf das Design von Code. Und die SOLID-Prinzipien beschreiben diese Design-Prinzipien. So werden Testbarkeit und gutes Design zu zwei Seiten derselben Medaille.

Das Thema „Gutes Design“ ist nicht neu. Manche sagen, auf SOLID angesprochen, sogar „Alles alter Wein in neuen Schläuchen!“ Ich sehe das anders. Es freut es mich sehr, dass Qualitätsbewusstsein zunehmend zu einem Trend-Thema in der Software-Entwicklung wird. Michael Feathers hat offenbar einen Nerv getroffen, als er den Begriff „SOLID“ prägte.

Wer von uns Entwicklern würde sich nicht wünschen, abends mit einem ruhigen Gefühl professionellen Stolzes von der Arbeit nach Hause zu fahren. Weil man sein solides Wissen eingesetzt hat, um etwas Qualitätsvolles zu schaffen. Etwas, auf das man eben mit gutem Gewissen stolz sein kann. Immer wieder bekomme ich von Kollegen zu hören, wie froh sie sind, dass sie in einem Umfeld arbeiten, in dem auf Qualität und Qualitätsbewusstsein Wert gelegt wird. Es motiviert sie unheimlich, SOLIDe Software zu entwickeln zu können und zu dürfen, auf die man hinterher stolz sein kann. Uncle Bob hat dieses Selbstverständnis mal in einem Vortrag in seiner unnachahmlichen Art folgendermaßen auf den Punkt gebracht: „We will not ship shit. Period.“ Das ist manchmal verdammt schwer. Aber es fühlt sich gut an!

Grund genug also, sich diese SOLID-Prinzipien etwas näher anzusehen. In einer losen Folge von Beiträgen möchten wir die Prinzipien einzeln und in ihrem raffinierten Zusammenspiel vorstellen. Dabei wollen wir es nicht bei einer Kurzzusammenfassung belassen. Wir wollen vor allem weitergeben, was wir selbst bei der Umsetzung in die Praxis gelernt haben, sowie Tipps und Tricks zur Umsetzung aufzeigen.