embarc logo
embarc logo

arc42-Starschnitt: Gradle. Schnipsel Nr. 4: Bausteinsicht

Stefan Zörner Stefan Zörner
28.11.2013

Lesezeit: 9 Minuten

Teile und herrsche. In dieser Folge geht es um Zerlegung und Hierarchiebildung. Wie zerfällt unsere Software in kleinere Teile?

Nachdem ich im zweiten Teil dieser Serie mit der Kontextbetrachtung (siehe Schnipsel #2) bereits eine Blackboxsicht des zu beschreibenden Systems vorgestellt habe, zoomen wir in dieser Folge hinein. Die Bausteinsicht zeigt die Struktur der Lösung, also ihre Bestandteile, und wie diese zusammenhängen.

arc42-Starschnitt, Schnipsel #4

Also wieder: Schere raus und losgeschnippelt …

Abflug Terminal 2

Im Taxi auf dem Weg zum Flughafen die unvermeidliche Frage: “Mit welcher Linie fliegen Sie?” Eigentlich interessiert den Fahrer das nicht. Tatsächlich will er wissen, zu welchem Terminal er fahren muss. “Lufthansa.”. “Ah, das ist Abflug Terminal 2”. Der Taxifahrer – im Gegensatz zu vielen seiner Fahrgäste – weiß nämlich, dass Terminal 2 für die Lufthansa verantwortlich ist.

Flughafen Hamburg

Große Flughäfen sind verblüffend komplex. Zu den klassischen Mitteln, um mit Komplexität umzugehen, zählen Zerlegung und Hierarchiebildung. So gibt es in einem Flughafen unterschiedliche Bereiche. Die Terminals zum Beispiel, London Heathrow hat gleich fünf. Die Strukturierung ist schon deswegen nötig, um Fluggästen und anderen Menschen Orientierung zu geben, aber etwa auch um die Sicherheit zu gewährleisten. So wird unterschieden in Abflug und Ankunft, Shoppen, Speisen, Lounges …

Die Zerlegung eines Flughafens in Teile braucht dabei nicht streng hierarchisch erfolgen. Die Gliederung in Terminal 1, 2, …, in Abflug- und Ankunftsbereich oder sicherheitskritisch und nicht sicherheitskritisch sind unterschiedliche Ordnungsprinzipien, eine Gepäckabfertigung kann es sowohl in Terminal 1 als auch in Terminal 2 geben, Gates werden gern nach Buchstaben A, B, … gruppiert usw.

Teile und herrsche!

Schnipsel #4 Softwaresysteme sind ebenfalls komplexe Gebilde. Die klassischen Mittel, um mit Komplexität umzugehen, kommen auch hier zum Einsatz. Die Motivation, ein Softwaresystem in Teile zu zerlegen, kann organisatorisch motiviert sein. Verschiedene Teams arbeiten unabhängig voneinander an Teilen des Gesamtsystems, oder bestimmte Teile sollen im weiteren Verlauf projektübergreifend wiederverwendet werden oder unabhängig voneinander vermarktbar sein. Es kann auch technisch motiviert sein, etwa wenn die Oberfläche leicht austauschbar sein soll. Das führt oft zu Schichten, einem weiterem Ordnungsprinzip neben fachlich motivierten Teilsystemen.

Früher wurde Softwarearchitektur sogar gern mit Struktur gleichgesetzt. Moderne Auffassungen sind da offener, wie etwa Martin Fowler in “Who Needs an Architect?” schreibt:

“Architecture is about the important stuff. Whatever that is.” (Martin Fowler)

Doch die Strukturierung der Lösung wird schnell wichtig, es sei denn Qualitätsmerkmale wie Wartbarkeit, Austauschbarkeit etc. sind für die Lösung völlig irrelevant (siehe Qualitätsziele in Schnipsel #3). In solch seltenen Fällen tut es auch ein Monolith oder eine große Matschkugel (Big Ball of Mud).

Die Zerlegung, orientiert an Prinzipien wie Seperation of concerns (Verantwortlichkeitsprinzip) und Information hiding (Geheimnisprinzip), nimmt großen Raum im Entwurf ein. Und die Bausteinsicht ist das zentrale Ergebnis, um betreffende Entscheidungen festzuhalten. Und um später Orientierung zu geben, etwa für neue Teammitglieder.

Bilder statt Worte

Wer sich auf einem Flughafen zurechtfinden will orientiert sich an der Beschilderung oder schaut auf einen Plan. Bestimmte Dinge lassen sich mit Bildern leichter kommunizieren als mit Text allein. Innerhalb eines großen Softwaresystems lässt sich die Option der Beschilderung nur bedingt realisieren (“Wo geht es hier zur Persistenz?"). Bildhafte Pläne von der Software anzufertigen, um Orientierung zu geben, geht natürlich schon.

Mit einem Plan auf dem Flughafen in Hamburg

Software zu visualisieren ist daher sehr üblich. Ebenfalls sehr üblich ist es, Aspekte zu trennen, und nicht alles in ein Bild zu zwängen. In der Softwarearchitektur hat sich hierfür das Konzept der Sichten (engl. “Views”) etabliert. arc42 schlägt verschiedene Sichten vor, mit der Kontextabgrenzung (auch Kontextsicht) haben wir in Schnipsel #2 bereits eine kennen gelernt. Ausgehend von der Kontextsicht zeigt die Bausteinsicht die Zerlegung des Systems in Teile, und wie diese Teile zusammenhängen.

Schematische Ebenen der Bausteinsicht
Schematische Ebenen der Bausteinsicht

Eine Bausteinsicht für Gradle

Auf Basis des Quelltextes von Gradle (Open Source) habe ich eine grobe Bausteinsicht angefertigt. Die Software wird selbst mit Gradle gebaut und besteht aus über 40 Subprojekten. Eine Bausteinsicht mit 40 Bestandteilen auf Ebene 1 würde wenig Orientierung geben und Neulinge eher abschrecken (vgl. Prinzip 7+/-2).

Ich habe die Subprojekte daher in zwei Ebenen zu größeren logischen Teilen zusammengefasst, und die Abhängikeiten mit Metainformationen aus den Build-Skripten und statischer Code-Analyse herausgearbeitet. Der folgende Schnipsel stellt überblicksartig einen Ausschnitt der Sicht dar, konkret Ebene 1 und für ein Subsystem auch Ebene 2.

 

Schnipsel #4 (Bausteinsicht): Bestandteile von Gradle

Ebene 1

Gradle lässt sich in 4 grobe Blöcke (“Subsysteme”) zergliedern. Das folgende Diagramm zeigt sie mit ihrer Interaktion untereinander und mit außen, die gestrichelten Pfeile stellen Abhängigkeiten zwischen Subsystemen bzw. Verwendungen dar.

Bausteinsicht, Ebene 1
Bausteinsicht, Ebene 1

Die folgende Tabelle gibt einen Überblick über die Verantwortlichkeiten der einzelnen Subsysteme.

Subsystem Kurzbeschreibung
Clients Gradle stellt Verwendern seine Funktionalität auf verschiedene Weise bereit. Kommandozeile, einfache graphische Oberfläche, Integration in Entwicklungsumgebungen und CI-Server ...
Core Build System Der Kern von Gradle umfasst die Basisfunktionalität (Interpretation von Skripten, Abhängigkeitsmanagement, Ausführung von Tasks, Java-Unterstützung ...) sowie das Plugin-Konzept als Erweiterungspunkt.
Tool Integration Plugins, die Werkzeuge anderer Projekte integrieren, etwa zur Qualitätssicherung, zur Veröffentlichung von Artefekten in Repositories, etc.
Language Support Plugins zur Unterstütztung weiterer Programmiersprachen neben Java (Scala, JavaScript, ...)

Ebene 2 (Subsystem “Clients”)

Das folgende Diagramm zerlegt das Clients-Subsystem weiter in fachlich motivierte Module. Sie hängen alle von Teilen des Core Build System ab, die betreffenden Pfeile sind im Diagramm der Übersicht halber aber weggelassen.

Bausteinsicht, Ebene 2, Clients
Bausteinsicht, Ebene 2, Clients

Modul Kurzbeschreibung Gradle Sub-Projekt(e)
Launcher Interaktion mit Gradle klassisch über Kommandozeile, oder alternativ mit einer graphischen Oberfläche. launcher, ui
Gradle Tooling API API, um Gradle in andere Werkzeuge einzubetten. Hierzu zählen Entwicklungsumgebungen, Continuous Integration Server, graphische Benutzeroberflächen ... tooling-api]
IDE Integration Unterstützung für integrierte Entwicklungsumgebungen, konkret etwa Eclipse und IDEA ide
Gradle Wrapper Der Wrapper ermöglicht die Verwendung von Gradle, ohne dass es dafür installiert sein muss. Interessant z.B. für Open Source Projekte, welche die Hürde für das Übersetzen ihrer Quelltexte senken wollen. wrapper
 

Weitere Details?

Die Darstellung oben im Schnipsel stellt aus meiner Sicht das Minimum für einen Architekturüberblick dar: Diagramme mit erläuternden Texten, und eine kurze Darstellung der jeweiligen Verantwortlichkeit jedes gezeigten Bausteins. Eine detaillierte Architekturbeschreibung würde zum einen tiefer hineinzoomen, zum anderen mehr Details zu den Bausteinen zeigen, etwa deren Schnittstellen. Im arc42-Template ist ein Vorschlag für entsprechende Inhalte enthalten (Blackbox-Template, Whitebox-Template).

Wo und wie tief Sie tatsächlich hineinzoomen, machen Sie an den Zielgruppen Ihrer Dokumentation fest, und an deren Interessen. Jemand, der einen Flughafen bauen soll, benötigt mehr und andere Details als jemand, der später einen Fluggast abholt. Eine Bausteinsicht mit gleichem Abstraktionsniveau wie der Quelltext macht in der Regel keinen Sinn, sie aktuell zu halten hingegen viel Arbeit.

Wenn Sie beim Hineinzoomen also an einer Stelle abbrechen, geben Sie dort Hinweise, wo es weiter geht. Ab einem bestimmten Punkt wird es immer erforderlich sich, im Quelltext nachzuschauen. Machen Sie den interessierten Lesern Ihrer Dokumentation den Weg dahin nicht zu schwer! Im Beispiel oben sind zur Illustration in der Ebene 2 des Clients-Subsystem die betreffenden Gradle Subprojekte vermerkt, inkl. Link zum Quelltext in der Versionskontrolle.

Muss es immer UML sein?

Die Diagramme im Schnipsel oben sind in UML (Unified Modeling Language) notiert. Wer UML wählt, um Architekturbilder anzufertigen, steht selten in der Kritik. Macht man ja halt so. Ist standardisiert, kann jeder lesen. Tatsächlich können UML meiner Erfahrung nach bei weitem nicht alle Zielgruppen einer Architekturdokumentation lesen. Zumindest wenn etwas originellere Diagramme und Modellelemente verwendet werden. Da Dokumentation die Kommunikation eigentlich unterstützen soll, kann das ein echtes Problem werden. Gerade überblicksartige Darstellungen sollen den Einstieg erleichtern. Wenn das das Ziel Ihrer Diagramme ist, lassen Sie sich lieber von Flughafenplänen inspirieren als von der UML-Spezifikation.

Diagramme auf dem Niveau grober Bausteinsichten erfordern eigentlich kein UML. Tatsächlich tun es die berühmten Kästchen und Striche hier oft auch; vorausgesetzt Sie erklären Ihre Notation in einer Legende. Da bei UML die Diagramme Sichten auf ein einheitliches Modell sind, ist die größte Stärke die Konsistenz der Bilder – Verwendung eines Modellierungswerkzeugs vorausgesetzt. Wenn ein Baustein an einer Stelle umbenannt wird, erscheint der neue Name automatisch in allen Diagrammen der Bausteinsicht, und auch in anderen Sichten. Das ist aus meiner Sicht (wenn überhaupt) das entscheidende Argument für UML. Zielgruppengerechte UML-Diagramme erhalten Sie oft durch eine betont kleine Anzahl unterschiedlicher Modellelemente, die sich dann auch leicht erklären lassen. Die Beschriftung “Legende: UML” hilft niemandem.

Wo kleben wir den Schnipsel hin?

Die Bausteinsicht hat ihren festen Platz in arc42, und zwar in Abschnitt 5 (siehe Abbildung unten). Die Gliederung sieht Unterkapitel 5.1, 5.2, … für die verschiedenen Ebenen vor. Hier könnte man auch anders strukturieren, beispielsweise direkt nach Subsystemen. Im Fall des Gradle-Beispiels also etwa “5.1 Clients”, “5.2 Core Build System”, …

Die von arc42 vorgeschlagene Gliederung hat den Vorteil, dass der Text beim sequentiellen Lesen nach hinten immer spezieller wird. Wer nur einen groben Überblick benötigt, braucht nicht viel hin- und herblättern; er bricht einfach bei Bedarf irgendwann ab.

Schnipsel #4 abheften in arc42
Schnipsel #4 abheften in arc42

Zum Weiterlesen

Ausblick

Den vierten Gradle-Schnipsel zum farbig ausdrucken, ausschneiden und aneinanderkleben können Sie hier herunterladen. ;-)

Neben der Bausteinsicht und der Kontextsicht schlägt arc42 weitere Sichten vor, die ich später noch vorstellen werde. Im nächsten Schnipsel geht es aber um Architekturentscheidungen, und wie man sie nachvollziehbar festhält. Das sind genau die Entscheidungen, die, wenn falsch getroffen, Ihr Projekt zum Scheitern bringen können. Also Drama pur – Ich kann Ihnen eine spannende Folge und interessante Einsichten zu Gradle versprechen …

 

Leanpub

Dieser Beitrag ist ursprünglich als Teil einer Blog-Serie beim Hanser-Verlag (“Hanser Update”) erschienen. Die Inhalte, ergänzt um reichhaltiges Bonus-Material, sind mittlerweile auch als E-Book bei Leanpub verfügbar.

zum arc42-Starschnitt