Fassung B aus Lektion 4.10.3 hat die Domäne in die Mitte gestellt und mit Domain, Application, Infrastructure und Web vier Ringe gebaut. Die Lektion endete mit dem Satz, dass der hexagonale Blick auf dieselbe Struktur noch etwas hinzufügt. Was genau, ist die Frage dieser Lektion.
Ports and Adapters kennen Sie seit Lektion 4.3.5: Kern, Anwendung mit Ports, Adapter außen, nach ihrer Technik benannt, und die Komposition
an einem Ort. Das wird hier nicht wiederholt. Diese Lektion sagt, was der Stil über diese Regeln hinaus meint, und prüft es zweimal an der
Wiedervorlage: Zuerst schneiden Sie Fassung C aus Fassung B und messen sie wie A und B. Dann bekommt Fassung C einen zweiten Eingang, eine
Nachricht aus Service Bus statt eines HTTP-Aufrufs, und ein git diff zeigt, ob die Mitte dafür auch nur eine Zeile ändern musste.
Was Ports and Adapters über Lektion 4.3.5 hinaus sagt
Alistair Cockburn hat den Stil zuerst als Hexagonal Architecture beschrieben, später unter dem Namen Ports and Adapters. Sein Ziel war eine Anwendung, die sich gleichermaßen von Menschen, von anderen Programmen, von automatischen Tests und von Skripten bedienen lässt, und die sich ohne ihre späteren Geräte und Datenbanken entwickeln und testen lässt. Aus diesem Ziel folgen drei Dinge, die in Lektion 4.3.5 nur am Rand vorkamen.
Es gibt kein Oben und Unten. Das Bild der Schichten stellt die Oberfläche oben hin und die Datenbank unten, und der Code folgt dem Bild: Oben ruft unten. Das Sechseck stellt beide nach außen, auf gleiche Höhe. Eine Weboberfläche ist für die Mitte nichts Besonderes, sie ist ein Eingang unter mehreren. Dasselbe gilt für die Datenbank auf der anderen Seite. Die sechs Ecken bedeuten übrigens nichts; Cockburn wählte die Form, damit beim Zeichnen Platz für mehrere Ports ist und niemand an Schichten denkt.
Die Asymmetrie liegt zwischen links und rechts, und sie hängt daran, wer anfängt.
| Seite | Wer beginnt | Wem gehört der Port | Form im Code | Fassung C | Kladde |
|---|---|---|---|---|---|
| treibend (links) | ein Akteur draußen: Mensch, Programm, Test | der Mitte; sie bietet ihn an | öffentliche Methoden der Mitte | FollowUpUseCases |
QuoteCommands |
| getrieben (rechts) | die Mitte | der Mitte; sie verlangt ihn | eine Schnittstelle, die ein Adapter umsetzt | IFollowUpStore, TimeProvider |
IQuoteRepository, ICurrentUser |
Auf beiden Seiten gehört der Port der Mitte, aber nicht auf dieselbe Weise. Links ruft der Adapter die Mitte, also hängt er von ihr ab, ganz ohne Trick. Rechts ruft die Mitte den Adapter, und erst das Dependency Inversion Principle aus Lektion 4.10.1 dreht die Abhängigkeit um. Wer die beiden Seiten verwechselt, legt einen treibenden Port als Schnittstelle an, die niemand ein zweites Mal umsetzt, oder er lässt einen getriebenen Adapter die Mitte aufrufen.
Ein Port hat so viele Adapter, wie es Wege nach draußen gibt. Ein Port ist ein Zweck, „Wiedervorlagen bearbeiten“ oder „Wiedervorlagen aufbewahren“. Ein Adapter ist eine Technik, die diesen Zweck bedient. Für die Wiedervorlage sieht das so aus:
| Port | Adapter | Wo |
|---|---|---|
treibend: FollowUpUseCases |
HTTP | FollowUps.Http |
| Nachricht aus Service Bus | FollowUps.ServiceBus, Übung 2 |
|
| Test | FollowUpUseCasesTests |
|
getrieben: IFollowUpStore |
EF Core mit SQLite | FollowUps.Sql |
| im Speicher | InMemoryFollowUpStore im Testprojekt |
Der Test steht dort mit Absicht. Er ist der erste treibende Adapter, den eine hexagonale Anwendung bekommt, noch bevor es eine Webseite gibt. Cockburns Ziel, die Anwendung ohne ihre Geräte zu bedienen, ist mit ihm schon erreicht.