javaland 2019 - 19.03...das hexagon - datenfluss user interface infrastructure product-service db...

33
Hexagonale Architektur Domain zentrierte Microservices Javaland 2019 - 19.03.2019 Christian Iwanzik @chrisIwanzik [email protected]

Upload: others

Post on 01-Jan-2020

16 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Hexagonale ArchitekturDomain zentrierte Microservices

Javaland 2019 - 19.03.2019

Christian Iwanzik@chrisIwanzik

[email protected]

Page 2: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Christian Iwanzik (33)SoftwareentwicklerDipl-Inf. (FH) - FH Köln

Steckenpferde:➢ JVM

○ Kotlin○ Scala○ auch java ;-)

➢ Domain Driven Design➢ Microservicearchitekturenö

Seit 2010 bei tarent Solutions in Bonn

www.tarent.de

Page 3: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Wir Bauen wir einen Warenkorb!

DB

Shoppingcart - Service Product-Service

GET /products/{sku}

GET /shoppingcart/{uuid}PUT /shoppingcart/{uuid}/items

Produktbild: http://tinobusiness.com/wp-content/uploads/2015/09/CONSUMER-PRODUCTS-e1442909155136.jpg

● Wir besitzen eine schöne Microservicearchitektur● Produkte und der Warenkorb sind in zwei verschiedene Services getrennt.● Aber wie bauen wir einen Microservice sauber auf?

Page 4: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Wir Bauen wir einen Warenkorb!Controller

Servicelayer

DB-Repository HTTP Client

top down

Separation of concerns!

Wenn wir mal die DB austauschen: Kein Problem!

Decoupling!

Dependency Inversion!

● Good old layers architecture● Wir haben einen Controller, einen Service, einen Client und ein Repository● Die Architektur sieht gut aus und streight forward

Page 5: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

… und dann kam die FachlogikMaximaler Warenkorb-wert: 120€

Maximale Produktanzahl im Warenkorb: 50

Maximale Anzahl pro Produkt: 10

SKU (Stock Keeping Unit): alphanumerisch von 5 - 20 Zeichen

● Der PO kommt an und hat fachliche Anforderungen an den Warenkorb

Page 6: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

… und dann kam die Fachlogik

0..n1

Controller

Servicelayer

DB-Repository HTTP Client

Klar: Hier im Service! Da ist die Logik!

Product

sku: String price: Int

ShoppingCart

products: Map <Product, Int>

● Das Team plant die Änderungen und malt sich eine kleine UML Skizze● Aber wo wird sie verortet? Natürlich in der Service Layer

Page 7: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Bob kommt neu ins TeamWas bauen wir denn hier?Ein

Warenkorb-service!

Ein µService mit Spring Boot!

Alles in Kotlin. Voll cool!

Oh und JPA und so!

Ja… Aber was MACHT denn der Service!?

Bob kommt neu ins Team. Was bauen wir denn hier?● Hauptsächlich technische Antworten.● Aber was genau macht denn der Service?

Page 8: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Was macht denn der Service?fun putProduct(@PathVariable uuid: String, sku: String): ResponseEntity<*> { val skuRegex = "[\\w\\d]{1,20}".toRegex()

return if(skuRegex.matches(sku)) {

val cart = service.addProduct(uuid, sku) … } else { ResponseEntity.badRequest().body("sku is not valid") }}

Controller

Also hier wird erst mal die SKU validiert. Beim Fehler geben wir HTTP 400 zurück.

● Der Kollege zeigt Bob den aktuellen Service und wo was verortet ist:● Im Controller finden wir die Datenvalidierung.

Page 9: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Was macht denn der Service?fun addProduct(uuid: String, sku: String): ShoppingCart? { val optionalCart = shoppingCartRepo.findById(uuid) return if(optionalCart.isPresent) { val cart = optionalCart.get() val product: Product = productServiceClient.getProduct(sku)

if(product != null) { cart.products?.add(ShoppingCartItem(product.sku, product, 1)) shoppingCartRepo.save(cart) } return cart

} else { null }}

Controller

ServicelayerUnd hier geben wir dann dem Warenkorb das gefundene Produkt.

Was sind denn● ShoppingCart● ShoppingCartItem● Product?

Hier holen wir ein Produkt beim Productservice ab.

● Und im Service finden wir die Hauptlogik des Service.○ Ein bestehender ShoppingCart wird geladen○ Ein Produkt wird vom Client gezogen○ Und das gefundende Produkt wird der Liste an Produkten des

ShoppingCarts hinzugefügt● Bob fallen beim Durchsehen, die Modelle auf. Und er fragt sich, was sie dort

noch machen.

Page 10: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Was macht denn der Service?@Entitydata class ShoppingCart ( @Id var uuid: String?,

var amount: Int?,

@OneToMany(cascade = [ALL]) var products: MutableList<ShoppingCartItem>?)

Controller

Servicelayer

Was sind denn● ShoppingCart● ShoppingCartItem● Product?

Achso. Das sind die Entities für den OR Mapper. Die nutzen wir aber auch im Client.

ShoppingCart

● Der Kollege zeigt ihm die Objekte. Es sind simple PoJos für den OR Mapper

Page 11: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Was macht denn der Service?@Entitydata class ShoppingCartItem( @Id var sku: String?,

@OneToOne(cascade = [ALL]) var product: Product?,

var quantity: Int?)

Aber ShoppingCartItem kommt doch im Modell gar nicht vor?

Ja, das brauchen wir aber für den ORM wegen der Quantity

ShoppingCart Product

0..n1

● Bob fällt auf, dass `ShoppingCartItem` gar nicht in der Modellskizze vorkommt. ● Dort gibt es doch nur `ShoppingCart` und `Product`● Die Gründe liegen in der Datenbank begründet, da sie eine Zwischentabelle

für die Quantity benötigt.

Page 12: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

DB-Repository

Was macht denn der Service?-- schema.sqlALTER TABLE SHOPPING_CART_ITEM ADD CONSTRAINT max_quantity CHECK QUANTITY <= 10

Controller

Servicelayer

Von einem Produkt darf man doch nur maximal 10 haben.Wo wird das denn geprüft?

Na in der `schema.sql`

ShoppingCart

Ähem… Anna? Wo war noch mal der Constraint?

DB-Repository

● Bob fragt nach den Invarianten für den Warenkorb. ○ Wo sind sie denn?

● Peter weiß die Antwort. Sie sind direkt in der Datenbank als Constraint.

Page 13: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Saube Schichten. Verteilte FachlichkeitController

Servicelayer

DB-Repository HTTP Client

Formatvalidierung

Objektkomposition

Überprüfung von Invarianten

● Die Schichten sind gut getrennt und alles hat Hand und Fuß● Lediglich die Fachlichkeit, das eigentlich Wichtige am Service, ist wild im

System verteilt.● Sogar in der Datenbank findet man Constraints.

Page 14: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Ein paar Wochen später:

BIG BALL OF

MUD

Wo wird noch mal der Warenkorbwert berechnet?

● Reales Beispiel aus einem Projekt mit ausufernder Komplexität.● Wo ist die Fachlogik? Was MACHT mein Service eigentlich?● Je älter und komplexer ein Service wird, desto verteilter ist die Fachlichkeit.

Page 15: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Die IDee !

Erzähl mal!

Ich hab mal was von Hexagonaler Architektur gehört.

● Bob ist mittlerweile gut im Team angekommen und hat eine Idee, wie man dem Chaos begegenet.

Page 16: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Das Hexagon - Die Schichten

Domain

Application

Ports

Product-Service

DB

● Fachlogik● Modell● “Das Herz der Software”● keine Technik● Domain Driven Design

● Usecases ● Komposition

● Technische “Anhängsel”● Controller● Queue Publisher● SQL Client

Ursprünge:● von Alistair Cockburn 2005 propagiert. Die Itention war die Ports-and-adapter

Architektur.● Hexagonal war zunächst nur der Arbeitstitel. Hat sich aber bis heute behalten.

Die hexagonale Architektur besteht grob aus drei Schichten. Daher auch Schichtenarchitektur.

● Modell: Gekapselte Fachlogik. NUR die Fachlogik und Fachdaten. Berechnungen, Validierungen, Pre- Post-Conditions, Invarianten. Keine Technik.

● Application: Komposition - Lade das Modell aus der DB. Sag ihm was du willst. Speicher es zurück in die DB.

● PortsTechnische Anhängsel - HTTP Controller, Queue Subscriber oder Publisher, etc. Reine Technik.

Page 17: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Die Domain

Reine Fachklassen- und Funktionen

Product

SKU

Price

ProductName

simple Fachtypen:syntaktische- und semantische Validierung

zusammengesetzter Fachtyp

<< Aggregate >>ShoppingCart Quantity

AggregateRoot- Interface nach außen- alle Fachlogik- Invarianten- immer gültig!

putProductInto

amount

quantityOfProduct

checkMaximumProductCount

Nur diese Teile reden mit der Außenwelt!

WICHTIG: Nach außen gegebene Objekte, dürfen keinen Einfluss mehr auf die Domäne haben!Kopieren!

Im Zentrum steht die Domäne. Also alles, was unseren Service fachlich ausmacht. ● Wir nutzen hier keine Literale als Fachobjekte, sondern wohl benamte

Klassen, die hier syntaktisch und semantisch validieren. Ich nenne sie mal spaßeshalber “Fachliterale”

● Lediglich ein Typ definiert eine API nach außen: Das “AggregateRoot”. Nur hier gehen Informationen in die Domäne und aus der Domäne raus.Nur diese API manipuliert die Domäne. Validiert sie aber auch und redigiert falsche Inputwerte. Wichtig: Die Domäne ist IMMER gültig!

● Vorteile: Testbarkeit. Sicherheit in der Berechnung, Typsicherheit.

Page 18: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Die Domaindata class Product(val sku: SKU, val price: Price, val name: Name)

Product(SKU("132456"), Price(4, 99), Name("Brot"))

data class SKU(val value: String) { private val regex = "[\\w\\d]{1,20}".toRegex()

init { if(!regex.matches(value)) throw IllegalArgumentException("...") }}

fun putProductInto(product: Product, quantity: Quantity): ShoppingCart {

checkMaximumProductCount()

val newAmount: ShoppingCartAmount = overallAmount + (product.price * quantity) val existingQuantity: Quantity? = cartItems[product]

if(existingQuantity == null) { cartItems[product] = quantity } else { cartItems[product] = existingQuantity.copy(value = existingQuantity.value + quantity.value) }

overallAmount = newAmount

return this} Wie sieht so was im Code aus?

● Fachobjekte validieren sich selbst● Zusammengesetzte Objekte nutzen lediglich Fachobjekte● Das AggregateRoot definiert eine Anzahl an Businessfunktionen und nutzt die

darunter liegenden Fachobjekte.● Wir ziehen Fachlichkeiten aus dem Controller und der Datenbank direkt in

unsere Fachklassen.

Page 19: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Das Hexagon - Datenfluss

User Interface Infrastructure

Product-Service

DB

Domain

Application

Ports

Wir gehen noch mal ein bisschen hinaus und schauen uns nun den Datenfluss an.Wir können das Hexagon in zwei Seiten teilen. Auf die rechte Seite schreiben wir aktive Komponenten, auf die rechte Seite passive Komponenten.

Page 20: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Die Application

Application

Product-Service

DBUser Interface Infrastructure

Domain

CommandService

Report

Service

Usecaseinterface

Usecase interface

Repositoryport

Port

● Usecases.● Komposition der Ports und

Domains. ● Keine Fachlogik!

● Zwischen den Schichten kommunizieren wir über definierte Interfaces genannt Ports.

● Aktive Komponenten nutzen dir Driver Ports. Diese Komponenten wollen etwas von unserem System.

○ Sie wollen neue Daten eingeben○ Sie wollen aber auch bestehende Daten abfragen○ Beispiel Command und Report Service

● Passive Komponenten werden über driven Ports angesteuert.○ Unser System will etwas von ihnen.○ Wir wollen Daten an die Komponente schicken○ Wir wollen aber auch Daten von der Komponente beziehen.

● Services bilden Usecases ab, die von aktiven Komponenten angestoßen werden können.

○ z.B. Über den Query Port kommt die Anfrage: “Gib die Summe aller aktuellen Warenkörbe”

○ Service nutzt das Repository Interface um die Domänenobjekte zu laden

○ Nutzt die Domäne um die Werte zu ermitteln ○ Gibt sie an den Query Port zurück.

Page 21: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Die Application

≪ Aggregate ≫ShoppingCart

putProductInto

CommandService

≪ interface ≫ServiceInterface

Aufrufer

≪ interface ≫Repository

Aufgeru-fener

≪ implements ≫

≪ implements ≫interface ServiceInterface { fun putProductIntoShoppingCart(shoppingCartUuid: ShoppingCartUuid,...) ...}

@Serviceclass CommandService(val shoppingCartRepositoryPort: ...): ServiceInterface {

override fun putProductIntoShoppingCart(shoppingCartUuid ...): Optional<ShoppingCart> { shoppingCartRepositoryPort.load(shoppingCartUuid) .map { shoppingCart -> shoppingCart.putProductInto(...) } …. }

● Ports werden durch Interfaces umgesetzt. Aufrufer und Aufgerufener sind (noch) unbekannt.

● Der Service komponiert nur die Ports mit der Domäne.

Page 22: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Ports And Adapter

Application

Ports

REST

UI

Product-Service

DBUser Interface Infrastructure

Domain

Driver Adapters

● Technische Frameworks

● Keine Fachlogik!

● Wir zeichnen wieder die gesamten Schichten und schauen uns an, wie wir mit den Application-Stöpseln auf der nächsten Ebene umgehen können.

● Wir nennen diese “Stöpsel” Adapter ● Jetzt wird auch klar, warum die Architektur auch Ports-and-adapter Architektur

heißt.● Nutzende Schichten benutzen diese Ports als “Driving Adapters”.

○ Also Logiken, die das System steuern und “benutzen” ○ Sie übersetzen alle “Befehle” die von außen hereinkommen auf die

interne Logik.

Page 23: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Ports And Adapter

Application

Ports

Product-Service

DB

REST

User Interface Infrastructure

Domain

Driver Adapters

HTTP

SQL

Driven Adapters

REST

UI

● Genutzte Schichten benutzen äußere Ports als “Driven Adapters”○ Also Logik, welche aus dem System genutzt wird.

● Wichtig: Driving und Driven Adapters definieren nicht den Datenfluss, sondern die Richtung der Befehle.

Page 24: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Ports And Adapter

Application

Ports

Product-Service

DB

REST

User Interface Infrastructure

Domain

ViewsController

HTTP

SQL

RESTController

HTTP Client

OR Mapper

● Zwischen den Schichten kommunizieren wir über definierte Interfaces genannt Ports.

○ Daher spricht man auch oft von der Ports-and-adapter Architektur.● Nutzende Schichten benutzen diese Ports als “Driving Adapters”.

○ Also Logiken, die das System steuern und “benutzen” ○ Sie übersetzen alle “Befehle” die von außen hereinkommen auf die

interne Logik.● Genutzte Schichten benutzen äußere Ports als “Driven Adapters”

○ Also Logik, welche aus dem System genutzt wird.● Wichtig: Driving und Driven Adapters definieren nicht den Datenfluss, sondern

die Richtung der Befehle.

Page 25: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Ports And Adapter

≪ Aggregate ≫ShoppingCart

putProductInto

CommandService

≪ interface ≫ServiceInterface

≪ interface ≫Repository

≪ implements ≫

≪ implements ≫

≪ adapter ≫ShoppingCartController

≪ adapter ≫JPARepository

≪ port ≫SpringBootMVC

≪ port ≫Hibernate

Page 26: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Hatten wir das nicht schon mal?ShoppingCartController

CommandService

JPARepository

top down

ShoppingCart Product

0..n1

● Die Struktur auf Codeebene ähnelt sehr stark dem, was wir bereits hatten● Allerdings “denken” wir hier in anderen Strukturen:

○ Statt einer 1 dimensionale Struktur von oben nach unten spannen wir eine 2 dimensionale Ebene auf.

○ Die Concerns sind viel enger gefasst als in der alten Architektur.○ Die Elemente sind durch Ports und Adapter noch loser gekoppelt.

Page 27: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Hexagonale Architektur

Application

Ports

Product-Service

DB

REST

User Interface Infrastructure

Domain

ViewsController

HTTP

SQL

RESTController

HTTP Client

OR Mapper

Srv

Alles zusammen:● Sieht komplizierter, aber auch strukturierter aus.

Achso: Warum ein Hexagon: ● Alistair Cockburn zeichnete in seinen ersten Entwurf zur Ports-and-adapter

Architektur ein Secheck, weil es grafisch besser zu seiner Anzahl an Ports passte.

● Man kann auch alle anderen X-Ecke nehmen.

Page 28: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Klaus kommt neu ins TeamWas bauen wir denn hier?

Hier ist der Domainkern und hier die Tests dazu.

Wow! Das ist echt sauber und verständlich.

Die Umsysteme findest du unter Ports.

● Klaus kommt neu ins Team und ist begeistert!

Page 29: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Wie geht es weiter?

Product-Service

DB

Component

Ursprünge:● von Alistair Cockburn 2005 propagiert. Die Itention war die Ports-and-adapter

Architektur.● Hexagonal war zunächst nur der Arbeitstitel. Hat sich aber bis heute behalten.

Die hexagonale Architektur besteht grob aus drei Schichten. Daher auch Schichtenarchitektur.

● Modell: Gekapselte Fachlogik. NUR die Fachlogik und Fachdaten. Berechnungen, Validierungen, Pre- Post-Conditions, Invarianten. Keine Technik.

● Application: Komposition - Lade das Modell aus der DB. Sag ihm was du willst. Speicher es zurück in die DB.

● PortsTechnische Anhängsel - HTTP Controller, Queue Subscriber oder Publisher, etc. Reine Technik.

Page 30: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Wann sollte ich es einsetzen?● Man hat generell eine Fachlogik (Domain)

● Die Domain hat Invarianten

● Viele Umsysteme, bzw. APIs

● Verschiedene fachliche Sichten

● Kein Fachmodell

● Keine Invarianten

● simples CRUD

Pro:● Man hat eine Domain mit Invarianten. Selbst wenn es wenige sind: Wo die her

kommen, gibt es noch viel mehr.● Man hat viele Umsysteme, die man irgendwo in seiner Architektur verankern

muss.● Man hat mehr als eine fachliche Sicht auf die Domäne und arbeitet mir

verschiedenen Readmodels.

Contra:● Man arbeitet generell nicht mit einem Fachmodell● Man muss keine Invarianten beachten.● z.B. simples CRUD oder ein Duchlauferhitzer (Formatkonverter, Gateway,

Datenpumpe, etc.)

Page 31: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Vor- und Nachteile● Macht die Domainkomplexität handhabbarer,

da zentralisiert.

● Einzelne Schichten lassen sich besser testen.

● Einführung eines neuen Umsystems ist einfacher.

● Neue Kollegen sehen sich den Kern an und wissen, was passiert. Die Wahrheit steht im Code. Diesmal wirklich. ;-)

● Overhead - Domainobjekte müssen oft in neue Modelle umgewandelt werden.

● Manche Frameworks machen einem ein Strich durch die Rechnung. Aufwand von Sonderlockenhier: Hibernate und Jackson

Vorteile:● Zentralisierte Fachlichkeit im µService hat immer Vorteile● Domain, Applikation und Ports sind über Interfaces getrennt. Sie lassen sich

separat gut testen.● Durch die Interfaces ist es auch einfach z.B. einen Messagebus anzubinden. ● Wenn man DDD betreibt,

Nachteile:● Die Domain muss oft in andere DTOs umgewandelt werden um auf

Frameworks zu passen● Die Domain ist die ganze Wahrheit. Manche Abfragen wollen aber nicht die

ganze Wahrheit liefern. Hier muss man “ReadModels” einbauen. Das macht die Abfagen aber auch wiederum entkoppelter.

Page 32: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

● https://fideloper.com/hexagonal-architecture

● https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexa

gonal-onion-clean-cqrs-how-i-put-it-all-together/

● https://marcus-biel.com/hexagonal-architecture/

● https://web.archive.org/web/20060711220612/http://alistair.cockburn.us:80/index.php/Main_Page

Literatur

Beispiel:

https://gitlab.com/Iwanzik/hexagonal-service

Page 33: Javaland 2019 - 19.03...Das Hexagon - Datenfluss User Interface Infrastructure Product-Service DB Domain Application Ports Wir gehen noch mal ein bisschen hinaus und schauen uns nun

Vielen Dank!