Ontologische oder teleologische Gruppierung?

Vor einigen Monaten habe ich bereits erklärt, warum dienstspezifische Artefakte bei dem jeweiligen Dienst abgelegt werden sollten (Zentrale Service-Einstellungen?) und in welchem Verhältnis Dienst- und Umgebung zueinander stehen (Dienst- oder Umgebung-Orientierung?).

Dabei geht die Frage nach dem Fokus der Gruppierung weit über die beschrieben Einstellungen, Geheimnisse und vergleichbaren Artefakte einer Microservices-Architektur hinaus. Das Thema der Gruppierung betrifft alle Ebenen und begint bereits im Quelltext, innerhalb einer Methode.

Schauen wir uns einmal einen einfachen Programmcode an.

Es wird eine Datei eingelesen, verarbeitet, gespeichert und abschließend protokolliert. So einfach so gut. Jetzt soll der gleiche Vorgang mit zwei anderen Dateien ebenfalls durchgeführt werden. Und jetzt wird es spannend. Gruppieren wir den Quelltext so?

Gruppierungsalternative A

Oder so?

Gruppierungsalternative B

Jemand könnte anmerken, dass beide Varianten schlecht sind und für die Gemeinsamkeit eine eigene Methode extrahiert werden sollte.

Gruppierungsalternative A’

Das ist auf jeden Fall besser, da von konkreten Implementierungsdetails abstrahiert wurde und es nur noch eine Stelle gibt um beispielsweise die Protokollierung weiterzuentwickeln. Allerdings hat dieses kleine Refaktoring nur das Abstraktionslevel erhöht, aber nicht unser Gruppierungsproblem gelöst. Tatsächlich entspricht es weiterhin der Gruppierungsalternative A. Die alternative Gruppierung würde folgendermaßen aussehen.

Gruppierungsalternative B’

Jetzt stellt sich die Frage, wie der Quelltext denn jetzt gruppiert werden sollte. Und vorallem warum so, denn schließlich haben beide Alternativen Vor- und Nachteile.

Aristoteles’ vier Gründe

Zunächst müssen die Unterschiede beider Alternativen beschrieben werden. Dazu können wir den Grund analysieren, warum der Code überhaupt in einer der beiden Alternativen geschrieben wurde. Es treffen hier nämlich mehrere Gründe aufeinander. Nach Aristoteles können Gründe in vier Kategorien eingeteilt werden (Four Causes). Auf die Frage nach dem WARUM gibt es also vier Arten von Antworten. Im Folgenden will ich die vier Gründe vorstellen und direkt auf Quelltext anwenden.

  • Matter. Die materielle Art, aus der das Objekt besteht. Für die Frage nach dem WARUM eines Stuhls, wäre die Antwort “weil die Holz-Atome und -Moleküle in ihrer Art existieren”. Auf den Programmcode bezogen wären es Daten, Variablen, Operatoren, Anweisungen, Einstellungen, etc.
  • Form. Die Darstellung und Struktur des Objekts. Für den Stuhl wären das die vier Beine, der Sitz und die Lehne. Auf den Programmcode bezogen wäre es die Syntax und das Design der Klassen und Methoden in Entwurfsmustern.
  • Agent. Die Entität, die für die Existenz des Objekts verantwortlich ist. Der Stuhl existiert, weil der Tischler ihn gefertigt hat. Auf den Programmcode bezogen wäre das die Person, die ihn programmiert hat.
  • Purpose. Der Sinn oder das Ziel, dass das Objekt erreichen soll. Der Stuhl existiert, weil sich der Tischler darauf setzen will. Auf den Programmcode bezogen wäre das der Zweck, die fachliche Komponente, das Feature, der Use Case, die Anforderung.

Durch diese Unterscheidung wird deutlich, das Gruppierungsalternative A/A’ den Purpose-Grund in den Vordergrund stellt. Die Anforderung ist “Verarbeite Datei X”, also wird der Quellcode demenstrechend gruppiert.

Gruppierungsalternative B/B’ stellt den Matter-Grund in den Vordergrund. Es geht um Dateien, Variablen, Verarbeitungen und Protokollierungen. Also wird primär nach diesen ‘Atomen’ gruppiert.

Eine Gruppierung nach syntaktischer Darstellung und Entwurfsmustern (Form) ist dem sehr ähnlich und würde JSON-Dateien, Visitors und Adapters in den Vordergrund stellen. Das könnte als Gruppierungsalternative C bezeichnet werden.

Auch die Gruppierungsalternative D ist vorstellbar, die primär nach Agent, also Entwickler gruppiert. Jeder Kollege programmiert seinen Quelltext in seiner Klasse oder Assembly. Schwierig wird es dann allerdings mit der Interoperabilität.

Matter oder Purpose?

Mit dem Wissen über die verschiedenen Gründe der Gruppierung ergeben sich nun neue Argumente für und gegen die oben beschriebenen Alternativen. Sollten wir nach Purpose (Gruppierungsalternative A/A’) oder nach Matter (Gruppierungsalternative B/B’) gruppieren?

Es macht Sinn, ein Softwaresystem primär anhand seiner Features, UseCases und Anforderungen in Dienste und Komponenten aufzuteilen, weil dies die primären Einheiten/Verantwortlichkeiten sind, die ein Team gemeinsam bearbeitet und die sich zusammen ändern. Es macht keinen Sinn, ein System anhand seiner Entitäten oder ‘Atome’ (Startup.cs-Dateien, Controller, DBs, Configs, Secrets, ID-Configs, Dokus, …) aufzuteilen, weil das Details eines Features und damit sekundär sind. Eine solche Aufteilung würde es erschweren Funktionen weiterzuentwickeln und neue hinzuzufügen. Außerdem widerspricht es sämtlichen Design-Prinzipien wie zum Beispiel Kohäsion, SRP, SOC und OCP (siehe oben referenzierte vorherige Blogposts zum Thema).

Es würde auch keiner Menschen eines Unternehmens so aufteilen, dass alle Köpfe hier, alle Hände dort, alle Füße wieder hier und alle Herzen wieder dort zusammengefasst werden. Stattdessen macht es Sinn ein Unternehmen anhand der Produkte aufzuteilen, an denen gearbeitet wird.

Es würde auch keiner das Inventar eines Unternehmens so aufteilen, dass alle Menschen in den ersten Raum, alle Tische in den zweiten Raum und alle Computer in den dritten Raum zusammengefasst werden. Stattdessen macht es Sinn, in jedem Raum eine Person mit Tisch und Computer auszustatten.

Es macht nur eine teleologische Aufteilung (gemeinsamer Sinn) Sinn, keine ontologische (gemeinsame Art). Zumindest solange wir kein Ersatzteillager, sondern einen lebenden und funktionsfähigen Organismus erreichen wollen.

Zentralität oder Dezentralität?

Das Diskussion von Zentralität und Dezentralität von Einstellungen ging am eigentlichen Thema vorbei. Da es bei Einstellungen, zum Beispiel K8S-ConfigMaps und -Secrets, von vornherein um ‘Atome’ (Matter) geht, macht eine dementsprechende primäre Gruppierung oder Zentralisierung keinen Sinn. Die erstrebenswerte Alternative ist aber nicht die Dezentralisierung von Matter, sondern die Zentralisierung von Purpose. Es gibt einen zentralen Bereich für jede fachliche Anforderung, jeden Use Case und jedes Feature. Und nur innerhalb dieses Bereichs können sämtliche Objekte, die einen gemeinsamen Sinn haben, erneut hierarchisch rekursiv gruppiert werden.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s