Logo nexyo GmbH

nexyo GmbH

Startup

Go and DDD := Building the Right Thing

Description

Andreas Krimbacher von nexyo spricht in seinem devjobs.at TechTalk über die Entscheidungen, welche hinter der im Unternehmen angewandten Technologie Go und der Wahl der Architektur stehen.

Beim Videoaufruf stimmst Du der Datenübermittlung an YouTube und der Datenschutzerklärung zu.

Video Zusammenfassung

In "Go and DDD := Building the Right Thing" zeigt Andreas Krimbacher, wie sein Team mit Go, Domain‑Driven Design und Clean Architecture den Nexio Data Hub als langlebiges, evolvierbares System aufbaut. Er erläutert das Modellieren der Domäne (Dataset, Distribution, Policy) samt Lebenszyklus, den Einsatz von Repository- und Factory-Pattern zur Entkopplung der Persistenz sowie die Schichtung aus Presenter/HTTP-API, Use-Case/App-Layer und Entitäten mit injizierten Repositories. Die resultierende ubiquitäre Sprache, das Single-Responsibility-Prinzip und eine testbare Architektur (schnelle Unit-Tests im Domain-Layer, mockbare Repositories für Integrations- und GUI-Tests) ermöglichen schnelles, sicheres Refactoring und iterative Lieferung – also das „richtige“ Produkt zu bauen.

Go und DDD := Building the Right Thing – Ein praxisnaher Architekturfahrplan aus der Data-Hub-Entwicklung bei nexyo GmbH

Kontext: Ein Data Hub als Rückgrat für operative Datenökosysteme

In der Session „Go and DDD := Building the Right Thing“ von Andreas Krimbacher (Speaker: Andreas Krimbacher, Company: nexyo GmbH) haben wir bei DevJobs.at mitgeschrieben, wie ein junges, wachsendes Team ein Enterprise-Produkt strukturiert, das über Jahre bestehen und mit Kundenanforderungen mitwachsen soll. Der Fokus der Präsentation: Wie Go und Domain-Driven Design (DDD) – flankiert von Clean Architecture – helfen, ein „Data Hub“-System richtig zu bauen, statt nur schnell zu bauen.

Krimbacher beschreibt das zentrale Produkt als „Nexio Data Hub“. Er sitzt im Zentrum einer Dateninfrastruktur, spricht mit verschiedenen Microservices und Datenbanken, kann mit anderen Data Hubs interagieren und bietet sowohl eine Web-UI als auch eine CLI für automatisierte Steuerung. Der Anspruch: Ein langlebiges, evolvierbares Enterprise-Produkt, dessen Struktur refaktorierbar bleibt und das robuste Sicherheits- und Nebenläufigkeitsanforderungen erfüllt.

Der Weg dorthin beginnt für das Team mit zwei Fragen: Welche Technologie? Welche Architektur- und Design-Patterns? Die Wahl für Go fiel schnell – wegen Einfachheit, guter Refakturierbarkeit, Sicherheitsmerkmalen und Concurrency-Features. Danach rückten zwei Bücher ins Zentrum: Clean Architecture (Robert C. Martin) und Domain-Driven Design (Eric Evans). Dazu Krimbacher sinngemäß: „Es führt kein Weg an diesen beiden Büchern vorbei.“

Warum Go? Entscheidung und Begründung

  • Go war bereits im Team in kleineren und mittleren Projekten im Einsatz – die Lernkurve war überschaubar.
  • Die Sprache fördert Einfachheit und klare Strukturen, was in komplexen, interagierenden Systemen zählt.
  • Refactoring-Freundlichkeit ist zentral, wenn ein Produkt 5, 10 oder 20 Jahre leben soll.
  • Security- und Concurrency-Eigenschaften sind in einer Infrastruktur, die andauernd mit fremden Systemen spricht, essenziell.

„Go was set“, fasst Krimbacher die Entscheidung zusammen: Die Sprache stand fest. Der Rest der Arbeit verlagerte sich auf Architekturfragen, insbesondere auf DDD und Clean Architecture.

DDD im Kern: Domänenobjekte und Domänenlogik – ohne Infrastruktur-Details

Im Zentrum der DDD-Perspektive steht die Domäne. Krimbacher modelliert sie über Domänenobjekte, die im Kontext eines Data Hubs naheliegen:

  • Dataset (Datensatz)
  • Distribution (Verteilung/Distribution eines Datensatzes)
  • Policy (Richtlinie/Regelwerk, das auf Distributionen wirkt)

Wichtig: Die Domänenlogik lebt in diesen Objekten – z. B. „Distribution hinzufügen“, „kombinierte Policy ermitteln“ etc. Entscheidend ist, dass in dieser Ebene keinerlei Infrastruktur-Details auftauchen: keine Datenbanktechnologie, keine Netzwerkprotokolle, keine Speicherrepräsentationen. Die Domäne spricht die Sprache des Kunden – und nur diese.

Lebenszyklus in der Domäne

Krimbacher stellt den Lebenszyklus eines Domänenobjekts heraus:

  1. Erzeugen
  2. Persistieren
  3. Wiederherstellen (aus der Persistenz)
  4. Modifizieren
  5. Erneut persistieren
  6. Archivieren (Ende des Lebenszyklus)
  7. Löschen

Aus diesem Lebenszyklus leiten sich zwei Bedürfnisse ab: Etwas muss Domänenobjekte erzeugen, und etwas muss sie speichern und wieder bereitstellen. So kommen Factory und Repository ins Spiel.

Repository-Pattern und Factory: Schnittstellen in der Domäne, Implementierung in der Infrastruktur

Das Repository beginnt als Interface innerhalb der Domäne. Es formuliert in Domänensprache, was möglich sein muss – ohne Implementierungsdetails:

  • Dataset persistieren
  • Dataset über UUID wiederfinden
  • Dataset löschen

Die konkrete Implementierung liegt in der Infrastruktur-Schicht: Dort wird tatsächlich mit der Datenbank gesprochen. Bemerkenswert ist außerdem, dass die Repository-Implementierung eine Factory injiziert bekommt. Die Factory kapselt die gesamte Logik zur Erzeugung echter Domänenobjekte – sowohl bei Neukonstruktion als auch bei der Rückführung aus persistierten Repräsentationen. Das Repository kann so echte, vollständige Domänenobjekte zurückliefern, ohne dass die Domäne selbst Datenbankwissen bräuchte.

Die Konsequenz: Das Domänenmodell bleibt frei von technischen Abhängigkeiten, und die Infrastruktur wird austauschbar. Für Tests und Refactoring ist diese Trennung Gold wert.

Clean Architecture als Laufzeitgerüst: UI → Presenter → Use Cases → Entities

Krimbacher zeigt das bekannte Clean-Architecture-Diagramm, wandelt es aber in eine lineare, intuitiv lesbare Darstellung. Von oben nach unten:

  • UI (z. B. Web-Frontend)
  • Presenter (z. B. HTTP/REST-API)
  • Use-Case-Schicht (auch „Application Layer“)
  • Entities (die Domäne – die zuvor beschriebenen Domänenobjekte)

Wesentliche Punkte:

  • Die Use-Case-Schicht erhält ein Repository injiziert. Sie orchestriert Domänenoperationen, ohne deren Persistenzdetails zu kennen.
  • Der Presenter kann verschiedene Formen annehmen – etwa REST oder gRPC. Für die Domäne spielt das keine Rolle.
  • Abhängigkeitsrichtung ist strikt von oben nach unten. Die Entities-Schicht weiß nichts über UI, Presenter oder Infrastruktur. Die Use Cases wissen nichts über die konkrete Implementierung der Repositories.

Diese klare Trennung verschafft Stabilität in der Evolution: UI- oder API-Wechsel, Datenbankschnittstellen oder neue Integrationen lassen sich um die Domäne herum austauschen, ohne das Herz des Systems permanent umzuschreiben.

Zusammenspiel im Code: „main“, Handler und Ablauf im „getDataset“-Beispiel

Auch wenn Krimbacher keine konkreten Code-Snippets projiziert, macht er den Ablauf nachvollziehbar:

  • In „main“ wird die Infrastruktur verkabelt: Eine Factory wird erzeugt, ein Repository initialisiert und die Anwendung zusammengebaut.
  • Ein „Dataset-Handler“ (als Teil der Presenter-/API-Schicht) wird erstellt.
  • Die Anwendung läuft als HTTP-Server, sodass die UI über REST zugreifen kann.

Im Handler trifft schließlich alles zusammen. Er sitzt genau an der Schnittstelle von Repository, Presenter und Domäne. Beispielhaft erläutert Krimbacher „getDataset“:

  • Der Presenter ruft die Methode mit einer UUID auf.
  • Der Handler nutzt das injizierte Repository, um das Dataset aus der Persistenz zu ziehen.
  • Domänenlogik könnte (bei Bedarf) angewendet werden.
  • Das Ergebnis wird an die UI zurückgegeben.

So bleibt die Domäne zentral und die Infrastruktur steuerbar – ohne die Schichten zu vermischen.

Warum nicht einfach CRUD über MySQL? Drei Prinzipien, die den Unterschied machen

Krimbacher adressiert die naheliegende Frage: Warum nicht einfach ein REST-API bauen, eine MySQL-Datenbank dahinter hängen und CRUD implementieren? Seine Antwort kondensiert sich in drei Prinzipien, die DDD und Clean Architecture zusammenbringen.

1) Ubiquitous Language (Allgegenwärtige Sprache)

DDD fordert eine gemeinsame Sprache zwischen Fachexperten und Entwicklern. Die Domänenschicht gibt den Takt vor: „Hier passiert die Magie, hier entsteht Wert für den Kunden.“ Die Sprache der Domäne wird im Code abgebildet und entwickelt sich über die Zeit gemeinsam mit den Stakeholdern weiter. Da die Domänenschicht keine Infrastrukturkenntnis hat, muss sie sich nicht durch technische Details ablenken lassen.

2) Single-Responsibility-Prinzip (SRP)

Krimbacher bezieht sich auf die Definition aus „Clean Architecture“: „A module should be responsible to one and only one actor.“ Praktisch heißt das: Wenn ein Paket von mehreren Stakeholdern gleichzeitig und womöglich widersprüchlich verändert werden müsste, ist es falsch geschnitten. Eine klare Verantwortungsverteilung erleichtert Refactoring, Testbarkeit und Evolution – und verhindert, dass Teams in Konflikte laufen, wenn Anforderungen auseinanderlaufen.

3) Testbarkeit und Testpyramide

„Wenn man ein Produkt ausliefert, muss man zu 150 % sicher sein, dass alles getestet ist“, betont Krimbacher. Die vorgestellte Struktur passt zu einer klassischen Testpyramide:

  • Unit-Tests unten: Die Domänenobjekte sind von Datenbank und Netzwerk getrennt – ideal für schnelle, umfangreiche Unit-Tests.
  • Integration/Komponententests in der Mitte: Dank klaren Interfaces (z. B. Repository als Interface in der Domäne) lässt sich Infrastruktur mocken bzw. gezielt austauschen. Man kann testweise Instanzen eines Repositories einsetzen, ohne eine echte Datenbank zu benötigen.
  • GUI-Tests oben: Um das Gesamtsystem samt User Experience zu verifizieren, werden End-to-End-Pfade überprüft.

Die Architektur fördert so Vertrauen in Refactorings: Wer sichere Tests hat, traut sich, die Struktur wirklich weiterzuentwickeln.

Organisatorische Effekte: Onboarding, schnelles Umsetzen, komfortables Refactoring

Neben den technischen Argumenten unterstreicht Krimbacher Team- und Produktvorteile:

  • Entkoppelte Pakete und eine saubere Struktur erleichtern das Onboarding. Neue Teammitglieder finden schnell heraus, wo Funktionalität hingehört und wie sie zu erweitern ist.
  • Enge Zusammenarbeit mit Kunden ist DNA: Änderungen müssen zügig eingearbeitet werden. Refactoring-Sicherheit ist deshalb ein Muss – andernfalls „macht man es nicht“, obwohl es sinnvoll wäre.
  • Mit guten Tests und klaren Schichten kann schnell und iterativ geliefert werden. Das sei der Kern dessen, was er mit „Building the Right Thing“ meint: zügig liefern, dabei aber dem richtigen Produktpfad folgen – gestützt auf Architekturdisziplin und getestete Evolution.

Praktische Leitplanken, die wir aus der Session mitnehmen

Ohne neuen Kontext zu erfinden, lassen sich aus Krimbachers Vortrag konkrete Handlungsanleitungen ableiten, die direkt aus seinen Punkten folgen:

  • Domäne zuerst modellieren
  • Domänenobjekte (z. B. Dataset, Distribution, Policy) benennen und mit Domänenlogik versehen.
  • Infrastrukturdetails strikt aus der Domäne heraushalten.
  • Lebenszyklus der Domänenobjekte klären
  • Erzeugen, persistieren, laden, ändern, archivieren, löschen.
  • Verantwortlichkeiten für diese Schritte explizit schneiden.
  • Repository als Domänen-Interface definieren
  • Methoden in Domänensprache (persistieren, über UUID laden, löschen) festlegen.
  • Aber: Keine Implementierungsdetails im Interface.
  • Factory für Erzeugung und Rehydrierung
  • Erzeugungslogik kapseln und in die Repository-Implementierung injizieren.
  • Aus Persistenzrepräsentationen wieder echte Domänenobjekte herstellen.
  • Clean Architecture als Orchestrierung
  • UI → Presenter → Use Cases → Entities als klare Abhängigkeitskette verstehen.
  • Use Cases orchestrieren, Entities sind rein, Presenter exponieren (z. B. REST).
  • Abhängigkeiten laufen nach unten, Wissen über Infrastruktur bleibt oben.
  • Komposition in „main“
  • Factory und Repository initialisieren, dann Anwendung zusammensetzen.
  • Presenter/Handler erstellen, Server starten – UI kann konsumieren.
  • Handler als Schnittstelle
  • Handler bündelt Repository, Presenter und Domäne.
  • Beispiel „getDataset“: UUID kommt vom Presenter, Repository lädt, Domäne bleibt zentral, UI erhält das Ergebnis.
  • Testpyramide bewusst füttern
  • Viele schnelle Unit-Tests in der Domäne.
  • Integration/Komponente über Interfaces (Repository) ohne echte DB möglich.
  • GUI-Tests für End-to-End-Verhalten.
  • SRP als Refactoring-Kompass
  • Wenn verschiedene Stakeholder denselben Codebereich in unterschiedliche Richtungen ändern wollen, Paketgrenzen neu schneiden.
  • Ubiquitous Language pflegen
  • Begriffe der Domäne konsequent im Code verwenden.
  • Gemeinsame Sprache mit Fachexperten als nachhaltige Basis.

Fazit: Go + DDD + Clean Architecture – das Trio für langlebige Enterprise-Produkte

„Go and DDD := Building the Right Thing“ macht greifbar, warum die vermeintlich langsamere Route – Domäne sauber modellieren, Abhängigkeiten strikt organisieren, Interfaces diszipliniert führen, Testpyramide ernst nehmen – am Ende der schnellere, sicherere Weg ist. Der Nexio Data Hub (so wie Krimbacher ihn beschreibt) zeigt die Leitidee: Die Domäne ist das Herz, die Infrastruktur ist austauschbar, die Anwendungsschicht orchestriert, die Präsentationsschicht exponiert.

Dass ein Team dafür Go wählt, ist in dieser Erzählung folgerichtig: Einfachheit, Refakturierbarkeit und Concurrency-Eigenschaften unterstützen genau den Betrieb, den ein Data Hub im Zentrum vieler Systeme benötigt. Mit DDD und Clean Architecture entsteht daraus ein System, das sich mit Kundenanforderungen weiterentwickeln lässt – testbar, refaktorierbar und für neue Teammitglieder nachvollziehbar. Für uns ist das die eigentliche Aussage dieses Talks: „Building the Right Thing“ passiert, wenn Struktur, Sprache und Tests die Evolution tragen.

Wer Software baut, die viele Jahre tragen soll, findet in dieser Kombination einen klaren Pfad: Domäne ernst nehmen, Clean-Architecture-Grenzen respektieren, Repositories und Factories richtig platzieren, Injektion bewusst handhaben, Tests priorisieren – und die Kette UI → Presenter → Use Cases → Entities diszipliniert leben. Genau so wird aus einer Technologieentscheidung plus zwei Büchern ein tragfähiger Engineering-Ansatz.

Weitere Tech Talks

Weitere Tech Lead Stories

Weitere Dev Stories