<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>atra.consulting &#8211;</title>
	<atom:link href="https://atra.consulting/feed/" rel="self" type="application/rss+xml" />
	<link>https://atra.consulting</link>
	<description>Software erfolgreich entwickeln. Komplexität beherrschen. Wandel gestalten.</description>
	<lastBuildDate>Tue, 14 Apr 2026 14:56:22 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://atra.consulting/wp-content/uploads/2025/04/cropped-Atra-Consulting-Favicon-512x512pixel-32x32.webp</url>
	<title>atra.consulting &#8211;</title>
	<link>https://atra.consulting</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>stackconf 2026: End Release Anxiety</title>
		<link>https://atra.consulting/engineering/stackconf-2026-end-release-anxiety/</link>
		
		<dc:creator><![CDATA[Daniel Schock]]></dc:creator>
		<pubDate>Tue, 14 Apr 2026 14:54:50 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Allgemein]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=9164</guid>

					<description><![CDATA[Release Anxiety ist kein Naturgesetz Freitag, 16:47 Uhr. Ein Pull Request mit einem kritischen Fix landet auf dem Tisch. Und plötzlich diese leise Frage im Hinterkopf: „Machen wir das wirklich noch vor dem Wochenende?” Release Anxiety ist erstaunlich verbreitet. Nicht weil Teams unfähig wären — sondern weil Prozesse es sind. Manuelle Checklisten, Nachtdeployments, halbautomatische Pipelines [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Release Anxiety ist kein Naturgesetz</h2>



<p class="wp-block-paragraph">Freitag, 16:47 Uhr. Ein Pull Request mit einem kritischen Fix landet auf dem Tisch. Und plötzlich diese leise Frage im Hinterkopf: „Machen wir das wirklich noch vor dem Wochenende?”</p>



<p class="wp-block-paragraph">Release Anxiety ist erstaunlich verbreitet. Nicht weil Teams unfähig wären — sondern weil Prozesse es sind. Manuelle Checklisten, Nachtdeployments, halbautomatische Pipelines und Changelogs, die „irgendwie” entstehen, machen Releases zu kleinen Events. Dabei sollten sie Routine sein.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Daniel Schock auf der <a href="https://stackconf.eu/" target="_blank" rel="noreferrer noopener">stackconf 2026</a></h2>



<p class="wp-block-paragraph">Auf der <a href="https://stackconf.eu/" target="_blank" rel="noreferrer noopener">stackconf 2026 </a>spricht unser Kollege Daniel Schock genau darüber: <strong>„End Release Anxiety: A Guide to Fully Automated Workflows with Semantic Release”</strong>.</p>



<p class="wp-block-paragraph">Es geht nicht um Tool-Evangelismus, sondern um die Transformation eines subjektiven, nervösen Rituals in einen reproduzierbaren, automatisierten Workflow.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Themen der <a href="https://stackconf.eu/" target="_blank" rel="noreferrer noopener">stackconf</a></h2>



<p class="wp-block-paragraph">Die stackconf bringt Expertinnen und Experten aus dem gesamten Cloud-native- und DevOps-Ökosystem zusammen. Die Themenlandschaft spiegelt die aktuellen Herausforderungen moderner Infrastruktur:</p>



<div class="wp-block-columns has-custom-css is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex wp-custom-css-6d97ee49">
<div class="wp-block-column content-box-dark is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-4fc3f8e1 wp-block-group-is-layout-flex">
<h4 class="wp-block-heading">Cloud-native Plattformen &amp; Kubernetes</h4>



<p class="has-small-font-size wp-block-paragraph">Container-Orchestrierung, Plattform-Engineering und Cloud-native Architekturen.</p>
</div>
</div>



<div class="wp-block-column content-box-dark is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-4fc3f8e1 wp-block-group-is-layout-flex">
<h4 class="wp-block-heading">CI/CD &amp; Automatisierung</h4>



<p class="has-small-font-size wp-block-paragraph">Deployment-Pipelines, Release-Automatisierung und Infrastructure as Code.</p>
</div>
</div>



<div class="wp-block-column content-box-dark is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-4fc3f8e1 wp-block-group-is-layout-flex">
<h4 class="wp-block-heading">Observability &amp; Metriken</h4>



<p class="has-small-font-size wp-block-paragraph">Monitoring, Tracing und datengetriebene Entscheidungen im Betrieb.</p>
</div>
</div>
</div>



<div class="wp-block-columns has-custom-css is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex wp-custom-css-3762dc0a">
<div class="wp-block-column content-box-dark is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-4fc3f8e1 wp-block-group-is-layout-flex">
<h4 class="wp-block-heading">Sicherheit &amp; Zero Trust</h4>



<p class="has-small-font-size wp-block-paragraph">Security by Design, Supply Chain Security und Zero-Trust-Architekturen.</p>
</div>
</div>



<div class="wp-block-column content-box-dark is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-4fc3f8e1 wp-block-group-is-layout-flex">
<h4 class="wp-block-heading">KI im Kontext von Infrastruktur &amp; DevOps</h4>



<p class="has-small-font-size wp-block-paragraph">Intelligente Automatisierung und KI-gestützte Betriebsprozesse.</p>
</div>
</div>



<div class="wp-block-column content-box-dark is-layout-flow wp-block-column-is-layout-flow">
<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-4fc3f8e1 wp-block-group-is-layout-flex">
<h4 class="wp-block-heading">Nachhaltige Systemarchitekturen</h4>



<p class="has-small-font-size wp-block-paragraph">Langlebige, wartbare und ressourcenschonende Systeme.</p>
</div>
</div>
</div>



<h2 class="wp-block-heading">Veranstaltungsort und Termin</h2>



<p class="wp-block-paragraph">Die <a href="https://stackconf.eu/" target="_blank" rel="noreferrer noopener">stackconf 2026 </a>findet am <strong>28. und 29. April</strong> im <strong>Studio Balan in München</strong> statt. atra ist als Sponsor dabei.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<aside style="background-color: color-mix(in oklab, oklch(72.3% 0.219 149.579) 5%, transparent);border-color:color-mix(in oklab, oklch(72.3% 0.219 149.579) 30%, transparent);padding:20px 32px"><div style="display:flex; gap: 2rem;align-items:center;"><svg aria-hidden="true" style="color: oklch(79.2% 0.209 151.711);width:3rem;" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 18v-5.25m0 0a6.01 6.01 0 0 0 1.5-.189m-1.5.189a6.01 6.01 0 0 1-1.5-.189m3.75 7.478a12.06 12.06 0 0 1-4.5 0m3.75 2.383a14.406 14.406 0 0 1-3 0M14.25 18v-.192c0-.983.658-1.823 1.508-2.316a7.5 7.5 0 1 0-7.517 0c.85.493 1.509 1.333 1.509 2.316V18"></path></svg><div><p style="margin-bottom:0px;">Mit dem Code <strong>ATRA_CONSULTING_15</strong> gibt es 15 % Rabatt auf alle Tickets.</p></div></div></aside>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="682" height="1024" src="https://atra.consulting/wp-content/uploads/2025/10/image-682x1024.jpeg" alt="" class="wp-image-8728" style="aspect-ratio:3/4;object-fit:cover"/></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Daniel Schock</h3>



<p class="wp-block-paragraph">Senior Software Engineer</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Daniel ist ein erfahrener Fullstack-Entwickler und DevOps-Spezialist mit einem klaren Schwerpunkt auf der Backend-Entwicklung mit Java und Kotlin. Seine Expertise wird durch praktische Erfahrung in der Frontend-Entwicklung mit Vue.js abgerundet. Er verfügt über umfassende Kenntnisse in der Konzeption von CI/CD-Pipelines sowie im Einsatz von Cloud-Technologien wie Kubernetes und AWS, die er erfolgreich in den Branchen Versicherung, Logistik und E-Commerce einsetzte. Daniel arbeitet bevorzugt in agilen Umgebungen und zeichnet sich durch seine analytische Denkweise und hohe Problemlösungskompetenz aus.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:d.schock@atra.consulting">d.schock@atra.consulting</a>&nbsp; &nbsp;&nbsp;<a href="https://de.linkedin.com/in/daniel-wochnik" target="_blank" rel="noreferrer noopener"></a></p>


</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Integral Facilitation – Warum echte Veränderung dort beginnt, wo Methoden enden</title>
		<link>https://atra.consulting/allgemein/integral-facilitation/</link>
		
		<dc:creator><![CDATA[Johannes Uske]]></dc:creator>
		<pubDate>Thu, 09 Apr 2026 09:19:33 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Coaching]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=9157</guid>

					<description><![CDATA[Warum scheitern so viele gut gemeinte Change-Initiativen? Warum scheitern so viele gut gemeinte Change-Initiativen trotz exzellenter Methoden, Tools und Roadmaps? Weil sie meist nur einen Teil des Systems adressieren:&#160; In der Realität wirken diese Aspekte jedoch immer gleichzeitig – und genau dort entstehen Reibung, Überlastung und Stillstand. Veränderung scheitert selten an fehlender Kompetenz.Sie scheitert daran, [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading"><strong>Warum scheitern so viele gut gemeinte Change-Initiativen?</strong></h2>



<p class="wp-block-paragraph">Warum scheitern so viele gut gemeinte Change-Initiativen trotz exzellenter Methoden, Tools und Roadmaps?</p>



<p class="wp-block-paragraph">Weil sie meist nur <strong>einen Teil des Systems</strong> adressieren:&nbsp;</p>



<ul class="wp-block-list">
<li>Prozesse <em>oder</em> Menschen.</li>



<li>Strukturen <em>oder</em> Kultur.</li>
</ul>



<p class="wp-block-paragraph">In der Realität wirken diese Aspekte jedoch immer gleichzeitig – und genau dort entstehen Reibung, Überlastung und Stillstand.</p>



<p class="wp-block-paragraph">Veränderung scheitert selten an fehlender Kompetenz.<br>Sie scheitert daran, wie Arbeit organisiert ist, wie Entscheidungen zustande kommen, wie mit Abhängigkeiten umgegangen wird – und wie Teams mit Spannungen umgehen, die aus Komplexität ganz natürlich entstehen.</p>



<p class="wp-block-paragraph">Integral Facilitation setzt genau an diesem Punkt an.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Worum es bei Integral Facilitation wirklich geht</strong></h2>



<p class="wp-block-paragraph">Integral Facilitation ist kein neues Toolset und keine Ersatzmethode.<br>Es ist ein Arbeitsansatz, um Veränderung dort wirksam zu machen, wo sie tatsächlich entsteht: in der Zusammenarbeit realer Teams unter realen Bedingungen.</p>



<p class="wp-block-paragraph">Im Kern macht Integral Facilitation sichtbar und bearbeitbar, was in Veränderungsprozessen ohnehin wirkt – aber selten bewusst gestaltet wird:</p>



<p class="wp-block-paragraph"><strong>Innere Dimensionen</strong><strong><br></strong>Wie Menschen denken, priorisieren, Sinn erkennen oder Widerstand entwickeln.</p>



<p class="wp-block-paragraph"><strong>Äußere Dimensionen</strong><strong><br></strong>Meetings, Entscheidungswege, Prozesse, Artefakte, konkrete Ergebnisse.</p>



<p class="wp-block-paragraph"><strong>Individuelle Perspektiven</strong><strong><br></strong>Verantwortung, Führung, Selbstorganisation, Rollenverständnis.</p>



<p class="wp-block-paragraph"><strong>Kollektive Dynamiken</strong><strong><br></strong>Teamkultur, unausgesprochene Regeln, Konfliktmuster, Zusammenarbeit über Schnittstellen hinweg.</p>



<p class="wp-block-paragraph">Die Wirkung entsteht nicht durch zusätzliche Reflexion, sondern dadurch, dass diese Ebenen miteinander in Beziehung gesetzt werden. So entsteht kollektive Handlungsfähigkeit – auch unter Druck, auch bei widersprüchlichen Anforderungen.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Einordnung im Vergleich zu Beratung und Change</strong></h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>Klassische Beratung</strong></td><td><strong>Klassischer Change</strong></td><td><strong>Integral Facilitation</strong></td></tr><tr><td>Experten liefern Analysen und Empfehlungen</td><td>Vorgehensmodelle und Maßnahmen werden eingeführt</td><td>Entwicklung von Zusammenarbeit wird ermöglicht</td></tr><tr><td>Fokus auf Struktur, Prozesse, Konzepte</td><td>Fokus auf Verhalten und Umsetzung</td><td>Fokus auf Denk- und Handlungsmuster im Arbeitsalltag</td></tr><tr><td>Steuerung überwiegend von außen</td><td>Veränderung meist top-down</td><td>Verantwortung entsteht im Team</td></tr><tr><td>Effizienz und Optimierung</td><td>Akzeptanz und Umsetzung sichern</td><td>Kollektive Handlungsfähigkeit stärken</td></tr><tr><td>Wirksam bei klaren Problemstellungen</td><td>Wirksam bei planbaren Veränderungen</td><td>Wirksam bei Komplexität und widersprüchlichen Anforderungen</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Integral Facilitation ist kein Ersatz dieser Ansätze, sondern ergänzt sie dort, wo Komplexität nicht mehr sauber zerlegt werden kann und Zusammenarbeit selbst zum entscheidenden Erfolgsfaktor wird.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Eine praktische Orientierung für deinen Arbeitsalltag</strong></h2>



<p class="wp-block-paragraph">Wenn du in komplexen Situationen feststeckst, hilft es, bewusst aus unterschiedlichen Blickwinkeln auf die gleiche Situation zu schauen.</p>



<p class="wp-block-paragraph">Nicht, um mehr zu analysieren – sondern um schneller zu erkennen, wo du wirklich ansetzen kannst.</p>



<p class="wp-block-paragraph">Vier Perspektiven haben sich dabei als besonders hilfreich erwiesen:</p>



<p class="wp-block-paragraph"><strong>Innere Sicht</strong><strong><br></strong> Was nehmen Menschen gerade wahr?<br>Welche Erwartungen, Spannungen oder Überlastungen sind spürbar?</p>



<p class="wp-block-paragraph"><strong>Äußere Sicht</strong><strong><br></strong> Was passiert konkret im Arbeitsalltag?<br>Wie laufen Meetings, Entscheidungen und Abstimmungen tatsächlich ab?</p>



<p class="wp-block-paragraph"><strong>Team-Logik</strong><strong><br></strong> Welche unausgesprochenen Regeln prägen die Zusammenarbeit?<br>Was „funktioniert hier einfach so“, ohne dass es je vereinbart wurde?</p>



<p class="wp-block-paragraph"><strong>System-Logik</strong><strong><br></strong> Welche Strukturen wirken im Hintergrund?<br>Rollen, Abhängigkeiten, KPIs, Schnittstellen – was verstärkt das aktuelle Verhalten?</p>



<p class="wp-block-paragraph">Der entscheidende Unterschied: Viele Ansätze bleiben auf einer dieser Ebenen stehen.<br>Hier geht es darum, sie bewusst zusammen zu betrachten.</p>



<p class="wp-block-paragraph">Erst dadurch wird sichtbar, warum Probleme stabil bleiben – und wo Veränderung mit möglichst wenig Aufwand ansetzen kann.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Mini-Fallgeschichte aus der Praxis</strong></h2>



<p class="wp-block-paragraph">Ein Team beschreibt seine Situation so:<br>„Wir springen ständig zwischen Themen und kommen nicht wirklich voran.“</p>



<ul class="wp-block-list">
<li><strong>Innere Sicht:</strong> Gefühl von Überlastung und fehlender Klarheit</li>



<li><strong>Äußere Sicht:</strong> viele parallele Themen, häufige Unterbrechungen</li>



<li><strong>Team-Logik:</strong> „Alles ist wichtig“ – niemand priorisiert klar</li>



<li><strong>System-Logik:</strong> viele Stakeholder, ungefilterte Anforderungen von außen</li>
</ul>



<p class="wp-block-paragraph"><strong>Teamgröße:</strong> 12 Personen<br><strong>Branche:</strong> Versicherungsumfeld<br><strong>Kontext:</strong> international, Englisch als Arbeitssprache</p>



<p class="wp-block-paragraph">Das Team verantwortet parallel:</p>



<ul class="wp-block-list">
<li>stabile Run- und Maintenance-Aufgaben</li>



<li>kontinuierliche Weiterentwicklung</li>



<li>akute Produktionsprobleme</li>
</ul>



<p class="wp-block-paragraph">Die fachlich stärksten Entwickler werden regelmäßig aus der Entwicklung gezogen, um Incidents zu lösen. Gleichzeitig gibt es viele Ansprechpartner, zahlreiche Abhängigkeiten und regelmäßige Einwürfe „von links“ – fachlich wie organisatorisch.</p>



<p class="wp-block-paragraph">Der fachliche Kontext ist komplex, die Fluktuation vergleichsweise hoch, Einarbeitungszeiten sind lang. Durch die internationale Zusammenarbeit reduziert sich zudem die fachliche Tiefe in Diskussionen – nicht aus Unwillen, sondern aus pragmatischer Sprachökonomie.</p>



<p class="wp-block-paragraph"><strong>Die Folgen im Alltag:</strong></p>



<ul class="wp-block-list">
<li>Meetings werden zunehmend als Belastung erlebt</li>



<li>Veränderung wird eher defensiv betrachtet</li>



<li>Gute Ideen bleiben liegen, weil Zeit und Fokus fehlen</li>



<li>Einzelne Schlüsselpersonen tragen einen Großteil des Produktionsdrucks</li>
</ul>



<p class="wp-block-paragraph">Der entscheidende Punkt ist:</p>



<p class="wp-block-paragraph">Das Problem liegt nicht nur in der Planung – sondern im Zusammenspiel der genannten Ebenen und Perspektiven. Deshalb setzten wir nicht bei neuen Prozessen an, sondern bei der Art der Zusammenarbeit.</p>



<div style="height:12px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Wie konkret angesetzt wurde</strong></h3>



<p class="wp-block-paragraph"><strong>Produktionsarbeit genutzt, um Last zu verteilen und Kompetenz aufzubauen</strong><strong><br></strong>Produktionsprobleme bleiben Priorität – aber nicht mehr Aufgabe einzelner Schlüsselpersonen. Mehr Entwickler wurden gezielt in Analyse und Lösungsfindung eingebunden – nicht nur zur Entlastung, sondern als bewusster Teil des Kompetenzaufbaus.</p>



<p class="wp-block-paragraph"><strong>Priorisierung im Moment geklärt – auch gegenüber Stakeholdern</strong><strong><br></strong>Backlog und Struktur waren vorhanden. Entscheidend war, Priorisierung im Alltag bewusst zu machen. Neue oder eskalierende Themen wurden aktiv rückgekoppelt: Was bedeutet diese neue Priorität konkret – und was wird dafür verschoben?<br>Diese Klärung wurde auch gegenüber Stakeholdern eingefordert.</p>



<p class="wp-block-paragraph"><strong>Schnittstellen klarer statt schneller gemacht</strong><strong><br></strong> Bei vielen Abhängigkeiten wurde nicht versucht, alles sofort zu klären.<br>Stattdessen wurde bewusst unterschieden: Was gehört in unseren Verantwortungsbereich – und was nicht?<br>Dabei ging es nicht um Abgrenzung, um der Abgrenzung willen, sondern um ein klareres, verlässlicheres Zusammenspiel.</p>



<p class="wp-block-paragraph"><strong>Fokuszeiten aktiv geschützt</strong><strong><br></strong> Fokus wurde nicht dem Zufall überlassen, sondern bewusst gestaltet.<br>Es wurde klarer vereinbart, wann Abstimmung notwendig ist – und wann konzentriertes Arbeiten Vorrang hat.</p>



<div style="height:12px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Was sich dadurch verändert hat</strong></h3>



<ul class="wp-block-list">
<li>Produktionsdruck verteilt sich auf mehrere Schultern</li>



<li>Prioritäten werden bewusster entschieden statt implizit gelebt</li>



<li>Schnittstellen verursachen weniger Reibung</li>



<li>Wissen wächst im Team statt bei Einzelnen</li>



<li>Fokuszeiten werden wirksam – nicht nur geplant</li>
</ul>



<p class="wp-block-paragraph"><strong>Das Ergebnis:</strong></p>



<ul class="wp-block-list">
<li>weniger Kontextwechsel</li>



<li>spürbar weniger Frustration</li>



<li>bessere Planbarkeit trotz gleichbleibender Komplexität</li>
</ul>



<p class="wp-block-paragraph">Die Fragen, die uns geholfen haben und die Du gleich in Deinem Team stellen könntest, um ähnliche Ergebnisse erzielen, sind die folgenden:</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Fragen, die Wirkung freilegen</strong></h2>



<ul class="wp-block-list">
<li>Wo optimieren wir Symptome, statt Zusammenarbeit zu gestalten?</li>



<li>Welche Probleme tauchen immer wieder auf – unabhängig vom Toolset?</li>



<li>Welche Spannungen sind systemisch – und welche machen wir unnötig persönlich?</li>



<li>Wo liegt der kleinste Hebel mit der größten Wirkung?</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Veränderung beginnt dort, wo Zusammenarbeit bewusst gestaltet wird</strong></h2>



<p class="wp-block-paragraph">Integral Facilitation ist keine Technik, die man einführt. Es ist eine Haltung zur Gestaltung von Zusammenarbeit in komplexen Umfeldern – und die Bereitschaft, mehrschichtig zu denken und zu handeln.</p>



<p class="wp-block-paragraph">Spannungen, Widerstände und Reibung werden dabei nicht als Störung gesehen, sondern als Hinweis darauf, wo Entwicklung möglich ist.</p>



<p class="wp-block-paragraph">Vielleicht ist der nächste Schritt kein neues Tool oder eine bessere KI.<br>Vielleicht ist es ein anderes Gespräch im Team. Oder der Mut, eine der Fragen aus diesem Artikel gemeinsam anzugehen.</p>



<p class="wp-block-paragraph">Nicht, um schneller oder effizienter zu werden. Sondern um wirksamer&nbsp; zusammenzuarbeiten.</p>



<p class="wp-block-paragraph">Dort beginnt Veränderung, die den Kern der Herausforderungen adressiert und nachhaltig wirkt.</p>



<p class="wp-block-paragraph">Was wäre möglich, wenn Du das in deinem Umfeld einfach einmal ausprobierst?</p>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-full"><img decoding="async" width="800" height="800" src="https://atra.consulting/wp-content/uploads/2025/10/Johannes-Uske.jpg" alt="" class="wp-image-8744" srcset="https://atra.consulting/wp-content/uploads/2025/10/Johannes-Uske.jpg 800w, https://atra.consulting/wp-content/uploads/2025/10/Johannes-Uske-768x768.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Johannes Uske</h3>



<p class="wp-block-paragraph">Agile Master</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Johannes<strong> </strong>ist ein erfahrener Agile Coach. Er bringt umfassende Erfahrungen in Transformationen, Scrum, SAFe und Teamentwicklung in den Bereichen IT, Konsumgüter, Banking und Automobil mit. Sein Fokus liegt auf praxisnahen Trainings, Führungskräfte-Coaching und systemischer Beratung, die nachhaltige Veränderungen und Selbstorganisation fördern. Durch den Einsatz partizipativer Methoden beseitigt er Blockaden und steigert den Teamerfolg. Johannes legt besonderen Wert auf psychologische Sicherheit, Produktqualität, Kundenzufriedenheit, Wertschätzung und kontinuierliche Verbesserung – und stärkt so Teams, um ihre Kollaboration zu optimieren.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:j.uske@atra.consulting">j.uske@atra.consulting</a>    <a href="https://de.linkedin.com/in/daniel-wochnik" target="_blank" rel="noreferrer noopener"></a></p>


</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Vom Vibe zum Validierungsprozess: Software Engineering wird zur Verifikations-Disziplin</title>
		<link>https://atra.consulting/uncategorized/vom-vibe-zum-validierungsprozess-software-engineering-wird-zur-verifikations-disziplin/</link>
		
		<dc:creator><![CDATA[Timo Kaiser]]></dc:creator>
		<pubDate>Mon, 16 Mar 2026 09:41:39 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=9128</guid>

					<description><![CDATA[Als ich vor einigen Monaten die ersten Gehversuche mit „Vibe-Coding“ unternahm, fühlte ich mich wie ein Magier. Ein kurzer Prompt, ein kurzes Warten, und – Puff – eine funktionale Web-Applikation stand vor mir. Doch der Kater ließ nicht lange auf sich warten. In einem Experiment lieferte mir die KI zwar in Rekordzeit ein Frontend, committete [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Als ich vor einigen Monaten die ersten Gehversuche mit „Vibe-Coding“ unternahm, fühlte ich mich wie ein Magier. Ein kurzer Prompt, ein kurzes Warten, und – <em>Puff</em> – eine funktionale Web-Applikation stand vor mir. Doch der Kater ließ nicht lange auf sich warten. In einem Experiment lieferte mir die KI zwar in Rekordzeit ein Frontend, committete aber trotz expliziter Warnungen sensible API-Keys direkt in das öffentliche Repository.</p>



<p class="wp-block-paragraph">Dieser Moment war ein klassischer Reality-Check. Er markiert den Punkt, an dem wir erkennen müssen: <strong>Die Kernkompetenz im Software Engineering verschiebt sich unwiderruflich von der Implementierung zur Verifikation.</strong> In einer Welt, in der wir zehnmal mehr Code produzieren können, müssen wir hundertmal besser darin werden, diesen zu prüfen. Qualitätssicherung rückt vom Ende der Kette direkt in das Zentrum der strategischen Wertschöpfung.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Die Psychologie des Scheiterns: Drei neue Anti-Patterns</strong></h2>



<p class="wp-block-paragraph">Wir müssen ehrlich sein: Wenn eine KI in Sekunden eine Lösung generiert, die syntaktisch brillant aussieht, schaltet unser Hirn in den Energiesparmodus. Wir verfallen in Verhaltensmuster, die im Enterprise-Umfeld fatale Folgen haben:</p>



<ol class="wp-block-list">
<li><strong>Der Rubber-Stamp-Reviewer:</strong> Man ertappt sich bei dem Gedanken: „Der Code sieht sauberer aus als das, was ich in einer Stunde mühsam händisch tippen würde.“ Man klickt auf <em>Approve</em>, ohne die logische Tiefe wirklich durchdrungen zu haben. Es ist eine Mischung aus falscher Bescheidenheit gegenüber der KI und schlichter Review-Fatigue.</li>



<li><strong>Die Illusion der Unit-Test-Abdeckung:</strong> Es ist verlockend, die KI den Code <em>und</em> die passenden Tests schreiben zu lassen. Doch das ist ein gefährlicher Zirkelschluss. Die KI beweist lediglich, dass ihr Code das tut, was sie glaubt, dass er tun soll. Die tatsächliche Business-Logik bleibt oft unvalidiert im Schatten.</li>



<li><strong>Die Gefahr der Kontext-Blindheit:</strong> KIs verstehen das „Was“, aber oft nur dann das „Warum“, wenn wir es ihnen explizit vorgeben. Wer sich blind auf generierte Lösungen verlässt, ohne architektonische Leitplanken zu setzen, importiert technologische Schulden in Rekordtempo. Die KI ist nicht per se „unwissend“ über Architektur – sie ist nur so gut wie der Kontext, den wir ihr zur Verfügung stellen.</li>
</ol>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Die strategische Konsequenz: Der Entwickler als Kurator</strong></h2>



<p class="wp-block-paragraph">Diese Verschiebung hat massive Auswirkungen auf die Organisation von IT-Teams. Wenn Code zur Commodity wird, ändert sich das Anforderungsprofil:</p>



<ul class="wp-block-list">
<li><strong>Seniorität durch Validierungskompetenz:</strong> Die Fähigkeit, Code zu schreiben, reicht nicht mehr aus. Ein Senior-Entwickler muss heute primär ein <strong>Senior-Validierer</strong> sein. Er braucht ein tieferes Verständnis für Softwarearchitektur und Security, um die subtilen Halluzinationen der KI im System-Kontext zu erkennen.</li>



<li><strong>Die Junior-Lücke:</strong> Wir laufen Gefahr, eine Generation von Entwicklern zu verlieren, die das „Handwerk“ nicht mehr von der Pike auf lernt. Unternehmen müssen hier aktiv mit Mentoring-Modellen gegensteuern, die den Fokus auf das „Lesen und Verstehen“ von Systemen legen.</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Der neue Audit-Cycle: Vier Säulen der Qualität</strong></h2>



<p class="wp-block-paragraph">Um die Geschwindigkeit des Vibe-Codings sicher zu beherrschen, brauchen wir eine klare Struktur. Es geht nicht um die Verlangsamung des Prozesses, sondern um seine Absicherung.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>1. Automatisierte Leitplanken (Hard Gates)</strong></h3>



<p class="wp-block-paragraph">Maschineller Code braucht maschinelle Kontrolle. SAST-Tools, Secrets Scanning und Architecture-Unit-Tests (wie ArchUnit) müssen jeden Commit scannen. Diese Tools fangen die „stochastischen Ausreißer“ ab, die LLMs prinzipbedingt immer wieder produzieren.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>2. Die Renaissance der Dokumentation (Contextual Excellence)</strong></h3>



<p class="wp-block-paragraph">Damit die KI nicht halluziniert, braucht sie erstklassigen Input. Wir erleben gerade, dass „alte“ Tugenden wie präzise <strong>PRDs</strong> (Product Requirement Documents) oder <strong>ADRs</strong> (Architecture Decision Records) zum kritischen Erfolgsfaktor werden. Tools wie <em>Claude Code</em> oder <em>Cursor</em> nutzen spezifische Konfigurationsdateien (z. B. CLAUDE.md oder .cursorrules), um Architektur-Leitplanken maschinenlesbar zu machen. Wer sauber dokumentiert, generiert sauberer.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>3. Agenten testen Agenten (Cross-Model Validation)</strong></h3>



<p class="wp-block-paragraph">Ein technisches Highlight ist der Einsatz spezialisierter Agenten-Kaskaden. Nutzen Sie die Konkurrenz der Modelle: Lassen Sie einen Architektur-Agenten die Einhaltung der Patterns überwachen und ein unabhängiges Review-LLM (z. B. Claude 3.5 Sonnet prüft GPT-4o-Output) nach logischen Fehlern suchen. Diese „Peer-AI“ deckt Blind Spots auf, die das ursprüngliche Modell systemisch übersieht.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>4. Die menschliche Kuration (Der finale Filter)</strong></h3>



<p class="wp-block-paragraph">Am Ende bleibt der Mensch als Architekt und Kurator unersetzlich. Seine Aufgabe ist die <strong>integrale Passfähigkeit</strong>: Entspricht die Lösung unseren langfristigen Wartbarkeits-Zielen? Ist die kognitive Last für das Team noch tragbar? Der Mensch unterschreibt nicht mehr für die Zeile Code, sondern für die Sinnhaftigkeit der Lösung im Gesamtgefüge.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Fazit: Skalierung der Verantwortung</strong></h2>



<p class="wp-block-paragraph">KI beschleunigt nicht nur unsere Entwicklung – sie skaliert auch unsere Fehler. Wer glaubt, durch generative Tools QA-Ressourcen einsparen zu können, begeht einen strategischen Irrtum. Wir müssen die freiwerdende Zeit bei der Implementierung konsequent in die Vorbereitung (Kontext) und die Verifikation (Audit) investieren.</p>



<p class="wp-block-paragraph">Professionalität im Jahr 2026 bedeutet: Wir nutzen den „Vibe“ für die Geschwindigkeit, aber wir bauen auf einer glasklaren Dokumentation und harten Architektur-Kompetenz für die Stabilität. Wer die Verifikation vernachlässigt, baut kein System, sondern ein Kartenhaus auf Steroiden.</p>



<p class="wp-block-paragraph"><strong>Die Frage ist nicht, wie schnell Ihre Agenten heute coden können – sondern wie präzise Ihre architektonischen Leitplanken sind, die sie daran hindern, in die falsche Richtung zu rennen.</strong></p>



<p class="wp-block-paragraph"><em>Meta-Hinweis: Dieser Text ist ein Experiment in eigener Sache. Er wurde vollständig generativ erstellt, wobei Few-Shot-Learnings meiner bisherigen Publikationen genutzt wurden, um meinen persönlichen Stil so authentisch wie möglich abzubilden. Während die Inhalte auf unserer realen Projekterfahrung bei atra.consulting basieren, fungierten wir – passend zur Kernthese des Artikels – als menschliche Kuratoren für die finale Validierung.</em></p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-full"><img decoding="async" width="425" height="425" src="https://atra.consulting/wp-content/uploads/2025/01/profilbild-daniel-wochnik-500-x-500px.jpg" alt="Daniel Wochnik, Geschäftsbereichsleitung Finanzdienstleistungen" class="wp-image-3216" style="object-fit:cover" title="Team-Schwarze"/></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Daniel Wochnik</h3>



<p class="wp-block-paragraph">Geschäftsbereichsleitung »Finanzdienstleistungen«</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Daniel ist seit 2017 in der IT-Branche aktiv und bringt seine umfassende Erfahrung als Senior Managing Consultant und Geschäftsbereichsleiter für Finanzdienstleistungen bei atra.consulting ein. Besonders begeistert ihn das Zusammenspiel technischer, methodischer und organisatorischer Aspekte. Als leidenschaftlicher Läufer und bekennender 1. FC Köln-Fan hat er seine Leidensfähigkeit auch privat mehrfach unter Beweis gestellt. Seine Kunden unterstützt er als Softwarearchitekt, agiler Coach und Berater bei der nachhaltigen und zielgerichteten Umsetzung von Entwicklungsprojekten.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:d.wochnik@atra.consulting">d.wochnik@atra.consulting</a>&nbsp; &nbsp;&nbsp;<a href="https://de.linkedin.com/in/daniel-wochnik" target="_blank" rel="noreferrer noopener"></a></p>



<ul class="wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a href="https://de.linkedin.com/in/daniel-wochnik" class="wp-block-social-link-anchor" target="_blank" rel="noopener"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li></ul>
</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Vom Spring Starter zur hexagonalen Architektur mit Kotlin</title>
		<link>https://atra.consulting/engineering/vom-spring-starter-zur-hexagonalen-architektur/</link>
		
		<dc:creator><![CDATA[Daniel Schock]]></dc:creator>
		<pubDate>Wed, 11 Mar 2026 13:13:46 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Consulting]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=9092</guid>

					<description><![CDATA[Einleitung In der modernen Softwareentwicklung wird häufig mit monolithischen Strukturen begonnen, um schnell sichtbare Ergebnisse zu erzielen. Startpunkt ist oft ein einfaches Spring Boot Projekt, generiert über Initializer wie start.spring.io. Mit zunehmender Komplexität und wachsenden Anforderungen stoßen diese Strukturen jedoch an ihre Grenzen: Die Wartbarkeit sinkt, die Testbarkeit wird erschwert und technische Abhängigkeiten vermischen sich [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Einleitung</h2>



<p class="wp-block-paragraph">In der modernen Softwareentwicklung wird häufig mit monolithischen Strukturen begonnen, um schnell sichtbare Ergebnisse zu erzielen. Startpunkt ist oft ein einfaches Spring Boot Projekt, generiert über Initializer wie <strong>start.spring.io</strong>. Mit zunehmender Komplexität und wachsenden Anforderungen stoßen diese Strukturen jedoch an ihre Grenzen: Die Wartbarkeit sinkt, die Testbarkeit wird erschwert und technische Abhängigkeiten vermischen sich untrennbar mit der fachlichen Logik.</p>



<p class="wp-block-paragraph">Eine Lösung für diese Herausforderungen bietet die hexagonale Architektur (auch bekannt als &#8222;Ports and Adapters&#8220;). Durch sie wird die Geschäftslogik ins Zentrum der Anwendung gerückt und von äußeren Einflüssen wie Datenbanken, Benutzeroberflächen oder externen APIs isoliert.</p>



<p class="wp-block-paragraph">Dieser Artikel beschreibt die schrittweise Migration eines klassischen Spring Boot Monolithen hin zu einer modularisierten, hexagonalen Architektur unter Verwendung von Kotlin und Gradle. Es wird aufgezeigt, wie durch klare Modulgrenzen und definiertes Dependency Management eine langlebige und flexible Software-Architektur entsteht.</p>



<p class="wp-block-paragraph">Zur besseren Nachvollziehbarkeit lassen sich die einzelnen Abschnitte Commit für Commit im <a href="https://github.com/atra-consulting/hexagon" target="_blank" rel="noopener">GitHub-Repository</a> nachvollziehen, der Zustand nach jedem Kapitel ist mit einem Git-Tag markiert.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Kapitel 0: Der Start</h2>



<p class="wp-block-paragraph">Als Ausgangszustand dient ein frisch generiertes Projekt von start.spring.io, welches das typische &#8222;Vorher&#8220;-Bild einer Anwendung darstellt.</p>



<ol class="wp-block-list">
<li>Es wird zu start.spring.io navigiert.</li>



<li>Folgende Konfiguration wird ausgewählt:
<ul class="wp-block-list">
<li><strong>Project:</strong> Gradle &#8211; Kotlin</li>



<li><strong>Language:</strong> Kotlin</li>



<li><strong>Spring Boot:</strong> (eine aktuelle Version, z.B. 3.5.x)</li>



<li><strong>Java:</strong> 21</li>



<li><strong>Dependencies:</strong>
<ul class="wp-block-list">
<li>Spring Web</li>



<li>Spring Data JPA</li>



<li>H2 Database</li>



<li>Spring Boot DevTools (optional)</li>



<li>Spring Configuration Processor (optional)</li>
</ul>
</li>
</ul>
</li>



<li>Das Projekt wird generiert, heruntergeladen und in der IDE geöffnet.</li>
</ol>



<p class="wp-block-paragraph">Es zeigt sich die typische, flache Spring-Boot-Struktur: Alle Komponenten befinden sich in src/main/kotlin unter einem Hauptpaket.</p>



<p class="wp-block-paragraph">Diese Struktur eignet sich ideal für einen schnellen Start. Nachteile werden jedoch sichtbar, sobald das Projekt wächst:</p>



<ul class="wp-block-list">
<li><strong>Keine Trennung von Belangen:</strong> Web-Logik (Controller), Business-Logik (Services) und Datenbank-Logik (Repositories, Entities) sind eng miteinander verwoben.</li>



<li><strong>Schwere Testbarkeit:</strong> Das Testen echter Business-Logik ohne das Hochfahren des Webservers oder das Mocken einer Datenbank gestaltet sich kompliziert.</li>



<li><strong>Technologie-Kopplung:</strong> Die Business-Logik ist untrennbar mit Spring-Annotationen (<strong>@Service</strong>, <strong>@Entity</strong>) und JPA verbunden.</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Kapitel 1: Der Monolith</h2>



<p class="wp-block-paragraph">Um eine Refactoring-Basis zu schaffen, wird zunächst eine funktionierende, wenn auch architektonisch einfach strukturierte Anwendung aufgebaut. Als Beispiel dient ein simples &#8222;Produkt&#8220;, welches wir über REST-API in einer Datenbank ansprechen können. Folgendes Diagramm veranschaulicht die Zielsetzung.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e53fad&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e53fad" class="aligncenter size-large wp-lightbox-container"><img decoding="async" width="1024" height="338" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/image-12-e1773047309167-1024x338.png" alt="" class="wp-image-9096" srcset="https://atra.consulting/wp-content/uploads/2026/03/image-12-e1773047309167-1024x338.png 1024w, https://atra.consulting/wp-content/uploads/2026/03/image-12-e1773047309167-768x253.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;--cbp-line-number-width:calc(2 * 0.6 * 1rem);line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>classDiagram
    direction RL
    class Product {
        &lt;&lt;Entity / data class>>
        +Long? id
        +String name
        +Double price
    }
    class ProductsRepository {
        &lt;&lt;interface>>
    }
    class ProductsController {
        &lt;&lt;RestController>>
        -ProductsRepository repository
        +list() List~Product~
        +create(Product product) Product
        +get(Long id) Product?
        +update(Long id, Double discount) Product?
    }
    ProductsRepository ..> Product : manages
    ProductsController --> ProductsRepository : repository
    ProductsController ..> Product : uses</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">classDiagram</span></span>
<span class="line"><span style="color: #D4D4D4">    direction RL</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;Entity / </span><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> class&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +Long? id</span></span>
<span class="line"><span style="color: #D4D4D4">        +String name</span></span>
<span class="line"><span style="color: #D4D4D4">        +Double price</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsRepository</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsController</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;RestController&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        -ProductsRepository repository</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">list</span><span style="color: #D4D4D4">() List~Product~</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">create</span><span style="color: #D4D4D4">(Product product) Product</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #569CD6">get</span><span style="color: #D4D4D4">(Long id) Product?</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">update</span><span style="color: #D4D4D4">(Long id, Double discount) Product?</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsRepository ..&gt; Product : </span><span style="color: #4EC9B0">manages</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsController -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> ProductsRepository : </span><span style="color: #4EC9B0">repository</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsController ..&gt; Product : </span><span style="color: #4EC9B0">uses</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Zuerst wird die <strong>Product.kt</strong> Klasse erstellt. Sie fungiert gleichzeitig als <strong>@Entity</strong> und <strong>data class</strong> – eine Klasse, die sämtliche Verantwortlichkeiten bündelt:</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// src/main/kotlin/consulting/atra/hexagon/Product.kts

package consulting.atra.hexagon  
import jakarta.persistence.Entity  
import jakarta.persistence.GeneratedValue  
import jakarta.persistence.Id  

@Entity  
data class Product(  
    @Id  
    @GeneratedValue
    var id: Long? = null,  
    var name: String,  
    var price: Double,
)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// src/main/kotlin/consulting/atra/hexagon/Product.kts</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> jakarta.persistence.Entity  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> jakarta.persistence.GeneratedValue  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> jakarta.persistence.Id  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #4EC9B0">@Entity</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@Id</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@GeneratedValue</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">? = </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> name: </span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> price: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">)</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Als Nächstes folgt das <strong>ProductsRepository.kt</strong>, definiert als einfaches Spring Data <strong>JpaRepository</strong>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// src/main/kotlin/consulting/atra/hexagon/ProductsRepository.kt

package consulting.atra.hexagon  
import org.springframework.data.jpa.repository.JpaRepository  
interface ProductsRepository: JpaRepository&lt;Product, Long>
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// src/main/kotlin/consulting/atra/hexagon/ProductsRepository.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.data.jpa.repository.JpaRepository  </span></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsRepository</span><span style="color: #D4D4D4">: </span><span style="color: #4EC9B0">JpaRepository</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">, </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">&gt;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Zuletzt wird der <strong>ProductsController.kt</strong> implementiert. Dieser <strong>@RestController</strong> injiziert das <strong>ProductsRepository</strong> direkt und verwendet das Product-Entity sowohl als Request- als auch als Response-Objekt:</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// src/main/kotlin/consulting/atra/hexagon/ProductsController.kt
package consulting.atra.hexagon  
import org.springframework.web.bind.annotation.GetMapping  
import org.springframework.web.bind.annotation.PatchMapping  
import org.springframework.web.bind.annotation.PathVariable  
import org.springframework.web.bind.annotation.PostMapping  
import org.springframework.web.bind.annotation.RequestBody  
import org.springframework.web.bind.annotation.RequestMapping  
import org.springframework.web.bind.annotation.RequestParam  
import org.springframework.web.bind.annotation.RestController  
@RestController  
@RequestMapping("/api/v1/products")  
class ProductsController(  
    private val repository: ProductsRepository,  
) {  
    @GetMapping  
    fun list(): List&lt;Product> = repository.findAll()  
    @PostMapping  
    fun create(@RequestBody product: Product): Product =
repository.save(product)  
    @GetMapping("/{id}")  
    fun get(@PathVariable id: Long): Product? =
repository.findById(id).orElse(null)  
    @PatchMapping("/{id}")  
    fun update(@PathVariable id: Long, @RequestParam discount: Double): Product? {  
        var product = repository.findById(id).orElse(null)  
        if (product != null) {  
            product.price *= (1 - discount / 100)  
            product = repository.save(product)  
        }  
        return product  
    }  
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// src/main/kotlin/consulting/atra/hexagon/ProductsController.kt</span></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.GetMapping  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.PatchMapping  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.PathVariable  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.PostMapping  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.RequestBody  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.RequestMapping  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.RequestParam  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.RestController  </span></span>
<span class="line"><span style="color: #4EC9B0">@RestController</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #4EC9B0">@RequestMapping</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;/api/v1/products&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsController</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> repository: </span><span style="color: #4EC9B0">ProductsRepository</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">) {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@GetMapping</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">list</span><span style="color: #D4D4D4">(): </span><span style="color: #4EC9B0">List</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">&gt; = repository.</span><span style="color: #DCDCAA">findAll</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@PostMapping</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">create</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">@RequestBody</span><span style="color: #D4D4D4"> product: </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4"> =</span></span>
<span class="line"><span style="color: #D4D4D4">repository.</span><span style="color: #DCDCAA">save</span><span style="color: #D4D4D4">(product)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@GetMapping</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;/{id}&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">get</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">@PathVariable</span><span style="color: #D4D4D4"> id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">? =</span></span>
<span class="line"><span style="color: #D4D4D4">repository.</span><span style="color: #DCDCAA">findById</span><span style="color: #D4D4D4">(id).</span><span style="color: #DCDCAA">orElse</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@PatchMapping</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;/{id}&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">update</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">@PathVariable</span><span style="color: #D4D4D4"> id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">, </span><span style="color: #4EC9B0">@RequestParam</span><span style="color: #D4D4D4"> discount: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">? {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> product = repository.</span><span style="color: #DCDCAA">findById</span><span style="color: #D4D4D4">(id).</span><span style="color: #DCDCAA">orElse</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (product != </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">) {  </span></span>
<span class="line"><span style="color: #D4D4D4">            product.price *= (</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> - discount / </span><span style="color: #B5CEA8">100</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">            product = repository.</span><span style="color: #DCDCAA">save</span><span style="color: #D4D4D4">(product)  </span></span>
<span class="line"><span style="color: #D4D4D4">        }  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> product  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Wird die Anwendung gestartet und die API aufgerufen, ist die Funktionalität gegeben.</p>



<p class="wp-block-paragraph">Das Problem hierbei ist jedoch ersichtlich: Der Controller gibt die Datenbank-Entität (<strong>Product</strong>) direkt an den Client weiter. Jede Änderung an der Datenbankstruktur (z.B. das Hinzufügen einer internen Spalte) stellt sofort einen &#8222;Breaking Change&#8220; für die API dar. Die API ist somit ein direktes Abbild der Datenbank.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Kapitel 2: Die neue Struktur</h2>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e55025&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e55025" class="aligncenter size-large wp-lightbox-container"><img decoding="async" width="1024" height="576" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/image-9-edited-1024x576.png" alt="" class="wp-image-9104" srcset="https://atra.consulting/wp-content/uploads/2026/03/image-9-edited-1024x576.png 1024w, https://atra.consulting/wp-content/uploads/2026/03/image-9-edited-768x432.png 768w, https://atra.consulting/wp-content/uploads/2026/03/image-9-edited-780x440.png 780w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>graph TD
    direction TB
    Application&#91;":application"&#93;
    Domain&#91;":domain"&#93;
    Endpoint&#91;":adapters:endpoint"&#93;
    Persistence&#91;":adapters:persistence"&#93;
    Application --> Domain
    Application --> Endpoint
    Application --> Persistence
    Endpoint --> Domain
    Persistence --> Domain</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">graph TD</span></span>
<span class="line"><span style="color: #D4D4D4">    direction TB</span></span>
<span class="line"><span style="color: #D4D4D4">    Application&#91;</span><span style="color: #CE9178">&quot;:application&quot;</span><span style="color: #D4D4D4">&#93;</span></span>
<span class="line"><span style="color: #D4D4D4">    Domain&#91;</span><span style="color: #CE9178">&quot;:domain&quot;</span><span style="color: #D4D4D4">&#93;</span></span>
<span class="line"><span style="color: #D4D4D4">    Endpoint&#91;</span><span style="color: #CE9178">&quot;:adapters:endpoint&quot;</span><span style="color: #D4D4D4">&#93;</span></span>
<span class="line"><span style="color: #D4D4D4">    Persistence&#91;</span><span style="color: #CE9178">&quot;:adapters:persistence&quot;</span><span style="color: #D4D4D4">&#93;</span></span>
<span class="line"><span style="color: #D4D4D4">    Application -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> Domain</span></span>
<span class="line"><span style="color: #D4D4D4">    Application -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> Endpoint</span></span>
<span class="line"><span style="color: #D4D4D4">    Application -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> Persistence</span></span>
<span class="line"><span style="color: #D4D4D4">    Endpoint -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> Domain</span></span>
<span class="line"><span style="color: #D4D4D4">    Persistence -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> Domain</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Nun wird das Fundament für die logische Trennung gelegt. Das einfache Projekt wird in ein Multi-Modul-Projekt umgewandelt.</p>



<p class="wp-block-paragraph">Die Idee ist es, die Geschäftslogik, die eingehende und die ausgehende Kommunikation des Monolithen zu trennen und in einzelne Gradle-Module zu verlagern. Folgende Dateistruktur dient als Zielbild der Umstrukturierung:</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>.
├── adapters
│   ├── endpoint
│   │   └── build.gradle.kts
│   └── persistence
│       └── build.gradle.kts
├── application
│   ├── src
│   └── build.gradle.kts
├── domain
│   ├── src
│   └── build.gradle.kts
├── gradle
│   ├── wrapper
│   │   ├── gradle-wrapper.jar
│   │   └── gradle-wrapper.properties
│   └── libs.versions.toml
├── build.gradle.kts
├── CHANGELOG.md
├── CONTRIBUTING.md 
├── .editorconfig
├── .gitattributes
├── .gitignore
├── gradle.properties
├── gradlew
├── gradlew.bat
├── LICENSE
├── README.md
└── settings.gradle.kts</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">.</span></span>
<span class="line"><span style="color: #D4D4D4">├── adapters</span></span>
<span class="line"><span style="color: #D4D4D4">│   ├── endpoint</span></span>
<span class="line"><span style="color: #D4D4D4">│   │   └── build.gradle.kts</span></span>
<span class="line"><span style="color: #D4D4D4">│   └── persistence</span></span>
<span class="line"><span style="color: #D4D4D4">│       └── build.gradle.kts</span></span>
<span class="line"><span style="color: #D4D4D4">├── application</span></span>
<span class="line"><span style="color: #D4D4D4">│   ├── src</span></span>
<span class="line"><span style="color: #D4D4D4">│   └── build.gradle.kts</span></span>
<span class="line"><span style="color: #D4D4D4">├── domain</span></span>
<span class="line"><span style="color: #D4D4D4">│   ├── src</span></span>
<span class="line"><span style="color: #D4D4D4">│   └── build.gradle.kts</span></span>
<span class="line"><span style="color: #D4D4D4">├── gradle</span></span>
<span class="line"><span style="color: #D4D4D4">│   ├── wrapper</span></span>
<span class="line"><span style="color: #D4D4D4">│   │   ├── gradle-wrapper.jar</span></span>
<span class="line"><span style="color: #D4D4D4">│   │   └── gradle-wrapper.properties</span></span>
<span class="line"><span style="color: #D4D4D4">│   └── libs.versions.toml</span></span>
<span class="line"><span style="color: #D4D4D4">├── build.gradle.kts</span></span>
<span class="line"><span style="color: #D4D4D4">├── CHANGELOG.md</span></span>
<span class="line"><span style="color: #D4D4D4">├── CONTRIBUTING.md </span></span>
<span class="line"><span style="color: #D4D4D4">├── .editorconfig</span></span>
<span class="line"><span style="color: #D4D4D4">├── .gitattributes</span></span>
<span class="line"><span style="color: #D4D4D4">├── .gitignore</span></span>
<span class="line"><span style="color: #D4D4D4">├── gradle.properties</span></span>
<span class="line"><span style="color: #D4D4D4">├── gradlew</span></span>
<span class="line"><span style="color: #D4D4D4">├── gradlew.bat</span></span>
<span class="line"><span style="color: #D4D4D4">├── LICENSE</span></span>
<span class="line"><span style="color: #D4D4D4">├── README.md</span></span>
<span class="line"><span style="color: #D4D4D4">└── settings.gradle.kts</span></span></code></pre></div>



<p class="wp-block-paragraph">Damit die Migrationsgrundlage erhalten bleibt, wird der <strong>src</strong>-Ordner zunächst in den zuvor erstellten <strong>application</strong>-Ordner verschoben.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">Kapitel 2.1: <strong>settings.gradle.kts</strong></h3>



<p class="wp-block-paragraph">Die <strong>settings.gradle.kts</strong> erfordert nun Aufmerksamkeit, da hier die Module definiert und die Grundlage eines zentralen Plugin- und Dependency-Managements geschaffen wird. Bisher war lediglich der Projektname hinterlegt.</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>rootProject.name = "hexagon"

// ...</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">rootProject.name = </span><span style="color: #CE9178">&quot;hexagon&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">// ...</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Es wird ein <strong>pluginManagement</strong>-Block für die zentral definierte Plugin-Auflösung ergänzt:</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// ...

pluginManagement {  
    repositories {  
        gradlePluginPortal()  
    }  
}

// ...</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">pluginManagement</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">repositories</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">gradlePluginPortal</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">// ...</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Die Auflösung der Dependencies wird durch den <strong>dependencyResolutionManagement</strong>-Block gesteuert. Das Überschreiben der Repositories durch Module kann verhindert werden, indem der <strong>RepositoriesMode</strong> auf <strong>FAIL_ON_PROJECT_REPOS</strong> gesetzt wird. Da Gradle bei der Nutzung von <strong>repositories</strong> und <strong>repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)</strong> im <strong>dependencyResolutionManagement</strong>-Block eine Warnung bezüglich <strong>UnstableApiUsage</strong> ausgibt, wird diese mit <strong>@Suppress(&#8222;UnstableApiUsage&#8220;)</strong> bewusst unterdrückt.</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// ...

@Suppress("UnstableApiUsage")  
dependencyResolutionManagement {  
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)  
    repositories {  
        mavenCentral()  
    }  
}

// ...</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"></span>
<span class="line"><span style="color: #4EC9B0">@Suppress</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;UnstableApiUsage&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #DCDCAA">dependencyResolutionManagement</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    repositoriesMode.</span><span style="color: #DCDCAA">set</span><span style="color: #D4D4D4">(RepositoriesMode.FAIL_ON_PROJECT_REPOS)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">repositories</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">mavenCentral</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">// ...</span></span></code></pre></div>



<p class="wp-block-paragraph">Mit einem <strong>include</strong>-Statement wird die <strong>settings.gradle.kts</strong> für ein modulares Gradle-Projekt vorbereitet. Hier werden die Module hinterlegt, wobei es für Gradle zu diesem Zeitpunkt unerheblich ist, ob die Ordner bereits existieren oder dazugehörige <strong>build.gradle.kts</strong>-Dateien enthalten sind.</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// ...
include(  
    ":application",  
    ":domain",  
    ":adapters:endpoint",  
    ":adapters:persistence",  
)
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #DCDCAA">include</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #CE9178">&quot;:application&quot;</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #CE9178">&quot;:domain&quot;</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #CE9178">&quot;:adapters:endpoint&quot;</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #CE9178">&quot;:adapters:persistence&quot;</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">)</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Die fertige <strong>settings.gradle.kts</strong> stellt sich damit wie folgt dar:</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// settings.gradle.kts

rootProject.name = "hexagon"  

pluginManagement {  
    repositories {  
        gradlePluginPortal()  
    }  
}  

@Suppress("UnstableApiUsage")  
dependencyResolutionManagement {  
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)  
    repositories {  
        mavenCentral()  
    }  
}  

include(  
    ":application",  
    ":domain",  
    ":adapters:endpoint",  
    ":adapters:persistence",  
)
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// settings.gradle.kts</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">rootProject.name = </span><span style="color: #CE9178">&quot;hexagon&quot;</span><span style="color: #D4D4D4">  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">pluginManagement</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">repositories</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">gradlePluginPortal</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #4EC9B0">@Suppress</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;UnstableApiUsage&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #DCDCAA">dependencyResolutionManagement</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    repositoriesMode.</span><span style="color: #DCDCAA">set</span><span style="color: #D4D4D4">(RepositoriesMode.FAIL_ON_PROJECT_REPOS)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">repositories</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">mavenCentral</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">include</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #CE9178">&quot;:application&quot;</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #CE9178">&quot;:domain&quot;</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #CE9178">&quot;:adapters:endpoint&quot;</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #CE9178">&quot;:adapters:persistence&quot;</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">)</span></span>
<span class="line"></span></code></pre></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">Kapitel 2.2: <strong>build.gradle.kts</strong></h3>



<p class="wp-block-paragraph">Das Herzstück der modularen Konfiguration bildet die <strong>build.gradle.kts</strong>. Hier werden projektweit gemeinsame Abhängigkeiten definiert und Gradle-Plugins konfiguriert.</p>



<p class="wp-block-paragraph">Um die Versionen der verwendeten Gradle-Plugins zentral zu steuern, werden diese mit Versionsnummer projektweit in der <strong>build.gradle.kts</strong> definiert, die Verwendung jedoch gleichzeitig mit einem <strong>apply false</strong> verhindert. Dies ist notwendig, da Gradle die Plugins sonst im <strong>rootProject</strong> hinterlegen und ausführen würde. Da unterschiedliche Module unterschiedliche Konfigurationen benötigen, muss gezielt kontrolliert werden, welches Modul welches Plugin erhält.</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>plugins {  
    kotlin("jvm") version "1.9.25" apply false  
    kotlin("plugin.spring") version "1.9.25" apply false  
    id("org.springframework.boot") version "3.5.7" apply false  
    id("io.spring.dependency-management") version "1.1.7" apply false  
    kotlin("plugin.jpa") version "1.9.25" apply false  
}
// ...
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">plugins</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">kotlin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;jvm&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;1.9.25&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">kotlin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;plugin.spring&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;1.9.25&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">id</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;3.5.7&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">id</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;io.spring.dependency-management&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;1.1.7&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">kotlin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;plugin.jpa&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;1.9.25&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Um gemeinsame Konfigurationen auf die Module anzuwenden, bietet Gradle unter anderem die Blöcke allprojects und subprojects an. allprojects konfiguriert alle Module, darunter auch das rootProject, während subprojects nur die untergeordneten Module betrifft. Für allprojects werden lediglich group und version gesetzt.</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// ...
allprojects {  
    group = "consulting.atra.hexagon"  
    version = "0.0.0"  
}
// ...
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #DCDCAA">allprojects</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    group = </span><span style="color: #CE9178">&quot;consulting.atra.hexagon&quot;</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    version = </span><span style="color: #CE9178">&quot;0.0.0&quot;</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Für weitere grundlegende Modul-Konfigurationen wird der <strong>subprojects</strong>-Block verwendet. Hier werden unter anderem die Compiler-Settings, die Java-Version und Dependencies festgelegt. Zuerst werden die Plugins geladen, die das Grund-Setup der Module benötigt.</p>



<ul class="wp-block-list">
<li><strong>java-library</strong> schaltet grundsätzliche Java-Compiler-Features frei; so kann die Java-Version erst mit diesem Plugin gesetzt werden. Darüber hinaus können mit dem Plugin kompatible Abhängigkeiten unter den einzelnen Modulen erreicht werden.</li>



<li><strong>org.jetbrains.kotlin.jvm</strong> stellt den Kotlin-Compiler bereit und ermöglicht dadurch die Verwendung von Kotlin in der <strong>JVM</strong>.</li>



<li><strong>org.springframework.boot</strong> bietet viele Funktionen rund um das Spring-Boot-Framework; vom Starten der Anwendung bis hin zum Bauen eines Images steht alles mit diesem Plugin zur Verfügung.</li>



<li><strong>org.jetbrains.kotlin.plugin.spring</strong> erweitert den Kotlin-Compiler um benötigte <strong>spring boot</strong> Features.</li>



<li><strong>io.spring.dependency-management</strong> wird für die Abhängigkeitsverwaltung verwendet. Im nächsten Kapitel wird dieses Plugin durch ein Gradle-eigenes Feature ersetzt.</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// ...

subprojects {
    apply {  
        plugin("java-library")  
        plugin("org.jetbrains.kotlin.jvm")  
        plugin("org.springframework.boot")  
        plugin("org.jetbrains.kotlin.plugin.spring") 
        plugin("org.jetbrains.kotlin.plugin.jpa") 
        plugin("io.spring.dependency-management")  
    }

    // ...
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">subprojects</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">apply</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;java-library&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.jetbrains.kotlin.jvm&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.jetbrains.kotlin.plugin.spring&quot;</span><span style="color: #D4D4D4">) </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.jetbrains.kotlin.plugin.jpa&quot;</span><span style="color: #D4D4D4">) </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;io.spring.dependency-management&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Bevor Abhängigkeiten definiert werden, verlangt Spring Boot das Erweitern der <strong>DependencyConfiguration</strong> <strong>compileOnly</strong> von <strong>annotationProcessor</strong>. <strong>DependencyConfigurations</strong> sind <strong>ClassPath</strong>-Container, in denen kompilierte Artefakte hinterlegt sind. Dadurch können Abhängigkeiten für einzelne Zwecke selektiv verwendet werden. So ist es beispielsweise möglich, für Tests andere Bibliotheken zu nutzen als für die eigentliche Implementierung, oder Bibliotheken nur während der <strong>RunTime</strong> zu verwenden, die zum Kompilieren nicht benötigt werden.</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// ...

subprojects {
    // ...
    val annotationProcessor by configurations  
    val compileOnly by configurations  
    val implementation by configurations  
    val testImplementation by configurations  
    val testRuntimeOnly by configurations  

    configurations {  
        compileOnly.extendsFrom(annotationProcessor)  
    }  

    dependencies {  
        implementation("org.jetbrains.kotlin:kotlin-reflect")
        testImplementation("org.springframework.boot:spring-boot-starter-test")  
        testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")  
        testRuntimeOnly("org.junit.platform:junit-platform-launcher")  
    }

    // ...
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">subprojects</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> annotationProcessor </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> compileOnly </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> implementation </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> testImplementation </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> testRuntimeOnly </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">configurations</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        compileOnly.</span><span style="color: #DCDCAA">extendsFrom</span><span style="color: #D4D4D4">(annotationProcessor)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">dependencies</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.jetbrains.kotlin:kotlin-reflect&quot;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testImplementation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot:spring-boot-starter-test&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testImplementation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.jetbrains.kotlin:kotlin-test-junit5&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testRuntimeOnly</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.junit.platform:junit-platform-launcher&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Anschließend werden die Extensions konfiguriert. Gradle erlaubt es, die DSL über Extensions zu erweitern. Soll diese in subprojects oder allprojects konfiguriert werden, muss dies über die configure&lt;?&gt;-Anweisung geschehen. Für Spring Boot und Kotlin müssen die JavaLanguageVersion in der JavaPluginExtension, die compilerOptions in der KotlinJvmProjectExtension und JPA-relevante Settings in der AllOpenExtension konfiguriert werden.</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// ...

subprojects {

    // ...

    configure&lt;JavaPluginExtension> {  
        toolchain {  
            languageVersion = JavaLanguageVersion.of(21)  
        }
    }  
    
    configure&lt;KotlinJvmProjectExtension> {  
        compilerOptions {  
            freeCompilerArgs.add("-Xjsr305=strict")  
        }  
    }
  
    configure&lt;AllOpenExtension> {  
        annotation("jakarta.persistence.Entity")  
        annotation("jakarta.persistence.MappedSuperclass")  
        annotation("jakarta.persistence.Embeddable")  
    }

    // ...
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">subprojects</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// ...</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">configure</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">JavaPluginExtension</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">toolchain</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">            languageVersion = JavaLanguageVersion.</span><span style="color: #DCDCAA">of</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">21</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        }</span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">configure</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">KotlinJvmProjectExtension</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">compilerOptions</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">            freeCompilerArgs.</span><span style="color: #DCDCAA">add</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;-Xjsr305=strict&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        }  </span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">configure</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">AllOpenExtension</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">annotation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;jakarta.persistence.Entity&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">annotation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;jakarta.persistence.MappedSuperclass&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">annotation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;jakarta.persistence.Embeddable&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Zu guter Letzt werden die Tasks der subprojects konfiguriert. In diesem Fall wird&nbsp; die Nutzung der JUnitPlatform für Tasks des Typs Test angewiesen und der BootJar-Task deaktiviert, da ansonsten das Spring-Boot-Plugin in allen konfigurierten Modulen eine Main-Methode sucht, aber nicht findet.</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// ...

subprojects {

    // ...
    tasks {  
        withType&lt;Test> {  
            useJUnitPlatform()  
        }  
        withType&lt;BootJar> {  
            enabled = false  
        }
    }  
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">subprojects</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">tasks</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">withType</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Test</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">useJUnitPlatform</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"><span style="color: #D4D4D4">        }  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">withType</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">BootJar</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">            enabled = </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">        }</span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Damit sieht die vollständige <strong>build.gradle.kts</strong> wie folgt aus:</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// build.gradle.kts

import org.jetbrains.kotlin.allopen.gradle.AllOpenExtension  
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension  

plugins {  
    kotlin("jvm") version "1.9.25" apply false  
    kotlin("plugin.spring") version "1.9.25" apply false  
    id("org.springframework.boot") version "3.5.7" apply false  
    id("io.spring.dependency-management") version "1.1.7" apply false  
    kotlin("plugin.jpa") version "1.9.25" apply false  
}  

allprojects {  
    group = "consulting.atra.hexagon"  
    version = "0.0.0"  
}  

subprojects {  
    apply {  
        plugin("java-library")  
        plugin("org.jetbrains.kotlin.jvm")  
        plugin("org.springframework.boot")  
        plugin("org.jetbrains.kotlin.plugin.spring")  
        plugin("io.spring.dependency-management")  
    }  
    val annotationProcessor by configurations  
    val compileOnly by configurations  
    val implementation by configurations  
    val testImplementation by configurations  
    val testRuntimeOnly by configurations  
    configurations {  
        compileOnly.extendsFrom(annotationProcessor)  
    }  
    dependencies {  
        implementation("org.jetbrains.kotlin:kotlin-reflect")  
        testImplementation("org.springframework.boot:spring-boot-starter-test")  
        testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")  
        testRuntimeOnly("org.junit.platform:junit-platform-launcher")  
    }  
    configure&lt;JavaPluginExtension> {  
        toolchain {  
            languageVersion = JavaLanguageVersion.of(21)  
        }  
    }  
    configure&lt;KotlinJvmProjectExtension> {  
        compilerOptions {  
            freeCompilerArgs.add("-Xjsr305=strict")  
        }  
    }  
    configure&lt;AllOpenExtension> {  
        annotation("jakarta.persistence.Entity")  
        annotation("jakarta.persistence.MappedSuperclass")  
        annotation("jakarta.persistence.Embeddable")  
    }  
    tasks {  
        withType&lt;Test> {  
            useJUnitPlatform()  
        }

        withType&lt;BootJar> {  
            enabled = false  
        }  
    }  
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// build.gradle.kts</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.jetbrains.kotlin.allopen.gradle.AllOpenExtension  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">plugins</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">kotlin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;jvm&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;1.9.25&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">kotlin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;plugin.spring&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;1.9.25&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">id</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;3.5.7&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">id</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;io.spring.dependency-management&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;1.1.7&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">kotlin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;plugin.jpa&quot;</span><span style="color: #D4D4D4">) version </span><span style="color: #CE9178">&quot;1.9.25&quot;</span><span style="color: #D4D4D4"> apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">allprojects</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    group = </span><span style="color: #CE9178">&quot;consulting.atra.hexagon&quot;</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    version = </span><span style="color: #CE9178">&quot;0.0.0&quot;</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">subprojects</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">apply</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;java-library&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.jetbrains.kotlin.jvm&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.jetbrains.kotlin.plugin.spring&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">plugin</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;io.spring.dependency-management&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> annotationProcessor </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> compileOnly </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> implementation </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> testImplementation </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> testRuntimeOnly </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">configurations</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        compileOnly.</span><span style="color: #DCDCAA">extendsFrom</span><span style="color: #D4D4D4">(annotationProcessor)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">dependencies</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.jetbrains.kotlin:kotlin-reflect&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testImplementation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot:spring-boot-starter-test&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testImplementation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.jetbrains.kotlin:kotlin-test-junit5&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testRuntimeOnly</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.junit.platform:junit-platform-launcher&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">configure</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">JavaPluginExtension</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">toolchain</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">            languageVersion = JavaLanguageVersion.</span><span style="color: #DCDCAA">of</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">21</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        }  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">configure</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">KotlinJvmProjectExtension</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">compilerOptions</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">            freeCompilerArgs.</span><span style="color: #DCDCAA">add</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;-Xjsr305=strict&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        }  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">configure</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">AllOpenExtension</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">annotation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;jakarta.persistence.Entity&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">annotation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;jakarta.persistence.MappedSuperclass&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">annotation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;jakarta.persistence.Embeddable&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">tasks</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">withType</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Test</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">useJUnitPlatform</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"><span style="color: #D4D4D4">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">withType</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">BootJar</span><span style="color: #D4D4D4">&gt; {  </span></span>
<span class="line"><span style="color: #D4D4D4">            enabled = </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">        }  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span></code></pre></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">Kapitel 2.3: <strong>application/build.gradle.kts</strong></h3>



<p class="wp-block-paragraph">Da die <strong>build.gradle.kts</strong> des Hauptordners bereits umfangreich konfiguriert wurde, kommen die einzelnen Module mit einer minimalen Konfiguration aus.</p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// application/build.gradle.kts

plugins {  
    id("application")  
    id("org.springframework.boot")  
    id("io.spring.dependency-management")  
}  

dependencies {  
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")  
    implementation("org.springframework.boot:spring-boot-starter-web")  
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")  
    developmentOnly("org.springframework.boot:spring-boot-devtools")  
    runtimeOnly("com.h2database:h2")  
    annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")  
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// application/build.gradle.kts</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">plugins</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">id</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;application&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">id</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">id</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;io.spring.dependency-management&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">dependencies</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot:spring-boot-starter-data-jpa&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot:spring-boot-starter-web&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;com.fasterxml.jackson.module:jackson-module-kotlin&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">developmentOnly</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot:spring-boot-devtools&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">runtimeOnly</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;com.h2database:h2&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">annotationProcessor</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;org.springframework.boot:spring-boot-configuration-processor&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Kapitel 3: Die Abhängigkeiten</h2>



<p class="wp-block-paragraph">Um das Verwalten von Abhängigkeiten noch leichter zu gestalten und das <strong>io.spring.dependency-management</strong>-Plugin abzulösen, kann ein Gradle Version Catalog verwendet werden. Dazu wird die Datei <strong>gradle/libs.versions.toml</strong> erstellt. Die Katalog-Datei gliedert sich in 4 relevante Segmente:</p>



<ul class="wp-block-list">
<li><strong>[versions]:</strong> Definiert die Versionen über einen eindeutigen Schlüssel. Versionen können über den Schlüssel von <strong>[libraries]</strong> und <strong>[plugins]</strong> referenziert werden.</li>



<li><strong>[libraries]:</strong> Bibliotheken mit einer eindeutigen Referenz. Dies wird zum Laden der BOMs verwendet, um nicht alle Bibliotheken selber verwalten zu müssen.</li>



<li><strong>[plugins]:</strong> Gradle-Plugins, welche über eine eindeutige Referenz in den Modulen verwendet werden können.</li>



<li><strong>[bundles]:</strong> Kollektion von <strong>[libraries]</strong>, ermöglicht es, gemeinsam auftretende Bibliotheken gebündelt zu definieren.</li>
</ul>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># gradle/libs.versions.toml
&#91;versions&#93;  
kotlin = "1.9.25"  
spring-boot = "3.5.7"  
&#91;libraries&#93;  
bom-spring-boot = { group = "org.springframework.boot", name = "spring-boot-dependencies", version.ref = "spring-boot" }  
h2 = { group = "com.h2database", name = "h2"}  
junit-platform = { group = "org.junit.platform", name = "junit-platform-launcher" }  
kotlin-jackson = { group = "com.fasterxml.jackson.module", name = "jackson-module-kotlin" }  
kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect" }  
kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit5" }  
spring-boot = { group = "org.springframework.boot", name = "spring-boot-starter" }  
spring-boot-configuration = { group = "org.springframework.boot", name = "spring-boot-configuration-processor" }  
spring-boot-devtools = { group = "org.springframework.boot", name = "spring-boot-devtools" }  
spring-boot-test = { group = "org.springframework.boot", name = "spring-boot-starter-test" }  
spring-boot-data-jpa = { group = "org.springframework.boot", name = "spring-boot-starter-data-jpa" }  
spring-boot-validation = { group = "org.springframework.boot", name = "spring-boot-starter-validation" }  
spring-boot-web = { group = "org.springframework.boot", name = "spring-boot-starter-web" }  

&#91;plugins&#93;  
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }  
kotlin-jpa = { id = "org.jetbrains.kotlin.plugin.jpa", version.ref = "kotlin" }  
kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" }  
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }  

&#91;bundles&#93;  
spring-boot-web = &#91;"spring-boot-validation", "spring-boot-web", "kotlin-jackson"&#93;  
spring-boot-test = &#91;"spring-boot-test", "kotlin-test"&#93;
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4"># gradle/libs.versions.toml</span></span>
<span class="line"><span style="color: #D4D4D4">&#91;versions&#93;  </span></span>
<span class="line"><span style="color: #D4D4D4">kotlin = </span><span style="color: #CE9178">&quot;1.9.25&quot;</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot = </span><span style="color: #CE9178">&quot;3.5.7&quot;</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">&#91;libraries&#93;  </span></span>
<span class="line"><span style="color: #D4D4D4">bom-spring-boot = { group = </span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;spring-boot-dependencies&quot;</span><span style="color: #D4D4D4">, version.ref = </span><span style="color: #CE9178">&quot;spring-boot&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">h2 = { group = </span><span style="color: #CE9178">&quot;com.h2database&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;h2&quot;</span><span style="color: #D4D4D4">}  </span></span>
<span class="line"><span style="color: #D4D4D4">junit-platform = { group = </span><span style="color: #CE9178">&quot;org.junit.platform&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;junit-platform-launcher&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">kotlin-jackson = { group = </span><span style="color: #CE9178">&quot;com.fasterxml.jackson.module&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;jackson-module-kotlin&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">kotlin-reflect = { group = </span><span style="color: #CE9178">&quot;org.jetbrains.kotlin&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;kotlin-reflect&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">kotlin-test = { group = </span><span style="color: #CE9178">&quot;org.jetbrains.kotlin&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;kotlin-test-junit5&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot = { group = </span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;spring-boot-starter&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot-configuration = { group = </span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;spring-boot-configuration-processor&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot-devtools = { group = </span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;spring-boot-devtools&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot-test = { group = </span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;spring-boot-starter-test&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot-</span><span style="color: #569CD6">data</span><span style="color: #D4D4D4">-jpa = { group = </span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;spring-boot-starter-data-jpa&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot-validation = { group = </span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;spring-boot-starter-validation&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot-web = { group = </span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">, name = </span><span style="color: #CE9178">&quot;spring-boot-starter-web&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">&#91;plugins&#93;  </span></span>
<span class="line"><span style="color: #D4D4D4">kotlin-jvm = { id = </span><span style="color: #CE9178">&quot;org.jetbrains.kotlin.jvm&quot;</span><span style="color: #D4D4D4">, version.ref = </span><span style="color: #CE9178">&quot;kotlin&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">kotlin-jpa = { id = </span><span style="color: #CE9178">&quot;org.jetbrains.kotlin.plugin.jpa&quot;</span><span style="color: #D4D4D4">, version.ref = </span><span style="color: #CE9178">&quot;kotlin&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">kotlin-spring = { id = </span><span style="color: #CE9178">&quot;org.jetbrains.kotlin.plugin.spring&quot;</span><span style="color: #D4D4D4">, version.ref = </span><span style="color: #CE9178">&quot;kotlin&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot = { id = </span><span style="color: #CE9178">&quot;org.springframework.boot&quot;</span><span style="color: #D4D4D4">, version.ref = </span><span style="color: #CE9178">&quot;spring-boot&quot;</span><span style="color: #D4D4D4"> }  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">&#91;bundles&#93;  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot-web = &#91;</span><span style="color: #CE9178">&quot;spring-boot-validation&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;spring-boot-web&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;kotlin-jackson&quot;</span><span style="color: #D4D4D4">&#93;  </span></span>
<span class="line"><span style="color: #D4D4D4">spring-boot-test = &#91;</span><span style="color: #CE9178">&quot;spring-boot-test&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;kotlin-test&quot;</span><span style="color: #D4D4D4">&#93;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Durch die Nutzung des Version Catalog fällt eine Anpassung der <strong>build.gradle.kts</strong> an. Zum einen wird die Version-Catalog-Referenz für <strong>plugins</strong> und <strong>dependencies</strong> genutzt, zum anderen wird das zuvor erwähnte <strong>io.spring.dependency-management</strong>-Plugin entfernt. Weiterhin müssen die BOMs in alle <strong>DependencyConfiguration</strong> geladen werden, damit Versionen, die von einer BOM verwaltet werden, auch referenziert werden können. Plugins werden über die <strong>alias()</strong>-Anweisung definiert, wobei zu beachten ist, dass diese in <strong>subprojects</strong> und <strong>allprojects</strong> so nicht zur Verfügung steht. BOMs müssen einzeln, nicht als <strong>[bundles]</strong>, über die <strong>platform()</strong>-Anweisung in jeder genutzten <strong>DependencyConfiguration</strong> hinterlegt werden.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// ...
plugins {  
    alias(libs.plugins.kotlin.jvm) apply false  
    alias(libs.plugins.kotlin.spring) apply false  
    alias(libs.plugins.kotlin.jpa) apply false  
    alias(libs.plugins.spring.boot) apply false  
}

// ...
subprojects {
    // ...
    val annotationProcessor by configurations  
    val compileOnly by configurations  
    val developmentOnly by configurations  
    val implementation by configurations  
    val testImplementation by configurations  
    val testRuntimeOnly by configurations  
    // ... 
    dependencies {  
        annotationProcessor(platform(rootProject.libs.bom.spring.boot))  
        compileOnly(platform(rootProject.libs.bom.spring.boot))  
        developmentOnly(platform(rootProject.libs.bom.spring.boot))  
        implementation(platform(rootProject.libs.bom.spring.boot))  
        testImplementation(platform(rootProject.libs.bom.spring.boot))  
        testRuntimeOnly(platform(rootProject.libs.bom.spring.boot))  
        implementation(rootProject.libs.kotlin.reflect)  
        testImplementation(rootProject.libs.bundles.spring.boot.test)  
        testRuntimeOnly(rootProject.libs.junit.platform)  
    }
    // ...
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #DCDCAA">plugins</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">alias</span><span style="color: #D4D4D4">(libs.plugins.kotlin.jvm) apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">alias</span><span style="color: #D4D4D4">(libs.plugins.kotlin.spring) apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">alias</span><span style="color: #D4D4D4">(libs.plugins.kotlin.jpa) apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">alias</span><span style="color: #D4D4D4">(libs.plugins.spring.boot) apply </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #DCDCAA">subprojects</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> annotationProcessor </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> compileOnly </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> developmentOnly </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> implementation </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> testImplementation </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> testRuntimeOnly </span><span style="color: #569CD6">by</span><span style="color: #D4D4D4"> configurations  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// ... </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">dependencies</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">annotationProcessor</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">platform</span><span style="color: #D4D4D4">(rootProject.libs.bom.spring.boot))  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">compileOnly</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">platform</span><span style="color: #D4D4D4">(rootProject.libs.bom.spring.boot))  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">developmentOnly</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">platform</span><span style="color: #D4D4D4">(rootProject.libs.bom.spring.boot))  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">platform</span><span style="color: #D4D4D4">(rootProject.libs.bom.spring.boot))  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testImplementation</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">platform</span><span style="color: #D4D4D4">(rootProject.libs.bom.spring.boot))  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testRuntimeOnly</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">platform</span><span style="color: #D4D4D4">(rootProject.libs.bom.spring.boot))  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(rootProject.libs.kotlin.reflect)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testImplementation</span><span style="color: #D4D4D4">(rootProject.libs.bundles.spring.boot.test)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">testRuntimeOnly</span><span style="color: #D4D4D4">(rootProject.libs.junit.platform)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// ...</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Die Leichtigkeit des Gradle Version Catalogs fällt erst richtig bei den einzelnen Modulen auf. Die <strong>build.gradle.kts</strong> des <strong>application</strong>-Moduls wird mit den neuen Änderungen noch schlanker.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// application/build.gradle.kts

plugins {  
    id("application")  
    alias(libs.plugins.spring.boot)  
    alias(libs.plugins.kotlin.jpa)  
}  

dependencies {  
    implementation(libs.spring.boot.data.jpa)  
    implementation(libs.bundles.spring.boot.web)  
    developmentOnly(libs.spring.boot.devtools)  
    runtimeOnly(libs.h2)  
    annotationProcessor(libs.spring.boot.configuration)  
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// application/build.gradle.kts</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">plugins</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">id</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;application&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">alias</span><span style="color: #D4D4D4">(libs.plugins.spring.boot)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">alias</span><span style="color: #D4D4D4">(libs.plugins.kotlin.jpa)  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">dependencies</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(libs.spring.boot.</span><span style="color: #569CD6">data</span><span style="color: #D4D4D4">.jpa)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(libs.bundles.spring.boot.web)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">developmentOnly</span><span style="color: #D4D4D4">(libs.spring.boot.devtools)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">runtimeOnly</span><span style="color: #D4D4D4">(libs.h2)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">annotationProcessor</span><span style="color: #D4D4D4">(libs.spring.boot.configuration)  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span></code></pre></div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Kapitel 4: Die Domain</h2>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e56eb5&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e56eb5" class="aligncenter size-large wp-lightbox-container"><img decoding="async" width="1024" height="335" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/image-11-e1772729141255-1024x335.png" alt="" class="wp-image-9095" srcset="https://atra.consulting/wp-content/uploads/2026/03/image-11-e1772729141255-1024x335.png 1024w, https://atra.consulting/wp-content/uploads/2026/03/image-11-e1772729141255-768x251.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>classDiagram
    class Product {
        &lt;&lt;data class>>
        +Long? id
        +String name
        +Double price
        +applyDiscount(Double discount)
    }

    class FindAllProductsUseCase {
        &lt;&lt;interface>>
        +findAllProducts() List~Product~
    }

    class FindProductByIdUseCase {
        &lt;&lt;interface>>
        +findProductById(Long id) Product?
    }

    class CreateProductUseCase {
        &lt;&lt;interface>>
        +createProduct(Product product) Product
    }
 
   class ApplyDiscountToProductUseCase {
        &lt;&lt;interface>>
        +applyDiscountToProduct(Long id, Double discount) Product
    }

    class SaveProductUseCase {
        &lt;&lt;interface>>
        +saveProduct(Product product) Product
    }

    class ProductsEndpointPort {
        &lt;&lt;interface>>
    }

    class ProductsPersistencePort {
        &lt;&lt;interface>>
    }

    ProductsEndpointPort --|> FindAllProductsUseCase
    ProductsEndpointPort --|> FindProductByIdUseCase
    ProductsEndpointPort --|> CreateProductUseCase
    ProductsEndpointPort --|> ApplyDiscountToProductUseCase
    ProductsPersistencePort --|> FindAllProductsUseCase
    ProductsPersistencePort --|> FindProductByIdUseCase
    ProductsPersistencePort --|> SaveProductUseCase
    FindAllProductsUseCase ..> Product : uses
    FindProductByIdUseCase ..> Product : uses
    CreateProductUseCase ..> Product : uses
    ApplyDiscountToProductUseCase ..> Product : uses
    SaveProductUseCase ..> Product : uses
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">classDiagram</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;</span><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> class&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +Long? id</span></span>
<span class="line"><span style="color: #D4D4D4">        +String name</span></span>
<span class="line"><span style="color: #D4D4D4">        +Double price</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">applyDiscount</span><span style="color: #D4D4D4">(Double discount)</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">FindAllProductsUseCase</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">findAllProducts</span><span style="color: #D4D4D4">() List~Product~</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">FindProductByIdUseCase</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">findProductById</span><span style="color: #D4D4D4">(Long id) Product?</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">CreateProductUseCase</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">createProduct</span><span style="color: #D4D4D4">(Product product) Product</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ApplyDiscountToProductUseCase</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">applyDiscountToProduct</span><span style="color: #D4D4D4">(Long id, Double discount) Product</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SaveProductUseCase</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">saveProduct</span><span style="color: #D4D4D4">(Product product) Product</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsEndpointPort</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsPersistencePort</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointPort --|&gt; FindAllProductsUseCase</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointPort --|&gt; FindProductByIdUseCase</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointPort --|&gt; CreateProductUseCase</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointPort --|&gt; ApplyDiscountToProductUseCase</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsPersistencePort --|&gt; FindAllProductsUseCase</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsPersistencePort --|&gt; FindProductByIdUseCase</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsPersistencePort --|&gt; SaveProductUseCase</span></span>
<span class="line"><span style="color: #D4D4D4">    FindAllProductsUseCase ..&gt; Product : </span><span style="color: #4EC9B0">uses</span></span>
<span class="line"><span style="color: #D4D4D4">    FindProductByIdUseCase ..&gt; Product : </span><span style="color: #4EC9B0">uses</span></span>
<span class="line"><span style="color: #D4D4D4">    CreateProductUseCase ..&gt; Product : </span><span style="color: #4EC9B0">uses</span></span>
<span class="line"><span style="color: #D4D4D4">    ApplyDiscountToProductUseCase ..&gt; Product : </span><span style="color: #4EC9B0">uses</span></span>
<span class="line"><span style="color: #D4D4D4">    SaveProductUseCase ..&gt; Product : </span><span style="color: #4EC9B0">uses</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Das <strong>domain</strong>-Modul bildet den Kern der hexagonalen Architektur. Hier residiert die reine Geschäftslogik, vollständig entkoppelt von technischen Frameworks oder Infrastruktur-Details. Gradle-seitig ist für dieses Modul keine weitere Konfiguration notwendig, da es lediglich auf der Standard-Kotlin-Konfiguration aus dem Root-Projekt aufbaut. Es wird bewusst darauf verzichtet, Abhängigkeiten zu Frameworks wie Spring Boot hinzuzufügen.</p>



<p class="wp-block-paragraph">Das zentrale Domänenmodell wird durch die Klasse <strong>Product</strong> repräsentiert. Im Gegensatz zur vorherigen Implementierung ist dies nun eine reine Kotlin-Klasse ohne JPA-Annotationen, angereichert mit fachlicher Logik wie der Preiskalkulation.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// domain/src/main/kotlin/consulting/atra/hexagon/domain/Product.kt

package consulting.atra.hexagon.domain  

data class Product(  
    val id: Long? = null,  
    var name: String,  
    var price: Double,  
) {  
    fun applyDiscount(discount: Double) {  
        price *= (1 - discount / 100)  
    }  
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// domain/src/main/kotlin/consulting/atra/hexagon/domain/Product.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">? = </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> name: </span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> price: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">) {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">applyDiscount</span><span style="color: #D4D4D4">(discount: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">) {  </span></span>
<span class="line"><span style="color: #D4D4D4">        price *= (</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> - discount / </span><span style="color: #B5CEA8">100</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Die Interaktion mit der Domäne wird über Use Cases definiert. Diese Interfaces beschreiben, was mit der Domäne getan werden kann, ohne vorzuschreiben, wie dies technisch umgesetzt wird.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>/ domain/src/main/kotlin/consulting/atra/hexagon/domain/ProductUseCases.kt

package consulting.atra.hexagon.domain  

interface FindAllProductsUseCase {  
    fun findAllProducts(): List&lt;Product>  
}  

interface FindProductByIdUseCase {  
    fun findProductById(id: Long): Product?  
}  

interface CreateProductUseCase {  
    fun createProduct(product: Product): Product  
}  

interface ApplyDiscountToProductUseCase {  
    fun applyDiscountToProduct(id: Long, discount: Double): Product  
}  

interface SaveProductUseCase {  
    fun saveProduct(product: Product): Product  
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">/ domain/src/main/kotlin/consulting/atra/hexagon/domain/ProductUseCases.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">FindAllProductsUseCase</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">findAllProducts</span><span style="color: #D4D4D4">(): </span><span style="color: #4EC9B0">List</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">&gt;  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">FindProductByIdUseCase</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">findProductById</span><span style="color: #D4D4D4">(id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">?  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">CreateProductUseCase</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">createProduct</span><span style="color: #D4D4D4">(product: </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ApplyDiscountToProductUseCase</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">applyDiscountToProduct</span><span style="color: #D4D4D4">(id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">, discount: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SaveProductUseCase</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">saveProduct</span><span style="color: #D4D4D4">(product: </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Um die Kommunikation nach außen zu ermöglichen, werden Ports definiert. Der <strong>ProductsEndpointPort</strong> fungiert als &#8222;Driving Port&#8220; (Eingang), der von der Außenwelt (z.B. REST API) aufgerufen wird. Der <strong>ProductsPersistencePort</strong> dient als &#8222;Driven Port&#8220; (Ausgang), über den die Domäne Daten speichert oder lädt, ohne die konkrete Datenbanktechnologie zu kennen.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// domain/src/main/kotlin/consulting/atra/hexagon/domain/ProductPorts.kt

package consulting.atra.hexagon.domain  

interface ProductsEndpointPort :  
    FindAllProductsUseCase,  
    FindProductByIdUseCase,  
    CreateProductUseCase,  
    ApplyDiscountToProductUseCase  

interface ProductsPersistencePort :  
    FindAllProductsUseCase,  
    FindProductByIdUseCase,  
    SaveProductUseCase</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// domain/src/main/kotlin/consulting/atra/hexagon/domain/ProductPorts.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsEndpointPort</span><span style="color: #D4D4D4"> :  </span></span>
<span class="line"><span style="color: #D4D4D4">    FindAllProductsUseCase,  </span></span>
<span class="line"><span style="color: #D4D4D4">    FindProductByIdUseCase,  </span></span>
<span class="line"><span style="color: #D4D4D4">    CreateProductUseCase,  </span></span>
<span class="line"><span style="color: #D4D4D4">    ApplyDiscountToProductUseCase  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsPersistencePort</span><span style="color: #D4D4D4"> :  </span></span>
<span class="line"><span style="color: #D4D4D4">    FindAllProductsUseCase,  </span></span>
<span class="line"><span style="color: #D4D4D4">    FindProductByIdUseCase,  </span></span>
<span class="line"><span style="color: #D4D4D4">    SaveProductUseCase</span></span></code></pre></div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Kapitel 5: Der Eingangs-Adapter</h2>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e57e7e&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e57e7e" class="aligncenter size-large wp-lightbox-container"><img decoding="async" width="1600" height="900" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/image-13-edited.png" alt="" class="wp-image-9100" srcset="https://atra.consulting/wp-content/uploads/2026/03/image-13-edited.png 1600w, https://atra.consulting/wp-content/uploads/2026/03/image-13-edited-1024x576.png 1024w, https://atra.consulting/wp-content/uploads/2026/03/image-13-edited-768x432.png 768w, https://atra.consulting/wp-content/uploads/2026/03/image-13-edited-1536x864.png 1536w, https://atra.consulting/wp-content/uploads/2026/03/image-13-edited-780x440.png 780w" sizes="(max-width: 1600px) 100vw, 1600px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>classDiagram
    class ProductsEndpoint {
        &lt;&lt;interface>>
        +list() List~ProductResponse~
        +create(ProductRequest product) ProductResponse
        +get(Long id) ProductResponse?
        +update(Long id, Double discount) ProductResponse?
    }

    class ProductsEndpointAdapter {
        &lt;&lt;RestController>>
        -ProductsEndpointPort port
        +list() List~ProductResponse~
        +create(ProductRequest product) ProductResponse
        +get(Long id) ProductResponse?
        +update(Long id, Double discount) ProductResponse?
    }

    class ProductsEndpointPort {
        &lt;&lt;interface / from domain>>
    }

    class ProductRequest {
        &lt;&lt;data class>>
        +String name
        +Double price
    }

    class ProductResponse {
        &lt;&lt;data class>>
        +Long id
        +String name
        +Double price
    }

    class Product {
        &lt;&lt;data class / from domain>>
    }

    ProductsEndpointAdapter ..|> ProductsEndpoint : implements
    ProductsEndpointAdapter --> ProductsEndpointPort : uses port
    ProductsEndpointAdapter ..> ProductRequest : receives
    ProductsEndpointAdapter ..> ProductResponse : returns
    ProductsEndpointAdapter ..> Product : maps to/from</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">classDiagram</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsEndpoint</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">list</span><span style="color: #D4D4D4">() List~ProductResponse~</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">create</span><span style="color: #D4D4D4">(ProductRequest product) ProductResponse</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #569CD6">get</span><span style="color: #D4D4D4">(Long id) ProductResponse?</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">update</span><span style="color: #D4D4D4">(Long id, Double discount) ProductResponse?</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsEndpointAdapter</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;RestController&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        -ProductsEndpointPort port</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">list</span><span style="color: #D4D4D4">() List~ProductResponse~</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">create</span><span style="color: #D4D4D4">(ProductRequest product) ProductResponse</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #569CD6">get</span><span style="color: #D4D4D4">(Long id) ProductResponse?</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">update</span><span style="color: #D4D4D4">(Long id, Double discount) ProductResponse?</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsEndpointPort</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface / from domain&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductRequest</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;</span><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> class&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +String name</span></span>
<span class="line"><span style="color: #D4D4D4">        +Double price</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;</span><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> class&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +Long id</span></span>
<span class="line"><span style="color: #D4D4D4">        +String name</span></span>
<span class="line"><span style="color: #D4D4D4">        +Double price</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;</span><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> class / from domain&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointAdapter ..|&gt; ProductsEndpoint : </span><span style="color: #4EC9B0">implements</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointAdapter -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> ProductsEndpointPort : </span><span style="color: #4EC9B0">uses</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">port</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointAdapter ..&gt; ProductRequest : </span><span style="color: #4EC9B0">receives</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointAdapter ..&gt; ProductResponse : </span><span style="color: #4EC9B0">returns</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointAdapter ..&gt; Product : </span><span style="color: #4EC9B0">maps</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">to</span><span style="color: #D4D4D4">/from</span></span></code></pre></div>



<p class="wp-block-paragraph">Der Eingangs-Adapter (Driving Adapter) ist verantwortlich für die Kommunikation von außen in die Anwendung hinein. In diesem Fall handelt es sich um einen REST-Controller. Das Modul <strong>adapters:endpoint</strong> erhält Zugriff auf das <strong>domain</strong>-Modul sowie auf die benötigten Web-Bibliotheken.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/endpoint/build.gradle.kts

dependencies {  
    implementation(project(":domain"))  
    implementation(libs.bundles.spring.boot.web)  
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/endpoint/build.gradle.kts</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">dependencies</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">project</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;:domain&quot;</span><span style="color: #D4D4D4">))  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(libs.bundles.spring.boot.web)  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Um die API-Schicht sauber von der Domäne zu trennen, werden separate Data Transfer Objects (DTOs) für Requests und Responses definiert. Dies verhindert, dass Änderungen an der internen Domänenstruktur ungewollt die externe API beeinflussen.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductRequest.kt

package consulting.atra.hexagon.adapters.endpoint  

data class ProductRequest(  
    var name: String, 
    var price: Double,  
)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductRequest.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.adapters.endpoint  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductRequest</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> name: </span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">, </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> price: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">)</span></span></code></pre></div>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductResponse.kt

package consulting.atra.hexagon.adapters.endpoint  

data class ProductResponse(  
    var id: Long,  
    var name: String,  
    var price: Double,  
)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductResponse.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.adapters.endpoint  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> name: </span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> price: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">)</span></span></code></pre></div>



<p class="wp-block-paragraph">Die Konvertierung zwischen DTOs und Domänen-Objekten erfolgt durch explizite Mapping-Funktionen.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductMapping.kt

package consulting.atra.hexagon.adapters.endpoint  

import consulting.atra.hexagon.domain.Product  

fun Product.toResponse() =  
    ProductResponse(  
        id = id!!,  
        name = name,  
        price = price,  
    )  

fun ProductRequest.toDomain() =  
    Product(  
        name = name,  
        price = price,  
    )  

fun List&lt;Product>.toResponses() =  
    map { it.toResponse() }</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductMapping.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.adapters.endpoint  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain.Product  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">toResponse</span><span style="color: #D4D4D4">() =  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">ProductResponse</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">        id = id!!,  </span></span>
<span class="line"><span style="color: #D4D4D4">        name = name,  </span></span>
<span class="line"><span style="color: #D4D4D4">        price = price,  </span></span>
<span class="line"><span style="color: #D4D4D4">    )  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductRequest</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">toDomain</span><span style="color: #D4D4D4">() =  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">Product</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">        name = name,  </span></span>
<span class="line"><span style="color: #D4D4D4">        price = price,  </span></span>
<span class="line"><span style="color: #D4D4D4">    )  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">List</span><span style="color: #D4D4D4">&lt;Product&gt;.</span><span style="color: #DCDCAA">toResponses</span><span style="color: #D4D4D4">() =  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">map</span><span style="color: #D4D4D4"> { it.</span><span style="color: #DCDCAA">toResponse</span><span style="color: #D4D4D4">() }</span></span></code></pre></div>



<p class="wp-block-paragraph">Die Schnittstelle des REST-Controllers wird zunächst als Interface definiert, um die technische Definition der Endpunkte von der Implementierung zu trennen.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductsEndpoint.kt

package consulting.atra.hexagon.adapters.endpoint  

import org.springframework.web.bind.annotation.GetMapping  
import org.springframework.web.bind.annotation.PatchMapping  
import org.springframework.web.bind.annotation.PathVariable  
import org.springframework.web.bind.annotation.PostMapping  
import org.springframework.web.bind.annotation.RequestBody  
import org.springframework.web.bind.annotation.RequestMapping  
import org.springframework.web.bind.annotation.RequestParam  

@RequestMapping("/api/v1/products")  
interface ProductsEndpoint {  

    @GetMapping  
    fun list(): List&lt;ProductResponse>  

    @PostMapping  
    fun create(@RequestBody product: ProductRequest): ProductResponse  

    @GetMapping("/{id}")  
    fun get(@PathVariable id: Long): ProductResponse?  

    @PatchMapping("/{id}")  
    fun update(@PathVariable id: Long, @RequestParam discount: Double): ProductResponse?  

}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductsEndpoint.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.adapters.endpoint  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.GetMapping  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.PatchMapping  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.PathVariable  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.PostMapping  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.RequestBody  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.RequestMapping  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.RequestParam  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #4EC9B0">@RequestMapping</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;/api/v1/products&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsEndpoint</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@GetMapping</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">list</span><span style="color: #D4D4D4">(): </span><span style="color: #4EC9B0">List</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4">&gt;  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@PostMapping</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">create</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">@RequestBody</span><span style="color: #D4D4D4"> product: </span><span style="color: #4EC9B0">ProductRequest</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4">  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@GetMapping</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;/{id}&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">get</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">@PathVariable</span><span style="color: #D4D4D4"> id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4">?  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@PatchMapping</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;/{id}&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">update</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">@PathVariable</span><span style="color: #D4D4D4"> id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">, </span><span style="color: #4EC9B0">@RequestParam</span><span style="color: #D4D4D4"> discount: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4">?  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Die eigentliche Implementierung des Adapters, <strong>ProductsEndpointAdapter</strong>, nutzt den <strong>ProductsEndpointPort</strong> der Domäne, um die Geschäftslogik auszuführen. Eingehende Requests werden in Domänenobjekte umgewandelt, an den Port übergeben und das Ergebnis wieder als Response-DTO zurückgegeben.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductsEndpointAdapter.kt

package consulting.atra.hexagon.adapters.endpoint  

import consulting.atra.hexagon.domain.ProductEndpointPort  
import org.springframework.web.bind.annotation.RestController  

@RestController  
class ProductsEndpointAdapter (  
    private val port: ProductsEndpointPort,  
) : ProductsEndpoint {  

    override fun list(): List&lt;ProductResponse> =  
        port.findAllProducts().toResponses()  

    override fun create(product: ProductRequest): ProductResponse =  
        port.createProduct(product.toDomain()).toResponse()  

    override fun get(id: Long): ProductResponse? =  
        port.findProductById(id)?.toResponse()  

    override fun update(  
        id: Long,  
        discount: Double  
    ): ProductResponse? =  
        port.applyDiscountToProduct(id, discount)?.toResponse()  
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/endpoint/src/main/kotlin/consulting/atra/hexagon/adapters/endpoint/ProductsEndpointAdapter.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.adapters.endpoint  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain.ProductEndpointPort  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.web.bind.annotation.RestController  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #4EC9B0">@RestController</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsEndpointAdapter</span><span style="color: #D4D4D4"> (  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> port: </span><span style="color: #4EC9B0">ProductsEndpointPort</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">) : </span><span style="color: #4EC9B0">ProductsEndpoint</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">list</span><span style="color: #D4D4D4">(): </span><span style="color: #4EC9B0">List</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4">&gt; =  </span></span>
<span class="line"><span style="color: #D4D4D4">        port.</span><span style="color: #DCDCAA">findAllProducts</span><span style="color: #D4D4D4">().</span><span style="color: #DCDCAA">toResponses</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">create</span><span style="color: #D4D4D4">(product: </span><span style="color: #4EC9B0">ProductRequest</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4"> =  </span></span>
<span class="line"><span style="color: #D4D4D4">        port.</span><span style="color: #DCDCAA">createProduct</span><span style="color: #D4D4D4">(product.</span><span style="color: #DCDCAA">toDomain</span><span style="color: #D4D4D4">()).</span><span style="color: #DCDCAA">toResponse</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">get</span><span style="color: #D4D4D4">(id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4">? =  </span></span>
<span class="line"><span style="color: #D4D4D4">        port.</span><span style="color: #DCDCAA">findProductById</span><span style="color: #D4D4D4">(id)?.</span><span style="color: #DCDCAA">toResponse</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">update</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">        id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">        discount: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    ): </span><span style="color: #4EC9B0">ProductResponse</span><span style="color: #D4D4D4">? =  </span></span>
<span class="line"><span style="color: #D4D4D4">        port.</span><span style="color: #DCDCAA">applyDiscountToProduct</span><span style="color: #D4D4D4">(id, discount)?.</span><span style="color: #DCDCAA">toResponse</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Kapitel 6: Der Ausgangs-Adapter</h2>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e590a5&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e590a5" class="aligncenter size-large wp-lightbox-container"><img decoding="async" width="1024" height="861" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/image-10-1024x861.png" alt="" class="wp-image-9094" srcset="https://atra.consulting/wp-content/uploads/2026/03/image-10-1024x861.png 1024w, https://atra.consulting/wp-content/uploads/2026/03/image-10-768x646.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>classDiagram
    class ProductEntity {
        &lt;&lt;Entity / data class>>
        +Long? id
        +String name
        +Double price
    }

    class ProductsRepository {
        &lt;&lt;interface>>
    }

    class ProductsPersistenceAdapter {
        &lt;&lt;Service>>
        -ProductsRepository repository
        +findAllProducts() List~Product~
        +findProductById(Long id) Product?
        +saveProduct(Product product) Product
    }

    class ProductsPersistencePort {
        &lt;&lt;interface / from domain>>
    }

    class Product {
        &lt;&lt;data class / from domain>>
    }

    ProductsPersistenceAdapter ..|> ProductsPersistencePort : implements
    ProductsPersistenceAdapter --> ProductsRepository : repository
    ProductsRepository ..> ProductEntity : manages
    ProductsPersistenceAdapter ..> ProductEntity : maps to/from
    ProductsPersistenceAdapter ..> Product : maps to/from</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">classDiagram</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductEntity</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;Entity / </span><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> class&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +Long? id</span></span>
<span class="line"><span style="color: #D4D4D4">        +String name</span></span>
<span class="line"><span style="color: #D4D4D4">        +Double price</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsRepository</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsPersistenceAdapter</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;Service&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        -ProductsRepository repository</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">findAllProducts</span><span style="color: #D4D4D4">() List~Product~</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">findProductById</span><span style="color: #D4D4D4">(Long id) Product?</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">saveProduct</span><span style="color: #D4D4D4">(Product product) Product</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsPersistencePort</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface / from domain&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;</span><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> class / from domain&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    ProductsPersistenceAdapter ..|&gt; ProductsPersistencePort : </span><span style="color: #4EC9B0">implements</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsPersistenceAdapter -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> ProductsRepository : </span><span style="color: #4EC9B0">repository</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsRepository ..&gt; ProductEntity : </span><span style="color: #4EC9B0">manages</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsPersistenceAdapter ..&gt; ProductEntity : </span><span style="color: #4EC9B0">maps</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">to</span><span style="color: #D4D4D4">/from</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsPersistenceAdapter ..&gt; Product : </span><span style="color: #4EC9B0">maps</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">to</span><span style="color: #D4D4D4">/from</span></span></code></pre></div>



<p class="wp-block-paragraph">Auf der anderen Seite des Hexagons befindet sich der Ausgangs-Adapter (Driven Adapter), der für die Persistenz zuständig ist. Das Modul <strong>adapters:persistence</strong> implementiert die technischen Details der Datenspeicherung mittels JPA und H2.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/persistence/build.gradle.kts

plugins {  
    alias(libs.plugins.kotlin.jpa)  
}  

dependencies {  
    implementation(project(":domain"))  
    implementation(libs.spring.boot.data.jpa)  
    runtimeOnly(libs.h2)  
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/persistence/build.gradle.kts</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">plugins</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">alias</span><span style="color: #D4D4D4">(libs.plugins.kotlin.jpa)  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">dependencies</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">project</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;:domain&quot;</span><span style="color: #D4D4D4">))  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(libs.spring.boot.</span><span style="color: #569CD6">data</span><span style="color: #D4D4D4">.jpa)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">runtimeOnly</span><span style="color: #D4D4D4">(libs.h2)  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Auch hier wird eine strikte Trennung vorgenommen: Die <strong>ProductEntity</strong> ist eine JPA-spezifische Klasse, die mit Datenbank-Annotationen versehen ist. Sie ist von der Domänenklasse <strong>Product</strong> getrennt, um das Domänenmodell nicht mit Persistenzdetails zu verunreinigen.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/persistence/src/main/kotlin/consulting/atra/hexagon/adapters/persistence/ProductEntity.kt

package consulting.atra.hexagon.adapters.persistence  

import jakarta.persistence.Entity  
import jakarta.persistence.GeneratedValue  
import jakarta.persistence.Id  

@Entity  
data class ProductEntity(  
    @Id  
    @GeneratedValue
    var id: Long? = null,  

    var name: String,  

    var price: Double,  
)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/persistence/src/main/kotlin/consulting/atra/hexagon/adapters/persistence/ProductEntity.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.adapters.persistence  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> jakarta.persistence.Entity  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> jakarta.persistence.GeneratedValue  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> jakarta.persistence.Id  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #4EC9B0">@Entity</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductEntity</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@Id</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">@GeneratedValue</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">? = </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> name: </span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> price: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">)</span></span></code></pre></div>



<p class="wp-block-paragraph">Das <strong>ProductsRepository</strong> bleibt ein klassisches Spring Data JPA Repository.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/persistence/src/main/kotlin/consulting/atra/hexagon/adapters/persistence/ProductsRepository.kt

package consulting.atra.hexagon.adapters.persistence  

import org.springframework.data.jpa.repository.JpaRepository  
interface ProductsRepository : JpaRepository&lt;ProductEntity, Long></textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/persistence/src/main/kotlin/consulting/atra/hexagon/adapters/persistence/ProductsRepository.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.adapters.persistence  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.data.jpa.repository.JpaRepository  </span></span>
<span class="line"><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsRepository</span><span style="color: #D4D4D4"> : </span><span style="color: #4EC9B0">JpaRepository</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">ProductEntity</span><span style="color: #D4D4D4">, </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">&gt;</span></span></code></pre></div>



<p class="wp-block-paragraph">Der <strong>ProductsPersistenceAdapter</strong> implementiert schließlich den <strong>ProductsPersistencePort</strong> der Domäne. Er übersetzt die Aufrufe der Domäne in Datenbankoperationen und konvertiert zwischen <strong>Product</strong> (Domäne) und <strong>ProductEntity</strong> (Datenbank). Damit bleibt die Domäne vollständig unabhängig von der verwendeten Datenbanktechnologie.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// adapters/persistence/src/main/kotlin/consulting/atra/hexagon/adapters/persistence/ProductsPersistenceAdapter.kt

package consulting.atra.hexagon.adapters.persistence  

import consulting.atra.hexagon.domain.Product  
import consulting.atra.hexagon.domain.ProductsPersistencePort  
import org.springframework.data.repository.findByIdOrNull  
import org.springframework.stereotype.Service  

@Service  
class ProductsPersistenceAdapter(  
    private val repository: ProductsRepository,  
) : ProductsPersistencePort {  
    override fun findAllProducts(): List&lt;Product> =  
        repository.findAll().toDomains()  

    override fun findProductById(id: Long): Product? =  
        repository.findByIdOrNull(id)?.let { return it.toDomain() }  

    override fun saveProduct(product: Product): Product =  
        repository.save(product.toEntity()).toDomain()  
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// adapters/persistence/src/main/kotlin/consulting/atra/hexagon/adapters/persistence/ProductsPersistenceAdapter.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon.adapters.persistence  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain.Product  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain.ProductsPersistencePort  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.data.repository.findByIdOrNull  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.stereotype.Service  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #4EC9B0">@Service</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsPersistenceAdapter</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> repository: </span><span style="color: #4EC9B0">ProductsRepository</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">) : </span><span style="color: #4EC9B0">ProductsPersistencePort</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">findAllProducts</span><span style="color: #D4D4D4">(): </span><span style="color: #4EC9B0">List</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">&gt; =  </span></span>
<span class="line"><span style="color: #D4D4D4">        repository.</span><span style="color: #DCDCAA">findAll</span><span style="color: #D4D4D4">().</span><span style="color: #DCDCAA">toDomains</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">findProductById</span><span style="color: #D4D4D4">(id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">? =  </span></span>
<span class="line"><span style="color: #D4D4D4">        repository.</span><span style="color: #DCDCAA">findByIdOrNull</span><span style="color: #D4D4D4">(id)?.</span><span style="color: #DCDCAA">let</span><span style="color: #D4D4D4"> { </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> it.</span><span style="color: #DCDCAA">toDomain</span><span style="color: #D4D4D4">() }  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">saveProduct</span><span style="color: #D4D4D4">(product: </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4"> =  </span></span>
<span class="line"><span style="color: #D4D4D4">        repository.</span><span style="color: #DCDCAA">save</span><span style="color: #D4D4D4">(product.</span><span style="color: #DCDCAA">toEntity</span><span style="color: #D4D4D4">()).</span><span style="color: #DCDCAA">toDomain</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Kapitel 7: Die Application</h2>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e59fbd&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e59fbd" class="aligncenter size-large wp-lightbox-container"><img decoding="async" width="1600" height="900" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/image-14-edited.png" alt="" class="wp-image-9099" srcset="https://atra.consulting/wp-content/uploads/2026/03/image-14-edited.png 1600w, https://atra.consulting/wp-content/uploads/2026/03/image-14-edited-1024x576.png 1024w, https://atra.consulting/wp-content/uploads/2026/03/image-14-edited-768x432.png 768w, https://atra.consulting/wp-content/uploads/2026/03/image-14-edited-1536x864.png 1536w, https://atra.consulting/wp-content/uploads/2026/03/image-14-edited-780x440.png 780w" sizes="(max-width: 1600px) 100vw, 1600px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>classDiagram
    class Application {
        &lt;&lt;SpringBootApplication>>
        -ProductsPersistencePort persistencePort
        +findAllProducts() List~Product~
        +findProductById(Long id) Product?
        +createProduct(Product product) Product
        +applyDiscountToProduct(Long id, Double discount) Product?
        +main(String[] args)$
    }

    class ProductsEndpointPort {
        &lt;&lt;interface / from domain>>
    }

    class ProductsPersistencePort {
        &lt;&lt;interface / from domain>>
    }

    class Product {
        &lt;&lt;data class / from domain>>
        +applyDiscount(Double discount)
    }

    class ProductsEndpointAdapter {
        &lt;&lt;RestController / from adapters:endpoint>>
        -ProductsEndpointPort port
    }

    class ProductsPersistenceAdapter {
        &lt;&lt;Service / from adapters:persistence>>
    }

    Application ..|> ProductsEndpointPort : implements (Driving Port)
    Application --> ProductsPersistencePort : uses (Driven Port)
    Application ..> Product : orchestrates domain logic
    ProductsEndpointAdapter --> ProductsEndpointPort : injects (Application)
    ProductsPersistenceAdapter ..|> ProductsPersistencePort : implements</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">classDiagram</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Application</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;SpringBootApplication&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        -ProductsPersistencePort persistencePort</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">findAllProducts</span><span style="color: #D4D4D4">() List~Product~</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">findProductById</span><span style="color: #D4D4D4">(Long id) Product?</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">createProduct</span><span style="color: #D4D4D4">(Product product) Product</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">applyDiscountToProduct</span><span style="color: #D4D4D4">(Long id, Double discount) Product?</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">main</span><span style="color: #D4D4D4">(String[] args)$</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsEndpointPort</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface / from domain&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsPersistencePort</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;interface / from domain&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;</span><span style="color: #569CD6">data</span><span style="color: #D4D4D4"> class / from domain&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        +</span><span style="color: #DCDCAA">applyDiscount</span><span style="color: #D4D4D4">(Double discount)</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsEndpointAdapter</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;RestController / from adapters:</span><span style="color: #4EC9B0">endpoint</span><span style="color: #D4D4D4">&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        -ProductsEndpointPort port</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ProductsPersistenceAdapter</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        &lt;&lt;Service / from adapters:</span><span style="color: #4EC9B0">persistence</span><span style="color: #D4D4D4">&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    Application ..|&gt; ProductsEndpointPort : </span><span style="color: #4EC9B0">implements</span><span style="color: #D4D4D4"> (</span><span style="color: #4EC9B0">Driving</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Port</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">    Application -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> ProductsPersistencePort : </span><span style="color: #4EC9B0">uses</span><span style="color: #D4D4D4"> (</span><span style="color: #4EC9B0">Driven</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Port</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">    Application ..&gt; Product : </span><span style="color: #4EC9B0">orchestrates</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">domain</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">logic</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsEndpointAdapter -</span><span style="color: #569CD6">-&gt;</span><span style="color: #D4D4D4"> ProductsEndpointPort : </span><span style="color: #4EC9B0">injects</span><span style="color: #D4D4D4"> (</span><span style="color: #4EC9B0">Application</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">    ProductsPersistenceAdapter ..|&gt; ProductsPersistencePort : </span><span style="color: #4EC9B0">implements</span></span></code></pre></div>



<p class="wp-block-paragraph"><br>Das <strong>application</strong>-Modul fungiert als Klebstoff, der alle Komponenten zusammenhält. Hier werden die Abhängigkeiten zu allen anderen Modulen definiert, damit Spring Boot den Application Context vollständig aufbauen kann.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// application/build.gradle.kts

plugins {  
    id("application")  
    alias(libs.plugins.spring.boot)  
}  

dependencies {  
    implementation(project(":domain"))  
    implementation(libs.spring.boot)  
    implementation(project(":adapters:endpoint"))  
    implementation(project(":adapters:persistence"))  
    developmentOnly(libs.spring.boot.devtools)  
    annotationProcessor(libs.spring.boot.configuration)  
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// application/build.gradle.kts</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">plugins</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">id</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;application&quot;</span><span style="color: #D4D4D4">)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">alias</span><span style="color: #D4D4D4">(libs.plugins.spring.boot)  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">dependencies</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">project</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;:domain&quot;</span><span style="color: #D4D4D4">))  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(libs.spring.boot)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">project</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;:adapters:endpoint&quot;</span><span style="color: #D4D4D4">))  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">implementation</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">project</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;:adapters:persistence&quot;</span><span style="color: #D4D4D4">))  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">developmentOnly</span><span style="color: #D4D4D4">(libs.spring.boot.devtools)  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">annotationProcessor</span><span style="color: #D4D4D4">(libs.spring.boot.configuration)  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph"><br>Die zentrale Klasse <strong>Application</strong> dient hierbei nicht nur als Startpunkt, sondern übernimmt in diesem Beispiel auch die Orchestrierung der Use Cases. Sie implementiert den <strong>ProductsEndpointPort</strong> (den Eingang zur Domäne) und nutzt den <strong>ProductsPersistencePort</strong> (den Ausgang zur Datenbank). Durch Dependency Injection wird die konkrete Implementierung des Persistenz-Adapters (<strong>ProductsPersistenceAdapter</strong>) zur Laufzeit bereitgestellt.</p>



<p class="wp-block-paragraph">Diese Struktur ermöglicht es, dass die Domäne selbst frei von Framework-Code bleibt, während die <strong>Application</strong>-Klasse die Verbindung zwischen den abstrakten Ports der Domäne und den konkreten Adaptern herstellt.</p>



<p class="wp-block-paragraph"></p>



<div class="wp-block-kevinbatdorf-code-block-pro atra-code" data-code-block-pro-font-family="" style="font-size:1rem;line-height:1.5rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Kotlin</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// application/src/main/kotlin/consulting/atra/hexagon/Application.kt

package consulting.atra.hexagon  

import consulting.atra.hexagon.domain.Product  
import consulting.atra.hexagon.domain.ProductsEndpointPort  
import consulting.atra.hexagon.domain.ProductsPersistencePort  
import org.springframework.boot.autoconfigure.SpringBootApplication  
import org.springframework.boot.runApplication  

@SpringBootApplication  
class Application(  
    private val persistencePort: ProductsPersistencePort  
) : ProductsEndpointPort {  
    override fun findAllProducts(): List&lt;Product> =  
        persistencePort.findAllProducts()  

    override fun findProductById(id: Long): Product? =  
        persistencePort.findProductById(id)  

    override fun createProduct(product: Product): Product =  
        persistencePort.saveProduct(product)  

    override fun applyDiscountToProduct(  
        id: Long,  
        discount: Double  
    ): Product? {  
        var product = persistencePort.findProductById(id)  
        if (product != null) {  
            product.applyDiscount(discount)  
            product = persistencePort.saveProduct(product)  
        }  
        return product  
    }  
}  

fun main(args: Array&lt;String>) {  
    runApplication&lt;Application>(*args)  
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// application/src/main/kotlin/consulting/atra/hexagon/Application.kt</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">package</span><span style="color: #D4D4D4"> consulting.atra.hexagon  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain.Product  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain.ProductsEndpointPort  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> consulting.atra.hexagon.domain.ProductsPersistencePort  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.boot.autoconfigure.SpringBootApplication  </span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.springframework.boot.runApplication  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #4EC9B0">@SpringBootApplication</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Application</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">val</span><span style="color: #D4D4D4"> persistencePort: </span><span style="color: #4EC9B0">ProductsPersistencePort</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">) : </span><span style="color: #4EC9B0">ProductsEndpointPort</span><span style="color: #D4D4D4"> {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">findAllProducts</span><span style="color: #D4D4D4">(): </span><span style="color: #4EC9B0">List</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">&gt; =  </span></span>
<span class="line"><span style="color: #D4D4D4">        persistencePort.</span><span style="color: #DCDCAA">findAllProducts</span><span style="color: #D4D4D4">()  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">findProductById</span><span style="color: #D4D4D4">(id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">? =  </span></span>
<span class="line"><span style="color: #D4D4D4">        persistencePort.</span><span style="color: #DCDCAA">findProductById</span><span style="color: #D4D4D4">(id)  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">createProduct</span><span style="color: #D4D4D4">(product: </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4"> =  </span></span>
<span class="line"><span style="color: #D4D4D4">        persistencePort.</span><span style="color: #DCDCAA">saveProduct</span><span style="color: #D4D4D4">(product)  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">override</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">applyDiscountToProduct</span><span style="color: #D4D4D4">(  </span></span>
<span class="line"><span style="color: #D4D4D4">        id: </span><span style="color: #4EC9B0">Long</span><span style="color: #D4D4D4">,  </span></span>
<span class="line"><span style="color: #D4D4D4">        discount: </span><span style="color: #4EC9B0">Double</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">    ): </span><span style="color: #4EC9B0">Product</span><span style="color: #D4D4D4">? {  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> product = persistencePort.</span><span style="color: #DCDCAA">findProductById</span><span style="color: #D4D4D4">(id)  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (product != </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">) {  </span></span>
<span class="line"><span style="color: #D4D4D4">            product.</span><span style="color: #DCDCAA">applyDiscount</span><span style="color: #D4D4D4">(discount)  </span></span>
<span class="line"><span style="color: #D4D4D4">            product = persistencePort.</span><span style="color: #DCDCAA">saveProduct</span><span style="color: #D4D4D4">(product)  </span></span>
<span class="line"><span style="color: #D4D4D4">        }  </span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> product  </span></span>
<span class="line"><span style="color: #D4D4D4">    }  </span></span>
<span class="line"><span style="color: #D4D4D4">}  </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">fun</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">main</span><span style="color: #D4D4D4">(args: </span><span style="color: #4EC9B0">Array</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">&gt;) {  </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">runApplication</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Application</span><span style="color: #D4D4D4">&gt;(*args)  </span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Fazit</h2>



<p class="wp-block-paragraph">Die Transformation vom monolithischen Spring Starter Projekt zur hexagonalen Architektur ist vollzogen. Durch die Aufteilung in Module (<strong>domain</strong>, <strong>adapters</strong>, <strong>application</strong>) wurde eine klare Trennung der Verantwortlichkeiten erreicht.</p>



<p class="wp-block-paragraph">Die Domäne ist nun das unabhängige Herzstück der Anwendung, frei von Framework-Abhängigkeiten und rein in Kotlin geschrieben. Externe Einflüsse wie REST-Schnittstellen oder Datenbanken wurden in separate Adapter ausgelagert, die über definierte Ports mit der Domäne kommunizieren.</p>



<p class="wp-block-paragraph">Zwar erhöht sich durch die Modularisierung und die Einführung von Mapping-Schichten die anfängliche Komplexität und die Menge an Boilerplate-Code, jedoch wird dies durch eine signifikant verbesserte Testbarkeit, Wartbarkeit und Flexibilität aufgewogen. Technologien können einfacher ausgetauscht und die Geschäftslogik isoliert getestet werden, was langfristig zu einer robusteren Softwarearchitektur führt.</p>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-large"><img decoding="async" width="682" height="1024" src="https://atra.consulting/wp-content/uploads/2025/10/image-682x1024.jpeg" alt="" class="wp-image-8728" style="aspect-ratio:3/4;object-fit:cover"/></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Daniel Schock</h3>



<p class="wp-block-paragraph">Senior Software Engineer</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Daniel ist ein erfahrener Fullstack-Entwickler und DevOps-Spezialist mit einem klaren Schwerpunkt auf der Backend-Entwicklung mit Java und Kotlin. Seine Expertise wird durch praktische Erfahrung in der Frontend-Entwicklung mit Vue.js abgerundet. Er verfügt über umfassende Kenntnisse in der Konzeption von CI/CD-Pipelines sowie im Einsatz von Cloud-Technologien wie Kubernetes und AWS, die er erfolgreich in den Branchen Versicherung, Logistik und E-Commerce einsetzte. Daniel arbeitet bevorzugt in agilen Umgebungen und zeichnet sich durch seine analytische Denkweise und hohe Problemlösungskompetenz aus.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:d.schock@atra.consulting">d.schock@atra.consulting</a>&nbsp; &nbsp;&nbsp;<a href="https://de.linkedin.com/in/daniel-wochnik" target="_blank" rel="noreferrer noopener"></a></p>


</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>OOP 2026: Zwischen KI und (Software-)Handwerk</title>
		<link>https://atra.consulting/engineering/oop-2026-zwischen-ki-und-software-handwerk/</link>
		
		<dc:creator><![CDATA[Michael Schwarze]]></dc:creator>
		<pubDate>Thu, 05 Mar 2026 08:49:04 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Consulting]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=9025</guid>

					<description><![CDATA[Bericht von der OOP 2026 Unter dem Motto »Embrace Change« fand die OOP 2026 vom 10. bis 13. Februar erstmals im MOC in München statt. Wir waren vor Ort und teilen unsere Eindrücke der besuchten Vorträge. Nach 35 Jahren hat die OOP Konferenz [1] ihren angestammten Platz verlassen und ist in das MOC München umgezogen. [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">Bericht von der OOP 2026</h1>



<p class="wp-block-paragraph"><strong>Unter dem Motto »Embrace Change« fand die OOP 2026 vom 10. bis 13. Februar erstmals im MOC in München statt. Wir waren vor Ort und teilen unsere Eindrücke der besuchten Vorträge.</strong></p>



<p class="wp-block-paragraph">Nach 35 Jahren hat die OOP Konferenz [1] ihren angestammten Platz verlassen und ist in das MOC München umgezogen. Ein Wandel, der zum diesjährigen Motto »Embrace Change« passte, auch wenn die Konferenz auf uns in der neuen Umgebung etwas kleiner wirkte als in den Vorjahren. Trotz widriger Umstände – ein Streik legte am Mittwoch den Münchener ÖPNV weitgehend lahm – war die Anreise dank guter Parksituation am neuen Standort entspannt.</p>



<p class="wp-block-paragraph">Inhaltlich war die diesjährige Ausgabe natürlich stark vom Thema Künstliche Intelligenz (KI) dominiert: Nahezu die Hälfte des Programms drehte sich direkt um AI, GenAI und Agentic Engineering. Aber auch die klassischen Themen wie Softwarearchitektur, Soziotechnische Systeme und 25 Jahre Agiles Manifest kamen nicht zu kurz – und waren an vielen Stellen von KI “durchzogen”.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e680a8&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e680a8" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="768" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild03_Tracks-1024x768.jpeg" alt="Blick auf die verschiedenen thematischen Blöcke der Konferenz." class="wp-image-9058" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild03_Tracks-1024x768.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild03_Tracks-768x576.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Die Konferenz ist mit über 120 Fachvorträgen in thematische Tracks unterteilt, die das gesamte Spektrum der modernen Softwareentwicklung abdecken:</p>



<ul class="wp-block-list">
<li><strong>Software Architecture – Building Software That Adapts</strong>: Strategien für flexible, zukunftsfähige Systemarchitekturen.</li>



<li><strong>Software Architecture – The Impact of Generative AI</strong>: Einfluss generativer KI auf Design-Paradigmen und Architekturprozesse.</li>



<li><strong>AI and the End of Business-as-Usual</strong>: Transformation von Geschäftsmodellen und Arbeitsprozessen durch KI.</li>



<li><strong>Product Ownership, User Experience &amp; Requirement Engineering</strong>: Nutzerzentrierte Produktentwicklung und Anforderungsmanagement.</li>



<li><strong>Back to Basics of Design, Architecture, and Programming</strong>: Rückbesinnung auf fundamentale Prinzipien des Software-Handwerks.</li>



<li><strong>Domain-Driven Design (DDD)</strong>: Beherrschung komplexer Fachdomänen durch kollaborative Modellierung.</li>



<li><strong>Platform Engineering</strong>: DevOps, thought further(?): Effizienzsteigerung durch interne Entwicklerplattformen und DevOps-Evolution.</li>



<li><strong>Legacy &amp; Innovation</strong>: Modernisierung von Altsystemen bei gleichzeitiger Aufrechterhaltung der Innovationskraft.</li>



<li><strong>Testing &amp; Quality</strong>: Qualitätssicherung, Test-Automatisierung und Validierung von KI-/Cloud-Systemen.</li>



<li><strong>Agility, Leadership &amp; Social Integration</strong>: Führungskultur, psychologische Sicherheit und moderne Agilität.</li>



<li><strong>Emerging Changes</strong>: Externe Einflüsse wie Green IT, Nachhaltigkeitsgesetze und Regulatorik.</li>
</ul>



<p class="wp-block-paragraph">Die OOP2026 reflektiert &#8222;25 Jahre Agiles Manifest&#8220; und hinterfragt, was nach der Agilität kommt. Die Eröffnungs-Keynote setzt sich kritisch mit der Vorherrschaft von US-Hyperscalern und politischen Einflüssen auf die IT-Infrastruktur auseinander und ist schon fast eine politische Ansage. Besonders hervorgehoben wird über alle Tracks der soziotechnische Ansatz – die Verbindung von Architektur, Teamkultur und Psychologie. Künstliche Intelligenz ist nicht mehr nur ein Trend-Thema, sondern zentraler Aspekt der OOP 2026.&nbsp;</p>



<p class="wp-block-paragraph">So nimmt das Thema KI/AI (inkl. GenAI und Agentic AI) etwa 30-40% des Gesamtprogramms ein. Es gibt einen dedizierten KI-Track (&#8222;AI and the End of Business-as-Usual&#8220;), aber KI-Inhalte finden sich cross-funktional in fast allen anderen Tracks (z.B. KI in der Software-Architektur, KI-gestütztes Testing, Ethik der KI). Zentrale KI-Themen sind:</p>



<ul class="wp-block-list">
<li><strong>Agentic Engineering:</strong> Der Übergang vom bloßen &#8222;Prompting&#8220; zu autonomen KI-Agenten in der Entwicklung.</li>



<li><strong>GenAI-Ethik:</strong> Kritische Diskussion über die &#8222;ethische Nutzung&#8220; und soziale Folgen (Vereinsamung in Teams durch KI-Automatisierung).</li>



<li><strong>KI-native Produktentwicklung:</strong> Wie Produkte von Grund auf neu gedacht werden müssen, wenn KI die Basis ist.</li>



<li><strong>EU AI Act:</strong> Regulatorische Anforderungen und deren Umsetzung in der Software-Architektur.</li>
</ul>



<h2 class="wp-block-heading"><br>Keynote: Eine Unterschrift Trumps und US-Hyperscaler sind illegal</h2>



<p class="wp-block-paragraph"><strong>Sprecher:</strong> Max Schrems</p>



<p class="wp-block-paragraph">Den Auftakt machte Max Schrems mit einer juristisch-technischen Realitätsprüfung, die es in sich hatte. Schrems, bekannt für seine erfolgreichen Klagen gegen Facebook, beleuchtete die massive Abhängigkeit europäischer Unternehmen von US-Cloud-Anbietern im Kontext der aktuellen geopolitischen Lage.</p>



<p class="wp-block-paragraph">Sein Kernargument: Durch Gesetze wie FISA 702 sind US-Anbieter („Electronic Communication Service Provider“) verpflichtet, US-Behörden Zugriff auf Daten (“Foreign Intelligence Information«, also somit eigentlich alles) von Nicht-US-Bürgern zu gewähren – was im direkten Konflikt mit der DSGVO und der EU-Grundrechtecharta steht. Microsoft soll ihm zufolge im Schnitt die Daten von ca. 200.000 Accounts pro Halbjahr offenlegen. Da dies auch Firmenaccounts umfasst, sind so Millionen Anwender außerhalb der EU betroffen.</p>



<p class="wp-block-paragraph">Und wie die gezeigte Seite aus Originalunterlagen der US-Regierung dazu eindrucksvoll (“Yahoo!, AOL, …”) dokumentiert, gilt dies auch schon seit mehr als 15 Jahren:</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e68f40&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e68f40" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="658" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild04_PRISM-scaled-e1772718520659-1024x658.jpeg" alt="Bild einer mehr als 15 Jahre alten Präsentation zu PRISM und FAA702" class="wp-image-9059" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild04_PRISM-scaled-e1772718520659-1024x658.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild04_PRISM-scaled-e1772718520659-768x494.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>

<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e69976&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e69976" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="574" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild05_Rechtsordnungen-scaled-e1772718620555-1024x574.jpeg" alt="Bild zum Konflikt der Rechtsordnungen EU und USA" class="wp-image-9060" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild05_Rechtsordnungen-scaled-e1772718620555-1024x574.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild05_Rechtsordnungen-scaled-e1772718620555-768x430.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">In gewissen Ländern wie bspw. Kuba und Nordkorea dürfen US-Tech-Dienste aufgrund entsprechender Vorgaben der US-Regierung derzeit schon nicht operieren. Außerdem werden Einzelpersonen regelmäßig durch die US-Regierung sanktioniert, siehe das Beispiel eines Richters des Internationalen Strafgerichtshofs, dessen sämtliche Konten bei US-Unternehmen wie Amazon, Airbnb oder PayPal von den Anbietern sofort geschlossen wurden [2]. Schrems stellte die berechtigte Frage, was nun mit Dänemark wegen Grönland passieren wird.</p>



<p class="wp-block-paragraph">Er verdeutlichte darüber hinaus, dass eine einfache „Executive Order“ des US-Präsidenten ausreicht, um Datentransfers für illegal zu erklären, Sanktionen zu verhängen oder den USA weitergehenden Zugriff auf Daten von Nicht-US-Bürgern zu gewähren.</p>



<p class="wp-block-paragraph">Hierbei lieferte er auch noch spannende Details zum Instrument “Executive Order”, welches sich wohl aufgrund der immer schwierigeren Gesetzgebungsverfahren mit dem Kongress schon seit Jahren zum Mittel der Wahl der US-Regierungen gemausert hat. Die Executive Order ist dabei kein Gesetz, sondern eine Dienstanweisung an Bundesbehörden. Sie kann bestehende Gesetze, die vom Kongress verabschiedet wurden, zwar nicht außer Kraft setzen oder umschreiben, durch geschickte Formulierung aber bspw. die Arbeit einer Behörde so einschränken, dass dies dem gleich kommt. Außerdem bestehen Möglichkeiten für den Präsidenten, die Inhalte von Executive Orders (und ähnlichen präsidialen Anweisungen) geheim zu halten.&nbsp;</p>



<p class="wp-block-paragraph">Besonders kritisch sah er die sogenannten „Supplementary Measures“ (wie Verschlüsselung) der Hyperscaler, die oft mehr Marketing als echter Schutz seien, solange der Anbieter selbst den Schlüssel hält oder durch US-Recht zur Herausgabe gezwungen werden kann. Mehr Details siehe bspw. auch hier [3].&nbsp;</p>



<p class="wp-block-paragraph">Sein Fazit war ernüchternd, aber klar: Eine rechtlich saubere Trennung wäre zwar möglich, insofern die großen Player ihre europäischen Dependancen bspw. als reine Finanzbeteiligungen führen würden, was aber&nbsp; bisher nicht konsequent umgesetzt wurde. Und da wir faktisch auch gar nicht wissen, welche Daten wirklich mitgelesen werden (Stichwort: geheime Executive Order), wäre es auch so oder so skeptisch zu bewerten. Für uns als Software Architekten bedeutet dies: Das Risiko ist real, „Compliance“ ist mehr als nur Papierkram und Digitale Souveränität wird und muss unseren Arbeitsalltag beherrschen.</p>



<h2 class="wp-block-heading"><br>Lean Compliance as Strategic Asset in Agile Organizations</h2>



<p class="wp-block-paragraph"><strong>Sprecher:</strong> Felix Rüssel, Erika Schüttfort</p>



<p class="wp-block-paragraph">Passend zum Thema Regulierung zeigte dieser Vortrag einen pragmatischen Weg aus der „Death by Checklists“-Falle, die wir in Europa mit im Schnitt einer neuen Regulierung alle drei Stunden schon lange erreicht haben. Und sich durch immer neue Anforderungen (Lieferkettensorgfaltspflichtengesetz, Digital Operational Resilience Act, …) auch auf unsere Arbeit als Softwarearchitekten und Produktentwickler niederschlägt:</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e6a654&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e6a654" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="743" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild06_Anzahl-Regulierungen-scaled-e1772718675623-1024x743.jpeg" alt="Bild, welches schematisch darstellt, wie die Anzahl der Regulierungen in den vergangenen 5 Jahren angewachsen ist." class="wp-image-9062" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild06_Anzahl-Regulierungen-scaled-e1772718675623-1024x743.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild06_Anzahl-Regulierungen-scaled-e1772718675623-768x557.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Die Referenten legten dar, dass viele Unternehmen Compliance fälschlicherweise als nachgelagerte Kontrollinstanz missverstehen. Stattdessen sei Compliance als integraler, wertschöpfender Baustein innerhalb des Wertstroms zu betrachten, dessen Fehlplanung oder Engpässe ein fundamentales Fluss-Problem („Flow“) darstellen.</p>



<p class="wp-block-paragraph">Statt Compliance als nachgelagerten Bremsklotz zu behandeln, sollte sie als „Lean Compliance“ integraler Bestandteil des Entwicklungsprozesses sein (“Shift Left”). Das Ziel ist eine echte Zusammenarbeit zwischen „Makers“ (Entwicklern) und „Checkers“ (Compliance Officers), statt eines Gegeneinanders.&nbsp;</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e6b120&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e6b120" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="738" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild07_Maker-Checker-scaled-e1772718782842-1024x738.jpeg" alt="Eine Übersicht der drei wesentlichen Rollen: Product Manager, Engineer und Compliance Officer" class="wp-image-9063" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild07_Maker-Checker-scaled-e1772718782842-1024x738.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild07_Maker-Checker-scaled-e1772718782842-768x554.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Besonders interessant war der Ansatz der „Minimum Viable Compliance“ (MVC) – also Compliance iterativ und parallel zum Produkt zu entwickeln, statt am Ende vor einem Berg an Anforderungen zu stehen.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e6bb69&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e6bb69" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="722" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild08_MVC-scaled-e1772718835692-1024x722.jpeg" alt="Bild vom Ansatz der Minimum Viable Compliance, einem &quot;klassischen&quot; PDCA-Zyklus" class="wp-image-9064" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild08_MVC-scaled-e1772718835692-1024x722.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild08_MVC-scaled-e1772718835692-768x541.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Die Redner adaptieren hierbei Kernprinzipien agiler Frameworks wie Scrum und Kanban für den Compliance-Sektor. Anstatt als isolierte Prüfinstanz zu agieren, integriert sich die Compliance-Funktion unmittelbar in cross-funktionale Produktteams, um regulatorische Anforderungen als kontinuierlichen Teil des Entwicklungsprozesses zu begreifen.</p>



<p class="wp-block-paragraph">Gerade in Deutschland ist die Klage über eine vermeintliche Überregulierung allgegenwärtig. Die Referenten schlossen ihren Vortrag jedoch mit einem pointierten Gegenentwurf ab: Nicht die Menge der Regulierung sei das primäre Hindernis, sondern deren ineffiziente Einbindung in die Wertschöpfungskette:</p>



<p class="wp-block-paragraph"><em>»Organisationen scheitern selten an der Regulierung selbst, sondern daran, dass ihr Betriebsmodell diese nicht absorbieren kann.«</em></p>



<h2 class="wp-block-heading"><br>Strategien für die Analyse großer Softwaresysteme mit Sprachmodellen</h2>



<p class="wp-block-paragraph"><strong>Sprecher:</strong> Michael Stal (Principal Key Expert Engineer, Siemens AG)</p>



<p class="wp-block-paragraph">Michael Stal, eine der zentralen Figuren der OOP-Konferenz (Conference Chair, regelmäßiger Sprecher, Autor zahlreicher Fachpublikationen sowie Chefredakteur JavaSPEKTRUM) gab einen tiefen Einblick in das Projekt „SARA“ (Siemens Architecture Review Agent), ein Versuch, die millionenschweren Codebasen des Siemens-Konzerns mittels LLMs zu analysieren. Plakatives Ziel ist dabei, z.B. dem Software-Korpus des ICE die Frage stellen zu können, warum eine spezielle Baureihe des ICE unter gewissen Umständen nicht bremst. Hierzu haben sie ein komplexes System aufgesetzt, welches sowohl moderne KI-Ansätze als auch klassische Code-Analyse-Tools verbindet.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e6c762&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e6c762" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="772" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild09_Loesungsueberblick-1024x772.jpeg" alt="Überblick der Gesamt-Architektur" class="wp-image-9065" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild09_Loesungsueberblick-1024x772.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild09_Loesungsueberblick-768x579.jpeg 768w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild09_Loesungsueberblick-780x588.jpeg 780w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Der Vortrag war dabei auch erfrischend ehrlich bezüglich der Grenzen aktueller KI-Modelle. Stal zeigte auf, dass LLMs zwar stark im Pattern-Matching sind, ihnen aber oft das Verständnis für den zeitlichen Verlauf (Code-Historie) und den Projektkontext fehlt. Um Halluzinationen und Kontext-Probleme in den Griff zu bekommen, setzten sie auf fortgeschrittene Prompting-Strategien wie „Chain of Thought“ und Multi-Agenten-Systeme, bei denen ein Agent Lösungen vorschlägt und ein anderer (Critique Agent) diese prüft – ein sogenannter Adversarial Approach.</p>



<p class="wp-block-paragraph">Vom Engineering-Standpunkt betrachtet, hat uns das Vorhaben hier umgehauen, da wurde modernste Technologie intelligent verbaut, um die Komplexität, die vermutlich tausende Entwickler und Architekten über Jahrzehnte geschaffen haben, zukünftig noch beherrschbar zu halten. Unsere Erkenntnis hier war jedoch auf unsere Nachfrage auch wirtschaftlicher Natur: Mit initialen Entwicklungskosten von rund 1,5 Millionen Euro und hohen Betriebskosten für private Cloud-Instanzen und Betriebsaufwänden für die durchaus komplexe Infrastruktur ist der Return on Invest (ROI) solcher Eigenentwicklungen noch nicht abschließend geklärt. Es bleibt der Eindruck: Man hat es gebaut, weil man es sich als Konzern leisten kann, aber der breite Nutzen muss sich erst noch beweisen.</p>



<h2 class="wp-block-heading"><br>Wie die Natur Probleme löst – und was IT-Projekte daraus lernen können</h2>



<p class="wp-block-paragraph"><strong>Sprecherin:</strong> Anna Melbinger</p>



<p class="wp-block-paragraph">Dr. Anna Melbinger ist promovierte Physikerin, die nach mehrjähriger internationaler Forschungstätigkeit im Bereich der theoretischen und biologischen Physik in die Beratung wechselte, wo sie aktuell Transformations- und IT-Strategieprojekte leitet.</p>



<p class="wp-block-paragraph">Ihr Vortrag, der biologische Strategien auf IT-Herausforderungen übertrug, war für uns einer der Höhepunkte der diesjährigen Konferenz – auch wenn keine Keynote. Die Natur, Meisterin im Schaffen langlebiger, komplexer Systeme, liefert ihr zufolge „Vorlagen“ und Hilfestellungen für unsere alltäglichen IT-Probleme.</p>



<p class="wp-block-paragraph">Dabei optimiert die Natur nicht auf Effizienz, sondern auf Robustheit – ein Prinzip, das wir in der Softwarearchitektur oft vernachlässigen, sind doch gerade aktuell wieder Produktivität und Effizienz präsenter denn je.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e6d3ef&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e6d3ef" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="904" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild10_Genetic-Drift-1024x904.jpeg" alt="Schematische Darstellung des Genetic Drift" class="wp-image-9067" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild10_Genetic-Drift-1024x904.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild10_Genetic-Drift-768x678.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Spannend war der Vergleich mit Bakterien (Chemotaxis) und Motten (Infotaxis), die Ziele nicht auf direktem Weg, sondern durch „Run-and-Tumble“ oder das Sammeln von Informationen erreichen. Für uns bedeutet das: In unsicheren Projektumgebungen ist es oft besser, Entscheidungspunkte zu setzen und sich an der Entwicklung von Kennzahlen (bspw. einem Abwärtstrend bei den Bugs) statt stur Meilensteine abzuarbeiten und absoluten Kennzahlen hinterherzurennen.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e6de4b&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e6de4b" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="836" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild11_Chemotaxis-1024x836.jpeg" alt="Überblick zu den Chemotaxis" class="wp-image-9068" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild11_Chemotaxis-1024x836.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild11_Chemotaxis-768x627.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Eine wichtige Erkenntnis: Evolution passiert am Engpass und dementsprechend ist auch eine Entlastung am Engpass blinder Optimierung überlegen. Die Rednerin brachte hier das Beispiel der Laktose-Toleranz, welche in nördlichen Ländern aufgrund des veränderten Nahrungsangebots zu einem Überlebensvorteil geführt hat.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e6e894&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e6e894" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="2560" height="1440" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild12_Evolution-edited-scaled.jpeg" alt="Überblick zu Evolution" class="wp-image-9088" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild12_Evolution-edited-scaled.jpeg 2560w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild12_Evolution-edited-1024x576.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild12_Evolution-edited-768x432.jpeg 768w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild12_Evolution-edited-1536x864.jpeg 1536w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild12_Evolution-edited-2048x1152.jpeg 2048w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild12_Evolution-edited-780x440.jpeg 780w" sizes="(max-width: 2560px) 100vw, 2560px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Auch das Konzept, dass Innovation Vielfalt (wie bei T-Zellen) und nicht vorzeitige Fokussierung benötigt, ist ein starkes Plädoyer für diverse Teams und Lösungsansätze, offenes Brainstroming und Design-Thinking-Ansätze.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e6f349&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e6f349" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="2560" height="1440" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild13_T-Zellen-edited-scaled.jpeg" alt="Übersicht zu T-Zellen" class="wp-image-9087" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild13_T-Zellen-edited-scaled.jpeg 2560w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild13_T-Zellen-edited-1024x576.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild13_T-Zellen-edited-768x432.jpeg 768w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild13_T-Zellen-edited-1536x864.jpeg 1536w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild13_T-Zellen-edited-2048x1152.jpeg 2048w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild13_T-Zellen-edited-780x440.jpeg 780w" sizes="(max-width: 2560px) 100vw, 2560px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Die Evolution, ein fundamentaler Prozess in der Natur, bewältigt die Herausforderungen der Anpassung und Optimierung durch das gnadenlose Prinzip des „Survival of the fittest“, sprich das Aussterben der weniger geeigneten. Ein solches Vorgehen ist in IT-Projekten, wo Zeit, Ressourcen und der Erfolg des Projekts auf dem Spiel stehen, weder wünschenswert noch praktikabel. Die „natürliche Auslese“, bei der ungeeignete Elemente erst in der späten Phase oder nach dem Scheitern des Gesamtprojekts identifiziert werden, ist ein kostspieliges und riskantes Unterfangen.</p>



<p class="wp-block-paragraph">Die zentrale Herausforderung in IT-Projekten lautet daher: Wie können wir dieses natürliche Prinzip umkehren? Wie können wir proaktiv und im Voraus erkennen, welche Teile unseres Projekts – seien es Code-Architekturen, Prozesse oder Anforderungen – nicht „fit“ (geeignet, nachhaltig, wartbar) sind, bevor sie Schaden anrichten oder das Projekt in eine Sackgasse führen?</p>



<p class="wp-block-paragraph">Hierzu lieferte die Rednerin keinen Blueprint, unserer Erkenntnis nach bieten agile Prinzipien aber einen wesentlichen Lösungsansatz. Sie bieten Methoden und Rahmenwerke, um das Unsichtbare sichtbar zu machen. Eine Kultur der kontinuierlichen Inspektion und Adaption zwingt durch kurze Iterationen (Sprints in Scrum) oder den ständigen Fluss in Kanban das Team, regelmäßig innezuhalten (z.B. in Retrospektiven) und kritisch zu hinterfragen, was funktioniert und was nicht. Dies ist die künstliche, menschlich gesteuerte Alternative zur „natürlichen Auslese“: Wir erkennen die Mängel, bevor das „Aussterben“ (das Scheitern des Projekts) droht, und korrigieren den Kurs.</p>



<h2 class="wp-block-heading"><br>Keynote: State of Play: KI-unterstütztes Programmieren</h2>



<p class="wp-block-paragraph"><strong>Sprecherin:</strong> Birgitta Böckeler (Thoughtworks)</p>



<p class="wp-block-paragraph">Birgitta Böckeler lieferte einen sehr fundierten Überblick über den aktuellen Stand von KI in der Softwareentwicklung. Wir bewegen uns ihr zufolge weg vom reinen „Autocomplete on Steroids“ hin zu „Agentic Engineering“ und komplexen Workflows.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e703f0&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e703f0" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="739" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild14_AGENT.MD_-1024x739.jpeg" alt="Schematische Darstellung der Bausteine eines Coding Assistants rund um die Datei AGENT.MD" class="wp-image-9071" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild14_AGENT.MD_-1024x739.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild14_AGENT.MD_-768x554.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Besonders wichtig erschien uns der Hinweis auf das &#8222;Context Engineering&#8220;: Der Erfolg von KI-Tools hängt entscheidend davon ab, wie effektiv der Kontext – also Regeln, benötigte Fähigkeiten und Schnittstellen – gemanagt und der KI bereitgestellt wird. Man könnte dies als eine Art &#8222;Prompt Engineering on steroids&#8220; oder &#8222;RAG on steroids&#8220; bezeichnen. Im Kern geht es dabei nach wie vor darum, ein großes &#8222;Standard&#8220;-Sprachmodell, das die wenigsten aus Kostengründen selbst trainieren können, mit den notwendigen Informationen zu versorgen – entweder direkt über den Prompt oder &#8222;intelligent&#8220; aus angeschlossenen Drittsystemen.&nbsp;</p>



<p class="wp-block-paragraph">Wobei die auch hier von der Rednerin u.a. referenzierte Agents.md nicht das Allheilmittel ist, mit dem sie derzeit durch die entsprechenden Fachmedien geht. Eine aktuelle Studie [4] fand dazu heraus:&nbsp;</p>



<p class="wp-block-paragraph"><em>»Across multiple coding agents and LLMs, we find that context files tend to reduce task success rates compared to providing no repository context, while also increasing inference cost by over 20%.«</em></p>



<p class="wp-block-paragraph">Die Rednerin war ebenso wie wir davon überzeugt, dass lokal betriebene, kleine Modelle mittelfristig aus Komplexitäts- und Performancegründen aussterben werden. So sind ihrer Einschätzung nach selbst die guten kleinen Modelle 8-12 mal langsamer als die großen:</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e70f76&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e70f76" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="689" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild15_kleine-Modelle-1024x689.jpeg" alt="Bild des Zitats, das kleine Modelle nicht mithalten können." class="wp-image-9072" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild15_kleine-Modelle-1024x689.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild15_kleine-Modelle-768x517.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Gleichzeitig warnte sie vor den Kosten („The Honeymoon is over“) und Sicherheitsrisiken wie Prompt Injection. Ihr Rat: Kenne dein Werkzeug und nutze es, auch wenn du skeptisch bist – denn KI wird die Art, wie wir Software bauen, fundamental verändern, auch wenn Halluzinationen ein “Feature” und kein Bug bleiben.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e719ec&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e719ec" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="486" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild16_KI-schweizer-Taschenmesser-1024x486.jpeg" alt="Visualisierung KI ist kein Hammer, es ist ein Schweizer Taschenmesser" class="wp-image-9073" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild16_KI-schweizer-Taschenmesser-1024x486.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild16_KI-schweizer-Taschenmesser-768x364.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Im Vortrag wurden auch einige aufschlussreiche Zahlen zu den Kosten von KI in der Entwicklung präsentiert, die in all dem Marketing-Hype (“Wir brauchen dank KI keine Entwickler mehr”) gerade untergehen. Während die KI-Generierung von 100 Zeilen Code Anfang 2024 lediglich 12 Cents kostete, stiegen diese Kosten bis zum Sommer 2025 auf 2,5 $ – in anderthalb Jahren also um den Faktor 21! Bei intensiver Nutzung in der Entwicklung –&nbsp;man darf nicht außer acht lassen, dass all die Agenten, die da gerade am Werk sind, extrem Token-hungrig sind, können die KI-Kosten schnell auf jährlich rund 90.000 $ steigen. Ein Betrag, für den man wiederum auch einen Entwickler einstellen könnte…</p>



<p class="wp-block-paragraph">Und obwohl KI die Code-Erstellung beschleunigen mag, bleiben die Ergebnisse noch aus. So kommt ein Working Paper der Harvard University vom 7. Januar 2026 [5] bspw. zu folgender Erkenntnis:</p>



<p class="wp-block-paragraph"><em>»Generative AI tools like Copilot and Cursor lead to moderate [~8 %], but not transformational, improvements in engineers’ productivity […and] does not translate to effects on downstream outcomes.«</em></p>



<p class="wp-block-paragraph">Ein kritischer Punkt ist und bleibt der Mensch als limitierender Faktor bei der Verwaltung der Vielzahl von KI-Agenten. Die wesentlichen Schritte der Softwareentwicklung bleiben der Rednerin zufolge weiterhin in menschlicher Hand, nämlich die Spezifikation (Klärung der Anforderungen: „Was will ich?“) und die Verifizierung (Überprüfung des Ergebnisses: „Ist es das, was ich will?“).</p>



<h2 class="wp-block-heading"><br>Missverständnisse zu Softwarearchitektur</h2>



<p class="wp-block-paragraph"><strong>Sprecherin:</strong> Carola Lilienthal</p>



<p class="wp-block-paragraph">Carola Lilienthal räumte gewohnt souverän mit gängigen Mythen der Softwarearchitektur auf. Basierend auf ihrer Analyse hunderter Softwaresysteme zeigte sie, warum Sätze wie „Wir machen Microservices, also brauchen wir keine Architektur mehr“ oder „Neubau ist besser als Refactoring“ gefährliche Trugschlüsse sind.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e72695&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e72695" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="645" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild17_Missverstaendnisse-1024x645.jpeg" alt="Bild mit einer Liste der 8 Missverständnisse zu Softwarearchitektur" class="wp-image-9074" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild17_Missverstaendnisse-1024x645.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild17_Missverstaendnisse-768x484.jpeg 768w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild17_Missverstaendnisse-570x360.jpeg 570w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>

<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e731a9&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e731a9" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="603" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild18_Kohaesion-1024x603.jpeg" alt="Überblick zu hoher Kohäsion und loser Kopplung" class="wp-image-9075" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild18_Kohaesion-1024x603.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild18_Kohaesion-768x453.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Ein Dauerbrenner für die Praxis der Softwareentwicklung und der Rednerin (und unserer Einschätzung) zufolge das Fundament modularer und wartbarer Architekturen: Die klare Unterscheidung und konsequente Anwendung<em> </em><em>hoher Kohäsion</em> (engl. <em>High Cohesion</em>) innerhalb von Modulen und von <em>loser Kopplung</em> (engl. Loose Coupling) zwischen Modulen.</p>



<p class="wp-block-paragraph">Hohe Kohäsion bedeutet, dass die Elemente innerhalb eines Moduls (z.B. Klassen, Methoden oder Funktionen) eine starke thematische und funktionale Zusammengehörigkeit aufweisen. Sie arbeiten eng zusammen, um eine <em>einzige, klar definierte Verantwortung</em> zu erfüllen (dem <em>Single Responsibility Principle</em> folgend). Module mit hoher Kohäsion sind leichter zu verstehen, zu testen und zu warten, da Änderungen an einer Verantwortung meist nur dieses eine Modul betreffen.</p>



<p class="wp-block-paragraph">Lose Kopplung hingegen beschreibt das Ideal minimaler, wohl-definierter Abhängigkeiten <em>zwischen</em> verschiedenen Modulen. Module sollten so wenig wie möglich über die internen Details anderer Module wissen. Änderungen im Inneren eines Moduls sollen idealerweise keine oder nur minimale Auswirkungen auf andere, davon abhängige Module haben (lose Kopplung). Dies wird oft durch die Verwendung von klaren Schnittstellen (Interfaces), Abstraktionen und Dependency Injection erreicht.</p>



<p class="wp-block-paragraph">Eine zentrale Gefahr und eine ständige Herausforderung in der Architektur ist die Entstehung <em>zyklischer Abhängigkeiten</em> (engl. <em>Circular Dependencies</em>). Hierbei hängt Modul A von Modul B ab, und Modul B hängt gleichzeitig von Modul A ab. Solche Zyklen bilden &#8222;Super-Module&#8220; oder große, unflexible Abhängigkeitsringe, die die Vorteile von Modularität vollständig untergraben.</p>



<p class="wp-block-paragraph">Die Warnung der Rednerin vor zyklischen Abhängigkeiten ist dabei besonders vehement, da sie auch durch Interfaces nicht verschwinden. Ein Interface kann zwar die <em>Art</em> der Abhängigkeit auf eine Abstraktionsebene heben und die Kopplung <em>lockern</em>, aber es löst den <em>zyklischen Verweis</em> selbst nicht auf. Wenn Modul A eine Schnittstelle I definiert, die Modul B implementiert, und Modul B dann wiederum direkt oder indirekt Modul A importiert, besteht der Zyklus weiterhin, was die Testbarkeit, die Wiederverwendbarkeit und die Deployment-Flexibilität massiv einschränkt. Die saubere Auflösung solcher Zyklen erfordert oft eine Umstrukturierung der Module oder die Einführung einer weiteren Abstraktionsebene (z.B. ein drittes Modul, das die Abhängigkeiten orchestriert).</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e73ff0&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e73ff0" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="663" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild19_Zyklen-1024x663.jpeg" alt="Sichtbarmachung der zyklischen Abhängigkeiten von 327 aus 8 Komponenten, die sich gegenseitig mehrfach aufrufen, wodurch der berühmte Big Ball of Mudd entsteht." class="wp-image-9076" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild19_Zyklen-1024x663.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild19_Zyklen-768x497.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Obwohl der Quellcode die „Wahrheit“ darstellt und KI uns immer besser beim Verständnis desselben unterstützt, bleibt eine grundlegende Dokumentation von Softwaresystemen unverzichtbar. Denn die Beweggründe für bestimmte architektonische Entscheidungen kann selbst eine KI nicht einfach aus dem Code ableiten, wie auch <a href="https://docs.google.com/document/d/1x99pADOLZgm6Meg03VjqdhzrqlKav86InTcAHlsRJ8I/edit?tab=t.0#heading=h.ima31upukzgo" target="_blank" rel="noopener">Michael Stal in seinem Vortrag</a> eindrucksvoll verdeutlichte.</p>



<p class="wp-block-paragraph">Sehr gut hat uns die kompakte Zusammenfassung des arc42-Ansatzes zur Architekturdokumentation [6] der Rednerin gefallen. Es gelang ihr, die zentralen Konzepte und die Struktur, die dieses Open-Source-Framework für eine effektive und verständliche Dokumentation von Software-Architekturen bietet, auf den Punkt zu bringen, ohne dabei wesentliche Details zu übergehen.&nbsp;</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e74e62&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e74e62" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="652" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild20_Architketursichten-1024x652.jpeg" alt="Übersicht zu den Architektursichten gemäß Arc42" class="wp-image-9077" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild20_Architketursichten-1024x652.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild20_Architketursichten-768x489.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Ein solider, fast zeitloser Vortrag, der daran erinnerte, dass die handwerklichen Grundlagen auch im KI-Zeitalter unverzichtbar bleiben.</p>



<h2 class="wp-block-heading"><br>Was Craftsmanship ausmacht</h2>



<p class="wp-block-paragraph"><strong>Sprecher:</strong> Marco Achtziger</p>



<p class="wp-block-paragraph">Ergänzend wurden in diesem Vortrag Einblicke in die Implementierung von „Craftsmanship“-Programmen, konkret im Testumfeld von Siemens, gewährt. Die zentrale Erkenntnis war, dass exzellentes Handwerk nicht hierarchisch verordnet werden kann. Stattdessen erfordert es einen kulturellen Wandel, der sich an Daniel Pinks Werk <em>Drive</em> [7] orientiert. Dieser Wandel basiert auf den drei Säulen intrinsischer Motivation – Autonomie (Autonomy), Beherrschung des Fachgebiets (Mastery) und Sinnhaftigkeit (Purpose) –, die essenziell sind, um Leistung und Zufriedenheit in der modernen Wissensarbeit zu steigern.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e75d93&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e75d93" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="2560" height="1440" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild21_TLDR-edited-scaled.jpeg" alt="Eine Zusammenfassung (TLDR) des Vortrags als Bild" class="wp-image-9089" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild21_TLDR-edited-scaled.jpeg 2560w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild21_TLDR-edited-1024x576.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild21_TLDR-edited-768x432.jpeg 768w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild21_TLDR-edited-1536x864.jpeg 1536w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild21_TLDR-edited-2048x1152.jpeg 2048w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild21_TLDR-edited-780x440.jpeg 780w" sizes="(max-width: 2560px) 100vw, 2560px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Der Redner gab dabei auch einen interessanten Einblick in die Software Craftsmanship Bewegung, beginnend in den 1990ern mit Extreme Programming, über Robert Martins&nbsp; <em>Clean Code(r)</em> und das “<em>Manifesto for Software Craftsmanship</em>“ im Jahr 2009 [8]:</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e7756c&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e7756c" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="843" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild22_Manifest-1024x843.jpg" alt="Ein Bild des Manifests für Software Craftmanship" class="wp-image-9079" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild22_Manifest-1024x843.jpg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild22_Manifest-768x632.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Eines von Steven Jobs berühmten Zitaten bildete einen guten Abschluss zu dem Vortrag:</p>



<p class="wp-block-paragraph"><em>»When you’re a carpenter making a beautiful chest of drawers, you’re not going to use a piece of plywood on the back, even though it faces the wall and nobody will ever see it. You’ll know it’s there, so you’re going to use a beautiful piece of wood on the back. For you to sleep well at night, the aesthetic, the quality, has to be carried all the way through.«</em></p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e78197&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e78197" class="aligncenter size-large is-resized wp-lightbox-container"><img decoding="async" width="2560" height="1439" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild23_Steve-Jobs-Zitat-edited-scaled.jpeg" alt="Ein Bild von Stephen Jobs mit dem Zitat daneben." class="wp-image-9090" style="width:860px" srcset="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild23_Steve-Jobs-Zitat-edited-scaled.jpeg 2560w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild23_Steve-Jobs-Zitat-edited-1024x576.jpeg 1024w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild23_Steve-Jobs-Zitat-edited-768x432.jpeg 768w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild23_Steve-Jobs-Zitat-edited-1536x863.jpeg 1536w, https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild23_Steve-Jobs-Zitat-edited-2048x1151.jpeg 2048w" sizes="(max-width: 2560px) 100vw, 2560px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<h2 class="wp-block-heading"><br>Unsere Einschätzung</h2>



<p class="wp-block-paragraph">Die OOP 2026 hat gezeigt, dass die Branche in Bewegung ist. Der Umzug in das MOC hat der Veranstaltung durch die bessere Verkehrsanbindung und die weiterläufigeren Räumlichkeiten gut getan, auch wenn sie etwas kompakter wirkte. Inhaltlich war die Dominanz von KI allgegenwärtig – nicht mehr als Hype, sondern in der Phase der konkreten, teils ernüchternden, teils hoffnungsvollen Anwendung (Agentic AI, RAG) –&nbsp;wo man das Thema in Gartners Hype-Cycle [9] aktuell verortet, mag dabei jeder für sich entscheiden:</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e78cf8&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e78cf8" class="aligncenter size-full is-resized wp-lightbox-container"><img decoding="async" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/03/OOP2026_Bild24_Gartner_Hype_Zyklus.svg" alt="Übersicht des Gartner Hypecycles" class="wp-image-9081" style="width:860px"/><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Gleichzeitig war spürbar, dass die klassischen Tugenden – saubere Architektur, soziotechnische Gestaltung und solides Handwerk – nicht an Bedeutung verlieren, sondern gerade durch die KI-Unterstützung noch wichtiger werden, um die entstehende Komplexität beherrschbar zu halten.</p>



<h3 class="wp-block-heading">Quellenangaben</h3>



<p class="wp-block-paragraph">Die Informationen basieren auf dem Besuch der OOP 2026 sowie den bereitgestellten Unterlagen und Vortragsbeschreibungen der Konferenz.</p>



<p class="wp-block-paragraph">[1]: <a href="https://www.oop-konferenz.de/de" target="_blank" rel="noopener">https://www.oop-konferenz.de/de</a><br>[2]: <a href="https://www.heise.de/news/Wie-ein-franzoesischer-Richter-von-den-USA-digital-abgeklemmt-wurde-11087453.html" target="_blank" rel="noopener">https://www.heise.de/news/Wie-ein-franzoesischer-Richter-von-den-USA-digital-abgeklemmt-wurde-11087453.html</a>&nbsp;<br>[3]: <a href="https://www.heise.de/news/Nicht-souveraen-Microsoft-kann-Sicherheit-von-EU-Daten-nicht-garantieren-10494684.html" target="_blank" rel="noopener">https://www.heise.de/news/Nicht-souveraen-Microsoft-kann-Sicherheit-von-EU-Daten-nicht-garantieren-10494684.html</a>&nbsp;<br>[4]: <a href="https://arxiv.org/abs/2602.11988" target="_blank" rel="noopener">https://arxiv.org/abs/2602.11988</a><br>[5]: <a href="https://fion.ac/jellyfish.pdf" target="_blank" rel="noopener">https://fion.ac/jellyfish.pdf</a><br>[6]: <a href="https://arc42.de/" target="_blank" rel="noopener">https://arc42.de/</a><br>[7]: <a href="https://en.wikipedia.org/wiki/Drive:_The_Surprising_Truth_About_What_Motivates_Us" target="_blank" rel="noopener">https://en.wikipedia.org/wiki/Drive:_The_Surprising_Truth_About_What_Motivates_Us</a><br>[8]: <a href="https://manifesto.softwarecraftsmanship.org/" target="_blank" rel="noopener">https://manifesto.softwarecraftsmanship.org/</a><br>[9]: <a href="https://de.wikipedia.org/wiki/Hype-Zyklus" target="_blank" rel="noopener">https://de.wikipedia.org/wiki/Hype-Zyklus</a>&nbsp;</p>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-full is-resized"><img decoding="async" width="320" height="320" src="https://atra.consulting/wp-content/uploads/2025/01/Team-Schwarze.jpg" alt="" class="wp-image-3217" style="object-fit:cover;width:417px;height:auto" title="Team-Schwarze"/></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Michael Schwarze</h3>



<p class="wp-block-paragraph">Geschäftsführer</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Michael ist ein erfahrener Softwareentwickler, -architekt und -manager mit über 30 Jahren Erfahrung in der Technologiebranche. Er hat sowohl in Startups als auch Konzernen auf Anwender- als auch Entwicklungs- und Beratungsseite gearbeitet.&nbsp; Coden ist für ihn nicht nur Beruf, sondern Leidenschaft, am liebsten mit dynamisch-typisierten Sprachen wie Ruby. Neben der Entwicklung langlebiger Softwaresysteme liegt ihm auch die Verbesserung des Managements in der Softwareentwicklung am Herzen. Wenn er nicht gerade mit seiner Familie und seinen zwei Kindern beschäftigt ist, findet man ihn in den Bergen, beim Joggen oder anderen sportlichen Aktivitäten.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:m.schwarze@atra.consulting">m.schwarze@atra.consulting</a>&nbsp; &nbsp;&nbsp;<a href="https://www.linkedin.com/in/michael-schwarze/" target="_blank" rel="noreferrer noopener"></a></p>



<ul class="wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a href="https://www.linkedin.com/in/michael-schwarze/" class="wp-block-social-link-anchor" target="_blank" rel="noopener"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li></ul>
</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Warum Priorisierung heute mehr braucht als eine Matrix</title>
		<link>https://atra.consulting/engineering/warum-priorisierung-heute-mehr-braucht-als-eine-matrix/</link>
		
		<dc:creator><![CDATA[Daniel Wochnik]]></dc:creator>
		<pubDate>Thu, 15 Jan 2026 09:04:28 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Consulting]]></category>
		<category><![CDATA[Fokus & Stärken]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Organisation]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=8939</guid>

					<description><![CDATA[Die Eisenhower-Matrix ist ein Klassiker der Management- und Consulting-Werkzeuge. Aufgaben werden in vier Quadranten nach Wichtigkeit und Dringlichkeit sortiert, und daraus leitet sich ab, was man sofort erledigt, delegiert oder konsequent lassen sollte. Gerade jungen Führungskräften empfehle ich Eisenhower regelmäßig – weil es einfach, eingängig und eigentlich ziemlich überzeugend ist. Umso erstaunter war ich, als [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Die Eisenhower-Matrix ist ein Klassiker der Management- und Consulting-Werkzeuge. Aufgaben werden in vier Quadranten nach Wichtigkeit und Dringlichkeit sortiert, und daraus leitet sich ab, was man sofort erledigt, delegiert oder konsequent lassen sollte. Gerade jungen Führungskräften empfehle ich Eisenhower regelmäßig – weil es einfach, eingängig und eigentlich ziemlich überzeugend ist.</p>



<p class="wp-block-paragraph">Umso erstaunter war ich, als mir kürzlich in einem ruhigen Moment auffiel, dass ich mich selbst im Arbeitsalltag erstaunlich selten daran halte. Und schlimmer noch: dass ich ziemlich gut darin geworden bin, mir das auch noch schönzureden.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e81342&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e81342" class="alignright size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="572" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/01/image-1-1024x572.png" alt="" class="wp-image-8941" style="width:400px" srcset="https://atra.consulting/wp-content/uploads/2026/01/image-1-1024x572.png 1024w, https://atra.consulting/wp-content/uploads/2026/01/image-1-768x429.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Eisenhower ist aus meiner Sicht weiterhin ein sinnvolles Werkzeug – das ist mir wichtig vorwegzuschicken. Gleichzeitig stößt dieses Zeitmanagement-Modell aus der Mitte des 20. Jahrhunderts – entwickelt von einem US-General und späteren Präsidenten – im Arbeitsalltag moderner Wissensarbeiter erstaunlich schnell an seine Grenzen.</p>



<p class="wp-block-paragraph">Dafür gibt es mehrere Gründe.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Kognitive Überlastung: Wenn zu viele Reize um Aufmerksamkeit konkurrieren</strong></h3>



<p class="wp-block-paragraph">Wissensarbeiter – egal ob Fachspezialisten, Berater oder Entscheider – leiden heute weniger an fehlender Priorisierung als an kognitiver Überlastung. Die ständige Notwendigkeit, zwischen konzentrierter Arbeit an komplexen Fragestellungen und reaktiver Kommunikation zu wechseln, erzeugt Kontextwechselkosten (siehe auch [1]), die Fokus, Entscheidungsqualität und letztlich auch die eigene Zufriedenheit spürbar beeinträchtigen.</p>



<p class="wp-block-paragraph">Die Eisenhower-Matrix verspricht an dieser Stelle eigentlich Orientierung, scheitert jedoch häufig an der psychologischen Realität der <em>Illusion of Urgency</em> [2]: Aufgaben fühlen sich dringend an, erzeugen Handlungsdruck und verlangen Aufmerksamkeit – ohne deshalb, um in der Sprache von Eisenhower zu bleiben, automatisch auch wichtig oder tatsächlich dringend zu sein.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<details class="wp-block-details foldable-info-box has-white-color has-text-color has-background has-link-color has-small-font-size wp-elements-090db9a5c012cbc984b9d9f6d5bb1d01 is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary><strong>Die Mär vom planvollen und reflektierten Manager</strong></summary>
<p class="wp-block-paragraph">Bereits in den 1970er Jahren hat Henry Mintzberg in seinen vielbeachteten Studien gezeigt, dass die Arbeit von Managern nur selten aus längeren, ungestörten Fokusphasen besteht. Stattdessen ist sie geprägt von vielen kurzen Aktivitäten, Unterbrechungen und spontanen Interaktionen. Entscheidungen entstehen dabei nicht sequenziell entlang klar priorisierter To-do-Listen, sondern situativ – eingebettet in Gespräche, Rückfragen und laufende Abstimmungen [3].</p>



<p class="wp-block-paragraph">Auch wenn sich die Arbeitswelt seitdem erheblich verändert hat, wirkt diese Beobachtung erstaunlich aktuell. Wissensarbeit ist heute eher noch stärker fragmentiert als zu Mintzbergs Zeiten. Digitale Kommunikationskanäle haben die Zahl der Kontaktpunkte erhöht und die Erwartung an schnelle Reaktionsfähigkeit weiter verschärft. Der Arbeitstag besteht für viele weniger aus geplantem Abarbeiten als aus permanentem Reagieren &#8211; und das bei bestem Willen nicht nur für Manager.</p>
</details>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e82273&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e82273" class="alignleft size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="572" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/01/image-3-1024x572.png" alt="" class="wp-image-8943" style="width:400px" srcset="https://atra.consulting/wp-content/uploads/2026/01/image-3-1024x572.png 1024w, https://atra.consulting/wp-content/uploads/2026/01/image-3-768x429.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Für mich hat sich daraus eine einfache, bewusst pragmatische Regel ergeben: Aufgaben, die sich in weniger als fünf Minuten erledigen lassen, versuche ich unmittelbar abzuschließen. Nicht aus Effizienzgründen im klassischen Sinne, sondern um kognitive Last zu reduzieren. Jede nicht beantwortete Rückfrage, jede angefangene, aber nicht abgeschlossene Kleinigkeit bleibt im Kopf präsent – und konkurriert dort mit eigentlich wichtigeren Themen um Aufmerksamkeit.</p>



<p class="wp-block-paragraph">Das Problem: In meinem hochfragmentierten Arbeitsalltag gibt es überraschend viele „kurze Anfragen“. Und so schlägt die Fünf-Minuten-Regel bei mir erstaunlich oft Eisenhower.</p>



<p class="wp-block-paragraph">Und ja, ich weiß: Man muss Mails und Chatnachrichten nicht sofort lesen. In der Theorie leuchtet mir das vollkommen ein. In der Praxis stressen mich 13 ungelesene Teams-Nachrichten jedoch zuverlässig. Disziplinierte Zeitfenster für Mail- und Chatkommunikation funktionieren für manche hervorragend. Für mich nicht. Und so stößt auch Eisenhower an seine Grenzen.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Kognitive Last der Organisation: Wenn zu viele Themen gleichzeitig offen sind</strong></h3>



<p class="wp-block-paragraph">Nun ist kognitive (Über-)Last kein individuelles Versagen. Sie ist in vielen Fällen ein übergreifendes organisatorisches Problem. Organisationen arbeiten selten an einem Thema zur gleichen Zeit. Sie arbeiten an sehr vielen. Projekte, Initiativen, Abstimmungen, Eskalationen, strategische Themen und operative Kleinigkeiten laufen parallel – oft über Monate oder sogar Jahre. Jeder offene Vorgang erzeugt kognitive Last. Nicht nur bei Einzelpersonen, sondern im System insgesamt: in Meetings, Statusrunden, Entscheidungsprozessen oder auch nur, weil ich diese eine nervige Aufgabe nun schon zum dritten Mal in die Folgewoche verschiebe.</p>



<p class="wp-block-paragraph">Diese systemische kognitive Last entsteht unabhängig davon, wie dringend oder wichtig ein einzelnes Thema gerade ist. Allein die Tatsache, dass etwas „noch offen“ ist, bindet Aufmerksamkeit. Ein psychologisches Fundament dieser Beobachtung liefert übrigens der Zeigarnik-Effekt, der besagt, dass uns unterbrochene, unerledigte Aufgaben kognitiv stärker beschäftigen als abgeschlossene [4]. Das kostet Energie – selbst dann, wenn faktisch gerade niemand daran arbeitet.</p>



<p class="wp-block-paragraph">Ein besonders plastisches Beispiel dafür habe ich im behördlichen Umfeld erlebt. Eine Broschüre sollte aktualisiert werden – kein besonders dringendes Thema, von mittlerer Wichtigkeit. Der erste Entwurf war schnell erstellt. Danach passierte lange Zeit: nichts. Aufgrund interner Prozesse mussten verschiedene Einheiten involviert werden, zwischen den einzelnen Abstimmungen lagen jeweils mehrere Wochen.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e830ee&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e830ee" class="alignright size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="572" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/01/image-2-1024x572.png" alt="" class="wp-image-8942" style="width:400px" srcset="https://atra.consulting/wp-content/uploads/2026/01/image-2-1024x572.png 1024w, https://atra.consulting/wp-content/uploads/2026/01/image-2-768x429.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Das Ergebnis? Ein Prozess über 20 Monate. Durch unzählige Abstimmungsrunden und Liegezeiten musste sich jeder Beteiligte in jedem Termin neu eindenken („Wo standen wir nochmal?“). Am Ende wurde konservativ geschätzt mindestens das Zehnfache der eigentlichen Arbeitszeit investiert, nur weil das Thema immer wieder liegen blieb. Ein klassisches Beispiel dafür, wie „nicht dringende“ Themen durch reinen Zeitverzug zu hocheffizienten Ressourcenfressern mutieren.</p>



<p class="wp-block-paragraph">Die Eisenhower-Matrix betrachtet Aufgaben isoliert. Sie hilft dabei, einzelne To-dos zu priorisieren. Was sie jedoch systematisch ausblendet, ist die kumulative Wirkung vieler paralleler, offener Themen auf eine Organisation.</p>



<p class="wp-block-paragraph">In der Praxis ist es oft nicht das einzelne wichtige oder dringende Thema, das überlastet – sondern die schiere Anzahl an offenen Baustellen. Aus einer Lean-Perspektive ist es deshalb sinnvoll, die Anzahl gleichzeitig offener Themen möglichst gering zu halten. Nicht nur, um schneller zu werden, sondern um arbeitsfähig zu bleiben.</p>



<p class="wp-block-paragraph">Genau hier beginnt ein Aspekt, den Eisenhower nur unzureichend adressiert: Offene Themen sind nicht neutral. Sie sind nicht einfach „noch nicht dran“. Sie erzeugen Kosten – allein durch ihr Liegenlassen.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Cost of Delay: Wenn Liegenlassen teuer wird</strong></h3>



<p class="wp-block-paragraph">Wenn man genau hinschaut, habe ich im obigen Behördenbeispiel bereits ein Konzept verwendet, ohne es zu benennen: Cost of Delay.</p>



<p class="wp-block-paragraph">Nicht die (gefühlte und meist sehr subjektive) Wichtigkeit einer Aufgabe entscheidet über ihre Priorität, sondern die Kosten, die entstehen, wenn sie nicht umgesetzt wird. Diese Kosten sind oft nicht sichtbar – aber sie sind real.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e83d9d&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e83d9d" class="alignleft size-full is-resized wp-lightbox-container"><img decoding="async" width="1024" height="559" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2026/01/image.png" alt="" class="wp-image-8940" style="width:400px" srcset="https://atra.consulting/wp-content/uploads/2026/01/image.png 1024w, https://atra.consulting/wp-content/uploads/2026/01/image-768x419.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Ein einfaches Beispiel: Ein kurzes Debriefing zu einem Konferenzbesuch an Kollegen zu schicken, ist selten dringend und meist auch nicht besonders wichtig. Während der Zugfahrt nach Hause ist das in wenigen Minuten erledigt. Zwei Wochen später brauche ich dafür schon deutlich länger. Zwei Monate später muss ich anhand meiner Notizen rekonstruieren, was ich eigentlich mitteilen wollte.</p>



<p class="wp-block-paragraph">Die Aufgabe ist dieselbe geblieben – der Aufwand nicht. Die Verzögerung hat hier keinen inhaltlichen Mehrwert erzeugt, sondern ausschließlich zusätzliche Arbeit. Genau das beschreibt Cost of Delay.</p>



<p class="wp-block-paragraph">In Organisationen wirkt dieser Effekt noch stärker. Der eigentliche Cost of Delay entsteht häufig nicht durch fehlende Umsetzung, sondern durch das Wiederanlaufen: sich erneut einlesen, Kontexte rekonstruieren, Entscheidungen erklären, Abhängigkeiten neu klären. Je länger ein Thema liegt, desto höher werden diese Reibungsverluste. Besonders schön wird es dann, wenn Nachfragen nach dem Stand einer Aufgabe und ein oder zwei Feedbackschleifen in Summe bereits mehr Zeit kosten als die eigentliche Erledigung.</p>



<p class="wp-block-paragraph">Eisenhower hilft dabei zu entscheiden, was wichtig und dringend ist. Cost of Delay macht sichtbar, was es kostet, nichts zu entscheiden – und Themen immer wieder liegen zu lassen.</p>



<p class="wp-block-paragraph">Mir ist bewusst, dass Cost of Delay ein abstrakter Begriff bleibt. Mir hilft dieser Perspektivwechsel jedoch sehr, meine Arbeitsprioritäten besser zu setzen. Übliche Dimensionen, die meinen höchst persönlichen Cost of Delay ausmachen, sind:</p>



<ul class="wp-block-list">
<li>der erwartete Mehrwert des Arbeitspakets (strategisch, operativ oder risikoseitig)</li>



<li>Effizienz- und Reibungsverluste über die Zeit (Wiederanlauf, Abstimmung, Kontextverlust)</li>



<li>die Möglichkeit, Themen sauber abzuschließen und damit kognitive Last zu reduzieren</li>



<li>Lernen und Wissensgewinn – oder dessen Verzögerung</li>
</ul>



<p class="wp-block-paragraph">Ob ich eine Aufgabe selbst erledige oder delegiere, beantwortet Cost of Delay allerdings nicht. Aber dazu kommen wir im kommenden Abschnitt.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Verteilte Verantwortung: Wenn klassische Delegation an Grenzen stößt</strong></h3>



<p class="wp-block-paragraph">Die Eisenhower-Matrix ist in einer Welt klarer Hierarchien entstanden. Aufgaben werden priorisiert, erledigt oder delegiert. Delegation setzt dabei etwas voraus, das lange selbstverständlich war: eine eindeutige hierarchische Ordnung mit klarer Weisungsbefugnis.</p>



<p class="wp-block-paragraph">In der Sprache von Reinventing Organizations [5] würde man sagen: Eisenhower passt hervorragend zu bernsteinfarbenen, stark hierarchischen Organisationen. Führung bedeutet dort, Entscheidungen zu treffen und Aufgaben weiterzugeben.</p>



<p class="wp-block-paragraph">Viele Organisationen funktionieren heute jedoch anders. Wir sprechen über flache Hierarchien, selbstorganisierte Teams, laterale Führung und Servant Leadership. Verantwortung liegt nicht mehr ausschließlich bei einzelnen Rollen, sondern verteilt sich auf Teams. Entscheidungen werden gemeinsam getroffen, Aufgaben gemeinsam getragen.</p>



<p class="wp-block-paragraph">In solchen Strukturen wird Delegation unscharf. An wen delegiere ich, wenn Verantwortung im Team liegt? Was bedeutet „abgeben“, wenn ich fachlich gar nicht weisungsbefugt bin? Und was passiert, wenn Delegation nicht als Entlastung, sondern als Abschieben wahrgenommen wird?</p>



<p class="wp-block-paragraph">Gleichzeitig verstehen sich viele Organisationen zunehmend als lernende Systeme. Aufgaben sind nicht nur Mittel zur Zielerreichung, sondern auch Gelegenheiten zur Entwicklung. Konzepte wie Management 3.0 [6] betonen genau diesen Aspekt: Arbeit dient nicht nur der Effizienz, sondern auch dem Lernen, der Motivation und dem Kompetenzaufbau von Mitarbeitern.</p>



<p class="wp-block-paragraph">Damit wird Delegation zu einer Führungsentscheidung mit mehreren Dimensionen. Nicht jede Aufgabe, die delegierbar wäre, sollte delegiert werden. Und nicht jede Aufgabe, die belastet, lässt sich sinnvoll abgeben. Eisenhower gibt darauf keine Antworten – weil er diese Organisationslogik schlicht nicht kennt.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Fazit: Eisenhower reicht nicht mehr – aber er bleibt hilfreich</strong></h3>



<p class="wp-block-paragraph">Die Eisenhower-Matrix ist kein schlechtes Werkzeug. Sie hilft, innezuhalten, Aufgaben bewusst zu betrachten und sich nicht von jeder Dringlichkeit treiben zu lassen. Das allein ist viel wert.</p>



<p class="wp-block-paragraph">In meinem Arbeitsalltag reicht sie jedoch nicht mehr aus. Kognitive Überlastung, systemische Reibung, Cost of Delay und veränderte Organisationsformen lassen sich nicht sauber in vier Quadranten pressen. Dafür sind moderne Wissensorganisationen zu komplex – und Arbeit zu stark von Kontext, Abhängigkeiten und Lernen geprägt.</p>



<p class="wp-block-paragraph">Was mir heute hilft, ist kein Ersatz für Eisenhower, sondern eine Ergänzung: der bewusste Blick auf Liegezeiten, auf kognitive Last – und auf die Frage, was es mich und die Organisation kostet, Dinge nicht zu entscheiden.</p>



<p class="wp-block-paragraph">Eisenhower hilft mir weiterhin bei der Orientierung. Die eigentliche Priorisierung entsteht jedoch erst im Zusammenspiel aus Kontext, Verantwortung und Cost of Delay. Am Ende bleibt die Erkenntnis: Ein Werkzeug ist eben nur ein Werkzeug. Mit einem Hammer lässt sich vieles erledigen – aber nicht alles im modernen Arbeitsalltag ist ein Nagel.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><strong>Referenzen</strong></h4>



<p class="wp-block-paragraph">[1] Multitasking: Switching Costs &#8211; <a href="https://www.apa.org/topics/research/multitasking" target="_blank" rel="noopener">https://www.apa.org/topics/research/multitasking</a>&nbsp;<br>[2] The Illusion of Urgency &#8211;&nbsp; <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC10159458/" target="_blank" rel="noopener">https://pmc.ncbi.nlm.nih.gov/articles/PMC10159458/</a>&nbsp;<br>[3] Mintzberg, H. (1973). The nature of managerial work.<br>[4] Zeigarnik-Effekt &#8211; <a href="https://de.wikipedia.org/wiki/Zeigarnik-Effekt" target="_blank" rel="noopener">https://de.wikipedia.org/wiki/Zeigarnik-Effekt</a>&nbsp;<br>[5] Reinventing Organisations &#8211; <a href="https://www.reinventingorganizations.com/" target="_blank" rel="noopener">https://www.reinventingorganizations.com/</a>&nbsp;<br>[6] Management 3.0 &#8211; <a href="https://management30.com/" target="_blank" rel="noopener">https://management30.com/</a>&nbsp;</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-full"><img decoding="async" width="425" height="425" src="https://atra.consulting/wp-content/uploads/2025/01/profilbild-daniel-wochnik-500-x-500px.jpg" alt="Daniel Wochnik, Geschäftsbereichsleitung Finanzdienstleistungen" class="wp-image-3216" style="object-fit:cover" title="Team-Schwarze"/></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Daniel Wochnik</h3>



<p class="wp-block-paragraph">Geschäftsbereichsleitung »Finanzdienstleistungen«</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Daniel ist seit 2017 in der IT-Branche aktiv und bringt seine umfassende Erfahrung als Senior Managing Consultant und Geschäftsbereichsleiter für Finanzdienstleistungen bei atra.consulting ein. Besonders begeistert ihn das Zusammenspiel technischer, methodischer und organisatorischer Aspekte. Als leidenschaftlicher Läufer und bekennender 1. FC Köln-Fan hat er seine Leidensfähigkeit auch privat mehrfach unter Beweis gestellt. Seine Kunden unterstützt er als Softwarearchitekt, agiler Coach und Berater bei der nachhaltigen und zielgerichteten Umsetzung von Entwicklungsprojekten.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:d.wochnik@atra.consulting">d.wochnik@atra.consulting</a>&nbsp; &nbsp;&nbsp;<a href="https://de.linkedin.com/in/daniel-wochnik" target="_blank" rel="noreferrer noopener"></a></p>



<ul class="wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a href="https://de.linkedin.com/in/daniel-wochnik" class="wp-block-social-link-anchor" target="_blank" rel="noopener"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li></ul>
</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>c&#8217;t webdev conference 2025</title>
		<link>https://atra.consulting/engineering/ct-webdev-conference-2025/</link>
		
		<dc:creator><![CDATA[Timo Kaiser]]></dc:creator>
		<pubDate>Fri, 19 Dec 2025 10:51:58 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Consulting]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=8918</guid>

					<description><![CDATA[Zwei Tage voller Frontend-Tiefgang in Köln Die Webentwicklung verändert sich rasant – aktuell vor allem durch neue Frontend-Paradigmen und den zunehmenden Einsatz von AI-gestütztem Coding. Genau deshalb war die c’t webdev conference Mitte November im KOMED im MediaPark in Köln für mich mehr als nur ein Pflichttermin. Zwei Tage lang trafen sich dort Frontend-Entwickler:innen, die [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Zwei Tage voller Frontend-Tiefgang in Köln</h2>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p class="wp-block-paragraph">Die Webentwicklung verändert sich rasant – aktuell vor allem durch neue Frontend-Paradigmen und den zunehmenden Einsatz von AI-gestütztem Coding. Genau deshalb war die <strong>c’t webdev conference</strong> Mitte November im <strong>KOMED im MediaPark in Köln</strong> für mich mehr als nur ein Pflichttermin.</p>



<p class="wp-block-paragraph">Zwei Tage lang trafen sich dort Frontend-Entwickler:innen, die sich intensiv mit Themen wie UI/UX, modernen JavaScript-Frameworks und neuen Ansätzen wie Vibe Coding und AI Agents beschäftigten. Der klare fachliche Fokus, die Tiefe der Vorträge und der direkte Austausch auf Augenhöhe machten schnell klar: Die Konferenz richtet sich nicht an Neugierige, sondern an echte<strong> </strong>Praktiker:innen. Die Organisation war top und das Catering im KOMED hervorragend – ideale Voraussetzungen für konzentriertes Networking und Lernen.</p>



<p class="wp-block-paragraph">Doch was die c&#8217;t webdev wirklich auszeichnet, war die spezifische Zielgruppe: Es handelte sich um eine klare Frontend-Konferenz. Das Publikum war tief in den Themen UI/UX, Coding mit AI Agents, Vibe Coding und den aktuellen JavaScript-Frameworks (React, Angular, Vue) verwurzelt. Hier traf man auf gleichgesinnte Frauen und Männer, die nicht nur auf der Suche nach Inspiration waren, sondern auch den tiefen fachlichen Austausch suchten. Der <em>Vibe</em> stimmte sofort, was eine ideale Basis für die kommenden Vorträge legte.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"><div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e893fc&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e893fc" class="aligncenter size-large wp-lightbox-container"><img decoding="async" width="820" height="1024" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/12/image-1-820x1024.png" alt="" class="wp-image-8920" srcset="https://atra.consulting/wp-content/uploads/2025/12/image-1-820x1024.png 820w, https://atra.consulting/wp-content/uploads/2025/12/image-1-768x959.png 768w" sizes="(max-width: 820px) 100vw, 820px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div></div>
</div>



<h2 class="wp-block-heading">Tag 1: Über AI Autopilots, Architektur und granularem State-Management</h2>



<h3 class="wp-block-heading">Keynote: Von Copilot zu Autopilot</h3>



<p class="wp-block-paragraph">Der Tag begann mit einer fesselnden Keynote von Daniel Sogl, der uns mitnahm auf die Reise <strong>&#8222;From Copilot to Autopilot – How AI Coding Tools Are Transforming the Developer Role&#8220;</strong>. Der Vortrag war mehr als eine Bestandsaufnahme; er war eine Aufforderung, die neue Realität kritisch zu hinterfragen.</p>



<p class="wp-block-paragraph">Sogl präsentierte eindrucksvolle Statistiken zur Adoption von AI-Tools, wobei 84 % der Entwickler sie bereits nutzen oder planen zu nutzen, und 51 % sie täglich verwenden. Diese Tools versprechen echte Produktivitätssteigerungen, wie z. B. eine um 55,8 % schnellere Aufgabenerledigung in kontrollierten Studien und eine Reduzierung der täglichen Arbeitszeit um 56 Minuten.</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p class="wp-block-paragraph">Der zentrale Weckruf kam mit dem <strong>Trust Paradox</strong>: Während Syntax-Fehler dank AI um bis zu 76 % reduziert werden, steigt das Risiko für tiefer liegende, architektonische Probleme signifikant an. Berechtigungsprobleme<strong> (+322 %) und </strong>Architekturmängel<strong> (+153 %)</strong> sind laut Sogl keine Seltenheit. Diese Zahlen haben mich am meisten überrascht und bestätigen meine Skepsis: AI erzeugt &#8222;saubereren&#8220; Code, verleitet aber zur Vernachlässigung der architektonischen Kontrolle.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"><div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e8a0fc&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e8a0fc" class="alignright size-large wp-lightbox-container"><img decoding="async" width="1024" height="576" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/12/image-2-1024x576.png" alt="" class="wp-image-8924" style="object-fit:cover" srcset="https://atra.consulting/wp-content/uploads/2025/12/image-2-1024x576.png 1024w, https://atra.consulting/wp-content/uploads/2025/12/image-2-768x432.png 768w, https://atra.consulting/wp-content/uploads/2025/12/image-2-780x440.png 780w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div></div>
</div>



<p class="wp-block-paragraph">Die Quintessenz des Vortrags: Die Entwicklerrolle wandelt sich vom reinen<strong> </strong>Coder<strong> </strong>zum<strong> </strong>Orchestrator und Strategen. Die Zukunft liegt in der <strong>Spec-Driven Development (SDD)</strong>, bei der wir die Spezifikationen klar vorgeben, bevor die AI den Code generiert. Genau hier liegt für mich eine der großen Herausforderungen der nächsten Jahre: Wir müssen uns stärker als je zuvor auf die architektonische Planung und saubere Anforderungsanalyse konzentrieren, um die AI als präzises Werkzeug zu führen, statt uns von ihren zufälligen &#8218;Vibes&#8216; treiben zu lassen.</p>



<p class="wp-block-paragraph">​</p>



<h3 class="wp-block-heading">Das Highlight von Tag 1: Signals in Depth</h3>



<p class="wp-block-paragraph">Nach der strategischen Keynote, die den Rahmen für die Zukunft der Entwicklerrolle setzte, tauchten wir am späten Vormittag tief in die Frontend-Architektur ein. Mein persönliches Highlight von Tag 1 war ein Vortrag, der zeigte, wie die modernen Frameworks das Kernproblem der Webentwicklung – die Reaktivität – endlich effizient lösen: <strong>&#8222;Signals in Depth – How reactivity works in many frontend frameworks&#8220;</strong> von Garrelt Mock.</p>



<p class="wp-block-paragraph">Mock erklärte anschaulich die Schwächen traditioneller Reaktivitätsansätze: das &#8222;Dirty Checking&#8220; (bekannt aus älteren Angular-Versionen mittels Zone.js) und das Virtual DOM (VDOM) Diffing in React. Diese Methoden, obwohl funktional, verursachen oft Performance-Overhead und unnötige Rechenzyklen, da unnötig große Teile der Komponenten neu gerendert werden, selbst wenn sich nur ein kleiner Datenpunkt geändert hat.</p>



<p class="wp-block-paragraph">Die Lösung liegt in <strong>Signals</strong>, die auf einem granularen Observer-Pattern basieren: Ein Signal weiß genau, welche UI-Teile oder Effekte von ihm abhängen. Bei einer Änderung wird nur dieser spezifische abhängige <em>Effect</em> aktualisiert, nicht die gesamte Komponente.</p>



<p class="wp-block-paragraph">Für mich war dieser Vortrag die wichtigste technische Erkenntnis des Tages. Die Eleganz und Effizienz, mit der Signals die Notwendigkeit für komplexe Mechanismen wie Zone.js oder VDOM-Diffing eliminieren und Frameworks wie SolidJS, Preact und das neue Angular schneller und speichereffizienter machen, ist ein klarer Hinweis auf einen Paradigmenwechsel im State-Management. Die Frontend-Architektur wird sich dadurch grundlegend vereinfachen – ein Muss für jede skalierbare Anwendung in den kommenden Jahren.</p>



<h3 class="wp-block-heading">Der Rest des ersten Tages: Von AI-Agents bis zur Frontend-Architektur</h3>



<p class="wp-block-paragraph">Neben Keynote und Signal-Tiefgang bot der erste Konferenztag eine spannende Bandbreite an Themen, die die aktuellen Herausforderungen und Trends in der Frontend-Welt widerspiegelten.</p>



<p class="wp-block-paragraph"><strong>AI-Driven Development:</strong> Sebastian Springer beleuchtete in seiner Session &#8222;AI Agents Beyond Simple Chatbots&#8220; die Entwicklung komplexer, autonomer AI-Lösungen und proaktiver Assistentensysteme, die weit über einfache LLM-Chat-Interfaces hinausgehen. Er zeigte Frameworks wie LangChain, mit denen man AI-Agents befähigen kann, reale Probleme zu lösen und mehrstufige Workflows zu automatisieren.</p>



<p class="wp-block-paragraph"><strong>Architektur und Skalierung:</strong> Der Vercel-Partner-Talk &#8222;From Monolith to Microfrontends: Choosing the Right Architecture&#8230;&#8220; von Yi Min Yang lieferte einen praktischen Leitfaden zu modernen Frontend-Architektur-Patterns. Er diskutierte alles von Monorepos (z.B. mit Turborepo) bis Microfrontends und präsentierte ein klares Entscheidungs-Framework, um die passende Architektur für Teamgröße und technische Anforderungen zu finden. Sehr interessant zu sehen, wie man auch step-by-step Architekturen modernisieren kann.</p>



<p class="wp-block-paragraph"><strong>Qualität und Metriken: </strong>Richard Gross erklärte unter dem Titel &#8222;Making sense of frontend code with forensic techniques&#8220;, wie man mithilfe von Tools wie CodeCharta und CodeGraph die Code-Qualität und Architektur in Projekten mit hunderttausenden Zeilen analysiert. Darüber hinaus zeigte Eva Feigl in &#8222;Beyond clicks: Measuring UX, outcomes and real product success&#8220; auf, wie man Produkt-Telemetrie und qualitative Nutzerforschung kombiniert, um wirklich verwertbare UX-Metriken zu erhalten und den Produkterfolg zu validieren.</p>



<h2 class="wp-block-heading">Tag 2: Menschliche Empathie und AI-Strenge&nbsp;</h2>



<h3 class="wp-block-heading">Keynote: Nobody needs UX – Die Unverzichtbarkeit der Empathie</h3>



<p class="wp-block-paragraph">Der zweite Konferenztag begann mit einer provokanten und nachdenklich stimmenden Keynote von Vicky Pirker mit dem Titel <strong>&#8222;Nobody needs UX&#8220;</strong>.</p>



<p class="wp-block-paragraph">Pirker nutzte diesen vermeintlich paradoxen Titel, um die Essenz von User Experience (UX) in Zeiten der schnellen AI-Entwicklung neu zu definieren: Es braucht nicht den Begriff UX, sondern die menschliche Haltung dahinter. Schlechte UX führt zu Frustration und Ablehnung, wie sie eindrücklich zeigte.</p>



<p class="wp-block-paragraph">Besonders relevant war die Diskussion im Kontext der AI-Revolution. Ihre klare Schlussfolgerung: User Experience bleibt menschzentriert, und KI dient lediglich als unser Sidekick. Die Aufgabe der Entwickler und Designer ist es, die Vision zu formen und die Nutzer zu begeistern.</p>



<p class="wp-block-paragraph">Für mich war der Fokus auf die Empathie der wichtigste Takeaway. Während KI gut darin ist, bekannte UX-Schemata und Design-Regeln zu erlernen und perfekt umzusetzen, bleibt die Fähigkeit, sich tief in den User hineinzufühlen – also die Wünsche und emotionalen Reaktionen vorherzusehen – eine zutiefst menschliche Leistung. Dieser Mangel an Empathie kann aber zum Problem werden, wenn KI versucht, UX komplett zu übernehmen. Daher muss die menschliche Perspektive, die qualitative Nutzerforschung und Empathie stets die letzte Kontrollinstanz bleiben.</p>



<h3 class="wp-block-heading"><strong>Das Highlight von Tag 2: EXACT Coding gegen den &#8222;Vibe&#8220;</strong></h3>



<p class="wp-block-paragraph">Die Keynote von Vicky Pirker stellte klar: Der Mensch muss die ethische und empathische Kontrolle behalten. Der darauf folgende Vortrag <strong>&#8222;AI-Powered Development Vibe Code Doesn’t Work!&#8220;</strong> von Marco Emrich und Ferdinand Ade lieferte die technische Methodik dazu. Sie äußerten eine klare Kritik am unstrukturierten &#8222;Vibe Coding&#8220; (generieren, akzeptieren, nicht prüfen) und belegten, dass dieser Ansatz – obwohl schnell – zu unsauberen und unsicheren Codebasen führt.</p>



<p class="wp-block-paragraph">Ich sehe Vibe Coding als einen effizienten Weg für schnelles Prototyping und Proof-of-Concepts; man erhält in kürzester Zeit gute, lauffähige Ergebnisse<em>.</em> Doch für Production-Ready Code ist dieser Ansatz meiner Meinung nach untauglich.</p>



<p class="wp-block-paragraph">Die Lösung der Sprecher war EXACT Coding, ein Ansatz, der die besten Seiten der AI mit der Disziplin etablierter Methoden kombiniert. EXACT Coding basiert auf <strong>EXample-Guided Ai-CollaboraTive</strong>.</p>



<p class="wp-block-paragraph">Das ist die Essenz für professionelle Softwareentwicklung: Bevor die AI überhaupt mit dem Codieren beginnt, müssen wir als Software Engineers in unseren Teams die Anforderungen und Spezifikationen klar erfassen und visualisieren. Der Mensch (Human-in-the-Loop) definiert das &#8222;Was&#8220; durch die Beispiele und Tests; die AI übernimmt die Implementierung.</p>



<p class="wp-block-paragraph">Der größte Vorteil dieser Methodik ist die Qualitätssicherung der Architektur: Indem wir uns zuerst auf Spezifikationen und die &#8222;Red&#8220;-Phase des TDD-Zyklus konzentrieren, zwingen wir die KI, in einem engen, validierten Rahmen zu arbeiten. Das beugt nicht nur Syntaxfehlern vor, sondern verhindert auch das Auseinanderdriften von Code und Gesamtarchitektur. Nur so stellen wir sicher, dass wir nicht nur Code schreiben, sondern nachhaltige, wartbare Software entwickeln und dabei niemals das große Ganze aus dem Auge verlieren.</p>



<h3 class="wp-block-heading"><strong>Weitere Highlights an Tag 2: Reaktivität, Testing und Agenten-Interfaces</strong></h3>



<p class="wp-block-paragraph">Auch abseits der Keynote und des AI-Vortrags lieferte Tag 2 wertvolle Inhalte, die sich tief mit den technischen Details der modernen Frontend-Entwicklung beschäftigten:</p>



<p class="wp-block-paragraph"><strong>Standardisierung von AI-Interfaces:</strong> Max Marschall stellte in seinem Vortrag &#8222;AG-UI &amp; MCP: Standardizing Agentic Web Interfaces&#8220; zwei neue Protokolle vor: AG-UI (Agent-User Interaction Protocol) und MCP (Model Context Protocol). Diese zielen darauf ab, die Interaktion zwischen intelligenten Agents und modernen Web-Frontends zu standardisieren und modularer, testbarer und verständlicher zu gestalten.</p>



<p class="wp-block-paragraph"><strong>Test-Qualität:</strong> Marco Emrich leitete die interaktive Session &#8222;How valuable are your tests?&#8220;. Er präsentierte die &#8222;Four Pillars of a Good Test&#8220; von Vladimir Khorikov, um Kriterien für eine objektive Bewertung des Nutzens von Tests zu schaffen und so eine fundierte Diskussion über Teststrategien zu ermöglichen.</p>



<p class="wp-block-paragraph"><strong>Accessibility in Komponenten:</strong> Und natürlich das beinahe-Highlight &#8222;Accessible Web Components&#8220; von Anna Maier. Sie lieferte einen wichtigen Einblick, wie man technische Fallstricke des Shadow DOM vermeidet, um die Barrierefreiheit von Komponenten von Anfang an zu gewährleisten, und betonte die Notwendigkeit, dies auch im Produktkontext zu testen und zu dokumentieren.</p>



<h2 class="wp-block-heading"><strong>Fazit: Eine lohnende Investition in die Frontend-Zukunft</strong></h2>



<p class="wp-block-paragraph">Die zwei Tage auf der <strong>c&#8217;t webdev conference</strong> im Kölner MediaPark waren für mich eine absolut lohnende Investition. Die Konferenz lieferte nicht nur einen umfassenden Überblick über die aktuellen Tools und Frameworks (von Signals bis React Fullstack), sondern beleuchtete vor allem die strategischen und methodischen Herausforderungen der Branche. Der Fokus lag klar auf der Zukunft der Entwicklerrolle: Wir bewegen uns vom reinen Code-Schreiber hin zum Orchestrator, der AI strukturiert einsetzt und dabei die menschliche Urteilsfähigkeit (Human Judgement) behält.</p>



<h3 class="wp-block-heading"><strong>Die wichtigste Erkenntnis: Der Mensch bleibt die Kontrollinstanz</strong></h3>



<p class="wp-block-paragraph">Die entscheidenden Takeaways liegen für mich in der methodischen Disziplin und Empathie. Wir haben gelernt, dass wir AI nicht blind vertrauen dürfen (Stichwort: Trust Paradox bei Architekturmängeln), sondern dass unser menschliches Urteilsvermögen und die Fähigkeit zur Empathie die unverzichtbaren Kontrollinstanzen bleiben.</p>



<h3 class="wp-block-heading"><strong>Networking und Empfehlung</strong></h3>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p class="wp-block-paragraph">Abgesehen vom Inhalt war die Atmosphäre auf der Konferenz herausragend. Die Teilnehmer:innen waren sehr freundlich und offen für einen fachlichen Austausch, was das Networking sehr erleichtert hat.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e8b658&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e8b658" class="wp-block-image size-large wp-lightbox-container"><img decoding="async" width="1024" height="520" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/12/image-3-1024x520.png" alt="" class="wp-image-8926" srcset="https://atra.consulting/wp-content/uploads/2025/12/image-3-1024x520.png 1024w, https://atra.consulting/wp-content/uploads/2025/12/image-3-768x390.png 768w, https://atra.consulting/wp-content/uploads/2025/12/image-3-417x212.png 417w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>
</div>



<p class="wp-block-paragraph">Ich kann die c&#8217;t webdev conference definitiv uneingeschränkt weiterempfehlen, da sie wertvolle Beiträge und tiefgreifende Infos aus der Tech-Branche im Bereich Frontend liefert. Die Konferenz richtet sich an diejenigen, die wissen wollen, wie man die Zukunft baut, nicht nur, wie man sie benutzt. Ob ich im nächsten Jahr wieder dabei bin, steht noch offen – schließlich soll man als Entwickler auch mal über den Tellerrand hinausschauen. Aber die Impulse aus Köln sind gesetzt und werden meine Arbeit nachhaltig prägen.</p>



<div style="height:80px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-full"><img decoding="async" width="800" height="800" src="https://atra.consulting/wp-content/uploads/2025/03/TK-Profile-e1741870954239.jpeg" alt="" class="wp-image-5208" srcset="https://atra.consulting/wp-content/uploads/2025/03/TK-Profile-e1741870954239.jpeg 800w, https://atra.consulting/wp-content/uploads/2025/03/TK-Profile-e1741870954239-768x768.jpeg 768w" sizes="(max-width: 800px) 100vw, 800px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Timo Kaiser</h3>



<p class="wp-block-paragraph">Senior Software Engineer</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph"><strong>Timo </strong>ist ein erfahrener Webentwickler mit über 15 Jahren Projekterfahrung, insbesondere in der Umsetzung moderner, barrierefreier Frontends auf Basis von Angular, TypeScript, HTML und SCSS. Sein Schwerpunkt liegt auf der Entwicklung skalierbarer, wartbarer und zugänglicher Webanwendungen<strong>.</strong></p>



<p class="wp-block-paragraph">Als Lead Developer verantwortet er in Projekten die technische Umsetzung, Architekturentscheidungen sowie die kontinuierliche Optimierung der User Experience. Timo ist Ansprechpartner für technische und methodische Fragen, übersetzt Anforderungen in strukturierte Sprints und Git-Workflows und sorgt durch Code-Reviews, Pairing und Coaching für hohe Qualität und Effizienz im Team. Er arbeitet eng mit Design- und UX-Teams zusammen und bringt seine gestalterische Erfahrung auch in Tools wie Figma oder Adobe XD ein.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:t.kaiser@atra.consulting">t.kaiser@atra.consulting</a>    <a href="https://de.linkedin.com/in/daniel-wochnik" target="_blank" rel="noreferrer noopener"></a></p>



<ul class="wp-block-social-links hidden is-layout-flex wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a href="https://www.linkedin.com/in/timo-kaiser-6a24b5130/" class="wp-block-social-link-anchor" target="_blank" rel="noopener"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li></ul>
</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ISAQB SAG 2025</title>
		<link>https://atra.consulting/engineering/isaqb-sag-2025/</link>
		
		<dc:creator><![CDATA[Daniel Wochnik]]></dc:creator>
		<pubDate>Mon, 15 Dec 2025 10:45:38 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Consulting]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=8913</guid>

					<description><![CDATA[Es gibt einige Konferenzen, die wir gewöhnlich besuchen. Eine davon ist das ISAQB Software Architecture Gathering (SAG), das traditionell im November im H4 Hotel in Berlin stattfindet – so auch in diesem Jahr, vom 24. bis zum 27. November. Als technologieagnostische Konferenz bietet das SAG weniger Deep Dives, dafür aber einen breit gefächerten und gut [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Es gibt einige Konferenzen, die wir gewöhnlich besuchen. Eine davon ist das ISAQB Software Architecture Gathering (SAG), das traditionell im November im H4 Hotel in Berlin stattfindet – so auch in diesem Jahr, vom 24. bis zum 27. November.</p>



<p class="wp-block-paragraph">Als technologieagnostische Konferenz bietet das SAG weniger Deep Dives, dafür aber einen breit gefächerten und gut zugänglichen Überblick über den aktuellen „Architektur-Mainstream“ in Deutschland. Man trifft viele bekannte Gesichter und das Programm ist üblicherweise mit namhaften nationalen wie internationalen Sprecherinnen und Sprechern besetzt. In diesem Jahr etwa mit Bernd Ruecker (Co-Founder Camunda, mit – Überraschung – einem halben, aber sehr sympathischen Werbevortrag), Cheryl Hung (ehem. CNCF), Alistair Cockburn (Mitautor des Agilen Manifests) oder Gregor Hohpe (dessen launisch-meinungsstarke Vorträge ich seit jeher mag).</p>



<p class="wp-block-paragraph">Der Nachteil dieser breiten und bewusst agnostischen Ausrichtung liegt allerdings auf der Hand: Viele Themen bleiben eher an der Oberfläche. Auch in diesem Jahr gab es ausschließlich Talks der Kategorien „Beginner“ und „Intermediate“ – wirklich neue Erkenntnisse sind dementsprechend selten.</p>



<p class="wp-block-paragraph">Wir waren dennoch vor Ort – und möchten im Folgenden ein paar Eindrücke teilen.</p>



<h3 class="wp-block-heading"><br><strong>Themenlandschaft: weniger AI-Dominanz als erwartet</strong></h3>



<p class="wp-block-paragraph">Ein Blick auf die Agenda brachte die erste Überraschung. Trotz ordentlicher Präsenz war AI nicht erdrückend dominant – für eine Architekturkonferenz zur aktuellen Zeit fast wohltuend. „Nur“ ungefähr jeder sechste Talk drehte sich explizit um die Themen AI, wobei natürlich sehr viele Sessions das Thema zumindest gestreift haben. Im Sprachgebrauch des Gartner Hype Cycle sind wir nun wohl endgültig über den Peak of Inflated Expectations hinaus und arbeiten uns langsam, aber sicher, hin zu wirklichen und nachhaltigen Use Cases.</p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e90972&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e90972" class="aligncenter size-large wp-lightbox-container"><img decoding="async" width="1024" height="564" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/12/image-1024x564.png" alt="" class="wp-image-8914" srcset="https://atra.consulting/wp-content/uploads/2025/12/image-1024x564.png 1024w, https://atra.consulting/wp-content/uploads/2025/12/image-768x423.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Statt GenAI waren sozio-technologische Fragestellungen oder auch der Dauerbrenner DDD in diesem Jahr wieder deutlich präsenter.</p>



<p class="wp-block-paragraph">Auch Green IT, ein Thema, von dem ich mir vor drei bis vier Jahren eine dauerhafte Etablierung erhofft hatte und das spätestens vom energieverschlingenden GenAI-Hype ein wenig in den Hintergrund gedrängt worden ist, war (für mich) überraschend präsent. Letzteres mag damit zu tun haben, dass das iSAQB seit vergangenen Jahr ein neues Modul „Green IT“ in seiner Advanced-Zertifizierung anbietet [1].</p>



<h3 class="wp-block-heading"><br><strong>Vibe Coding, Verantwortung und Plattformarchitektur</strong></h3>



<p class="wp-block-paragraph">Unter den Vorträgen ist mir der Talk „Vibe Coding Auth Without Melting Down!“ von Cheryl Hung besonders in Erinnerung geblieben [2]. Er ging der Frage nach, ob sich auch fehlerintolerante Bereiche wie Authentifizierung mittels Vibe Coding lösen lassen. Die Antwort: It depends. In ihrem Beispiel zeigte sie eine mit Claude Code generierte Authentifizierungslösung, die funktional war, aber typische handwerkliche Anfängerfehler enthielt – etwa die Verwendung veralteter Hash-Bibliotheken oder das unbeabsichtigte Leaken von Nutzerinformationen [3]. Das deckt sich sehr mit meinen eigenen Erfahrungen: Vibe Coding liefert einen erstaunlich brauchbaren, aber eben nicht fehlerfreien Ausgangspunkt [4].</p>



<p class="wp-block-paragraph">Spannend war allerdings weniger der Code selbst, sondern Cheryls Vorgehen: Sie hat die Sicherheitslücken nicht eigenhändig gesucht, sondern Claude Code im einmal generierten Code gezielt nach Schwachstellen analysieren lassen – eine Vorgehensweise, die in der Praxis zunehmend eingesetzt wird [5]. Einerseits nicht unerwartet, andererseits irgendwie faszinierend – das LLM „weiß“ grundsätzlich von diesen Schwachstellen, muss aber erst in die richtige Richtung geleitet werden.</p>



<p class="wp-block-paragraph">Damit bleibt Vibe Coding für mich auf einem Niveau, das signifikante Geschwindigkeitsvorteile ermöglicht – solange man den Leitsatz beachtet: Never vibe code an app you wouldn’t be able to code yourself. Ob das im Startup-Kontext immer beherzigt wird? We will see…</p>



<p class="wp-block-paragraph">Als möglichen Lösungsansatz griff Cheryl das Konzept Shift Down Security auf. Während Shift Left als etabliertes Prinzip die frühzeitige Verlagerung von Verantwortung – etwa für Qualität, Tests, Sicherheit oder Architektur – in die Entwicklungsteams und in die frühe Phase des Entwicklungsprozesses beschreibt, setzt Shift Down an einer anderen Stelle an: Statt Verantwortung weiter nach vorne zu schieben, wird sie bewusst nach unten, also auf Plattform- und Infrastruktur-Level, verlagert [6][7].</p>



<p class="wp-block-paragraph">Dort werden Sicherheitsmechanismen technisch und organisatorisch verankert – etwa durch vordefinierte, abgesicherte Base Images, verpflichtende Policies, vorstrukturierte Toolchains oder Plattform-Guardrails, die bestimmte Fehler (menschliche wie maschinelle) gar nicht erst zulassen. Dieser Gedanke deckt sich stark mit dem Prinzip sogenannter Enabling Constraints: Bedingungen, die nicht einschränken, sondern Qualität und Sicherheit gezielt ermöglichen [8].</p>



<p class="wp-block-paragraph">Ein Konzept, das sowohl menschlichen als auch KI-basierten Entwicklerwerkzeugen hilft, typische Fehler gar nicht erst entstehen zu lassen. Und noch dazu ein netter Querverweis zum Talk von Michael Mahlberg war, in welchem Enabling Constraints eine wichtige Rolle einnehmen [9].</p>



<p class="wp-block-paragraph">Der Übergang von Vibe Coding zu Shift Down war für meinen Geschmack etwas abrupt, zumal die gezeigten Authentifizierungsfehler kaum über Plattformmechanismen lösbar gewesen wären. Trotzdem ein sehr gelungener Talk mit einem prägnanten Beispiel sowie einem für mich neuen und interessanten Konzept.</p>



<h3 class="wp-block-heading"><br><strong>Hexagons, Ports &amp; Adapter</strong></h3>



<p class="wp-block-paragraph">Auch der Vortrag von Alistair Cockburn zur hexagonalen Architektur [10] – laut ihm selbst eine der drei schlimmsten Benennungen von Architekturkonzepten überhaupt – war eine der Sessions, die gleichzeitig unterhaltsam, temporeich und technisch fundiert waren. Zum einen ist es schlicht faszinierend, den Urheber eines Architekturstils über Historie, Motivation und ursprüngliches Designziel sprechen zu hören. Zum anderen hat Alistair den Vortrag sehr geschickt mit konkreten Implementationsbeispielen aus unterschiedlichen Sprachen kombiniert.</p>



<p class="wp-block-paragraph">Allein das Tempo machte den Talk für mich zum anspruchsvollsten Vortrag, den ich die Tage gehört habe – und damit zur willkommenen Abwechslung zu den insgesamt sehr gut gemachten, aber oft sehr einsteigerorientierten Sessions. Ein einzelnes fachliches Learning würde ich rückblickend gar nicht herausgreifen. Stattdessen hat sich mein Eindruck bestätigt, dass Port-&amp;-Adapter-Architekturen zu den Stilformen gehören, mit denen sich jede Entwicklerin und jeder Architekt ernsthaft beschäftigt haben sollte (und spätestens dann versteht, wie ich von Hexagons zu Ports &amp; Adaptern komme).</p>



<h3 class="wp-block-heading"><br><strong>Fazit: Vor allem eine gute Orientierung</strong></h3>



<p class="wp-block-paragraph">Was bleibt für mich am Ende vom SAG? Am Ende war es inhaltlich zumeist nicht revolutionär, aber durchaus wertvoll. AI war präsent, DDD sowieso – und manche Konzepte wirken erstaunlich robust gegenüber Hype-Zyklen. Vielleicht ist genau das der eigentliche Reiz des SAG: Man nimmt selten ein einzelnes atemberaubendes Konzept mit nach Hause, aber jedes Jahr ein etwas klareres Verständnis davon, warum sich bestimmte Ideen in der Architektur so hartnäckig halten. Und vielleicht reicht das völlig.</p>



<h4 class="wp-block-heading"><br><strong>Referenzen</strong></h4>



<ol class="wp-block-list">
<li><em>iSAQB Advanced Level Module – Green IT</em><em><br></em><a href="https://isaqb.org/certifications/advanced-level/green-it/" target="_blank" rel="noopener">https://isaqb.org/certifications/advanced-level/green-it/</a> </li>



<li><em>Keynote: Vibe Coding Auth Without Melting Down!</em><em><br></em><a href="https://conferences.isaqb.org/software-architecture-gathering/session/keynote-vibe-coding-auth-without-melting-down/" target="_blank" rel="noopener">https://conferences.isaqb.org/software-architecture-gathering/session/keynote-vibe-coding-auth-without-melting-down/</a> </li>



<li><em>Cheryl Hung – Vibe Coding Auth Without Melting Down (Slides)</em><em><br></em><a href="https://www.slideshare.net/slideshow/cheryl-hung-vibe-coding-auth-without-melting-down-isaqb-software-architecture-gathering-2025-pdf/284317660" target="_blank" rel="noopener">https://www.slideshare.net/slideshow/cheryl-hung-vibe-coding-auth-without-melting-down-isaqb-software-architecture-gathering-2025-pdf/284317660</a> </li>



<li><em>Ein halber Tag im Leben eines Vibecoders </em><em><br></em><a href="https://atra.consulting/engineering/ein-halber-tag-im-leben-eines-vibecoders">https://atra.consulting/engineering/ein-halber-tag-im-leben-eines-vibecoders</a> </li>



<li><em>Passing the Security Vibe Check: The Dangers of Vibe Coding</em><em><br></em><a href="https://www.databricks.com/blog/passing-security-vibe-check-dangers-vibe-coding" target="_blank" rel="noopener">https://www.databricks.com/blog/passing-security-vibe-check-dangers-vibe-coding</a> </li>



<li><em>Shift-Down Security (SIG-Security Working Paper)</em><em><br></em><a href="https://raw.githubusercontent.com/kubernetes/sig-security/main/sig-security-docs/papers/shift-down/shift-down-security.md" target="_blank" rel="noopener">https://raw.githubusercontent.com/kubernetes/sig-security/main/sig-security-docs/papers/shift-down/shift-down-security.md</a> </li>



<li><em>What is Shift-Down Security?</em><em><br></em> <a href="https://nirmata.com/2024/09/13/what-is-shift-down-security/" target="_blank" rel="noopener">https://nirmata.com/2024/09/13/what-is-shift-down-security/</a> </li>



<li><em>The Magic Power of Enabling Constraints</em><em><br></em> <a href="https://www.scrum.org/resources/blog/magic-power-enabling-constraints" target="_blank" rel="noopener">https://www.scrum.org/resources/blog/magic-power-enabling-constraints</a></li>



<li><em>Now We’ve Given Them Every Freedom – and They Still Don’t Do What We Want</em><em><br></em><a href="https://conferences.isaqb.org/software-architecture-gathering/session/now-weve-given-them-every-freedom-and-they-still-dont-do-what-we-want/" target="_blank" rel="noopener">https://conferences.isaqb.org/software-architecture-gathering/session/now-weve-given-them-every-freedom-and-they-still-dont-do-what-we-want/</a> </li>



<li><em>The Hexagonal or Ports &amp; Adapters Architecture</em><em><br></em><a href="https://conferences.isaqb.org/software-architecture-gathering/session/the-hexagonal-or-ports-adapters-architecture/" target="_blank" rel="noopener">https://conferences.isaqb.org/software-architecture-gathering/session/the-hexagonal-or-ports-adapters-architecture/</a><br></li>
</ol>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-full"><img decoding="async" width="425" height="425" src="https://atra.consulting/wp-content/uploads/2025/01/profilbild-daniel-wochnik-500-x-500px.jpg" alt="Daniel Wochnik, Geschäftsbereichsleitung Finanzdienstleistungen" class="wp-image-3216" style="object-fit:cover" title="Team-Schwarze"/></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Daniel Wochnik</h3>



<p class="wp-block-paragraph">Geschäftsbereichsleitung »Finanzdienstleistungen«</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Daniel ist seit 2017 in der IT-Branche aktiv und bringt seine umfassende Erfahrung als Senior Managing Consultant und Geschäftsbereichsleiter für Finanzdienstleistungen bei atra.consulting ein. Besonders begeistert ihn das Zusammenspiel technischer, methodischer und organisatorischer Aspekte. Als leidenschaftlicher Läufer und bekennender 1. FC Köln-Fan hat er seine Leidensfähigkeit auch privat mehrfach unter Beweis gestellt. Seine Kunden unterstützt er als Softwarearchitekt, agiler Coach und Berater bei der nachhaltigen und zielgerichteten Umsetzung von Entwicklungsprojekten.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:d.wochnik@atra.consulting">d.wochnik@atra.consulting</a>&nbsp; &nbsp;&nbsp;<a href="https://de.linkedin.com/in/daniel-wochnik" target="_blank" rel="noreferrer noopener"></a></p>



<ul class="wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a href="https://de.linkedin.com/in/daniel-wochnik" class="wp-block-social-link-anchor" target="_blank" rel="noopener"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li></ul>
</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Event-Rückblick: Java-Startzeiten optimieren</title>
		<link>https://atra.consulting/engineering/java-startzeiten-optimieren/</link>
		
		<dc:creator><![CDATA[Timo Kaiser]]></dc:creator>
		<pubDate>Tue, 18 Nov 2025 08:52:15 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=8878</guid>

					<description><![CDATA[Vortrag im Office mit Karsten Silz Wie holen wir das Beste aus unseren Java-Anwendungen heraus? Zu diesem Thema gab Karsten Silz bei uns im Stuttgarter Office einen tiefen Einblick in die aktuellen Möglichkeiten der Performance-Optimierung. Gerade in Zeiten von Serverless Computing und Microservices ist die Startzeit von Java-Anwendungen ein kritischer Faktor. Karsten zeigte uns anschaulich [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">Vortrag im Office mit Karsten Silz</h3>



<p class="wp-block-paragraph"><strong>Wie holen wir das Beste aus unseren Java-Anwendungen heraus?</strong> Zu diesem Thema gab Karsten Silz bei uns im Stuttgarter Office einen tiefen Einblick in die aktuellen Möglichkeiten der Performance-Optimierung.</p>



<p class="wp-block-paragraph">Gerade in Zeiten von Serverless Computing und Microservices ist die Startzeit von Java-Anwendungen ein kritischer Faktor. Karsten zeigte uns anschaulich die Bandbreite der Möglichkeiten auf – vom einfachen <strong>Spring Boot Tuning</strong> über <strong>Class Data Sharing (CDS)</strong> und <strong>Project Leyden</strong> bis hin zu <strong>Project CRaC </strong>und <strong>GraalVM Native Image</strong>.</p>



<p class="wp-block-paragraph">Besonders wertvoll war dabei der Blick auf die Wirtschaftlichkeit: Nicht jede technische Optimierung rechnet sich am Ende auch betriebswirtschaftlich.</p>



<p class="wp-block-paragraph">Wer den Vortrag verpasst hat oder tiefer in die technischen Details, Benchmarks und ROI-Berechnungen einsteigen möchte, findet alle Informationen, Folien und Beispiel-Code direkt in Karstens Zusammenfassung.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-fe48e5de wp-block-buttons-is-layout-flex">
<div class="wp-block-button has-custom-width wp-block-button__width-50 is-style-fill no-text-decoration"><a class="wp-block-button__link has-white-color has-primary-background-color has-text-color has-background has-link-color wp-element-button" href="https://betterprojectsfaster.com/learn/talk-atra-consulting-java-startup/" target="_blank" rel="noreferrer noopener">Zum vollständigen Artikel von Karsten Silz</a></div>
</div>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-full"><img decoding="async" width="800" height="800" src="https://atra.consulting/wp-content/uploads/2025/03/TK-Profile-e1741870954239.jpeg" alt="" class="wp-image-5208" srcset="https://atra.consulting/wp-content/uploads/2025/03/TK-Profile-e1741870954239.jpeg 800w, https://atra.consulting/wp-content/uploads/2025/03/TK-Profile-e1741870954239-768x768.jpeg 768w" sizes="(max-width: 800px) 100vw, 800px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Timo Kaiser</h3>



<p class="wp-block-paragraph">Senior Software Engineer</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph"><strong>Timo </strong>ist ein erfahrener Webentwickler mit über 15 Jahren Projekterfahrung, insbesondere in der Umsetzung moderner, barrierefreier Frontends auf Basis von Angular, TypeScript, HTML und SCSS. Sein Schwerpunkt liegt auf der Entwicklung skalierbarer, wartbarer und zugänglicher Webanwendungen<strong>.</strong></p>



<p class="wp-block-paragraph">Als Lead Developer verantwortet er in Projekten die technische Umsetzung, Architekturentscheidungen sowie die kontinuierliche Optimierung der User Experience. Timo ist Ansprechpartner für technische und methodische Fragen, übersetzt Anforderungen in strukturierte Sprints und Git-Workflows und sorgt durch Code-Reviews, Pairing und Coaching für hohe Qualität und Effizienz im Team. Er arbeitet eng mit Design- und UX-Teams zusammen und bringt seine gestalterische Erfahrung auch in Tools wie Figma oder Adobe XD ein.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:t.kaiser@atra.consulting">t.kaiser@atra.consulting</a>    <a href="https://de.linkedin.com/in/daniel-wochnik" target="_blank" rel="noreferrer noopener"></a></p>



<ul class="wp-block-social-links hidden is-layout-flex wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a href="https://www.linkedin.com/in/timo-kaiser-6a24b5130/" class="wp-block-social-link-anchor" target="_blank" rel="noopener"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li></ul>
</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Wieso ich Retros nicht mehr mag</title>
		<link>https://atra.consulting/engineering/wieso-ich-retros-nicht-mehr-mag/</link>
		
		<dc:creator><![CDATA[Daniel Wochnik]]></dc:creator>
		<pubDate>Mon, 20 Oct 2025 08:30:35 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=8679</guid>

					<description><![CDATA[Und was ich daraus gelernt habe&#8230; Retrospektiven gelten als Herzstück agiler Teams – doch was, wenn sie sich nur noch wie ein weiteres Meeting anfühlen? In diesem Artikel schildere ich, wie ich selbst in die Falle der „Retro Fatigue“ getappt bin, welche Muster mir dabei aufgefallen sind und wie wir Retros wieder zu echten Räumen [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">Und was ich daraus gelernt habe&#8230;</h3>



<p class="wp-block-paragraph"><em>Retrospektiven gelten als Herzstück agiler Teams – doch was, wenn sie sich nur noch wie ein weiteres Meeting anfühlen? In diesem Artikel schildere ich, wie ich selbst in die Falle der „Retro Fatigue“ getappt bin, welche Muster mir dabei aufgefallen sind und wie wir Retros wieder zu echten Räumen für Verbesserung machen können.&nbsp;</em></p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Beruflich gesprochen bin ich mit agiler Softwareentwicklung groß geworden. Als ich 2017 meine ersten Schritte bei einer großen deutschen Traditionsversicherung machte, waren hippe Agile-Trainingscenter mit Kickertisch und Gratiskaffee sowie der Trend zu autonomen Teams mit mehr Freiheitsgraden selbst dort längst angekommen. Und was soll ich sagen? Vielleicht lag es auch an meiner ersten Führungskraft, die noch eher vom Typ „Excelliste &amp; Rapport-Planung“ war – aber ich war sofort fasziniert von der agilen Denkweise, die motivierte Individuen und ein funktionierendes Produkt in den Mittelpunkt stellt. Vom ersten Tag an hätte ich mich wohl als Agilist bezeichnet – ohne den Begriff überhaupt zu kennen.</p>



<p class="wp-block-paragraph">Auch heute noch begeistern mich Konzepte wie Modern Agile, und in meinen Projekten übernehme ich gelegentlich agile Rollen. Umso erstaunter war ich, als ich kürzlich feststellte: Ich freue mich nicht mehr auf meine Retrospektive. Im Gegenteil – der zweiwöchentliche Termin fühlte sich zunehmend wie eine lästige Pflichtaufgabe an. Wäre ich als Agile Master nicht qua Rolle der Hüter der Retro gewesen – ich hätte sie wohl abgesagt.</p>



<p class="wp-block-paragraph">Dabei halte ich es eigentlich mit Woody Zuill, der sagte:</p>



<p class="wp-block-paragraph"><em>„If you adopt only one agile practice, let it be retrospectives. Everything else will follow.“</em></p>



<p class="wp-block-paragraph">Wie konnte es soweit kommen? Wie wurde aus dem vielleicht wichtigsten Ritual der agilen Welt eine Routine, die ich (und vermutlich große Teile des Teams) als wenig wertvoll empfand?</p>



<p class="wp-block-paragraph">Eins vorweg: Nicht jede Retro war schlecht. Es gab großartige Diskussionen und wertvolle Impulse für Verbesserungen. Und ja, vermutlich habe ich mich im operativen Tagesgeschäft manchmal zu sehr verfangen und Inspect &amp; Adapt nicht immer priorisiert.</p>



<p class="wp-block-paragraph">Aber dennoch … die Retros fühlten sich oft wie eine Pflichtübung an. Wie kam es zu dieser Retro Fatigue? Und was kann man dagegen tun?</p>



<h3 class="wp-block-heading"><br><strong>Inspect ohne Adap</strong>t</h3>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e9a4fc&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e9a4fc" class="alignleft size-full is-resized wp-lightbox-container"><img decoding="async" width="1024" height="1024" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/10/image-5.png" alt="" class="wp-image-8684" style="width:310px" srcset="https://atra.consulting/wp-content/uploads/2025/10/image-5.png 1024w, https://atra.consulting/wp-content/uploads/2025/10/image-5-768x768.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Es beginnt oft leise: Ein Action Item verschwindet in der Jira-Tiefe. Ein anderes bleibt ohne Besitzer. Beim dritten ist unklar, was es eigentlich bedeuten soll. Niemand sagt es laut, aber alle spüren es – da bewegt sich wenig. Die Retro war nicht schlecht, aber auch nicht wirksam. Genau hier entsteht sie: die stille Enttäuschung, die sich Retro für Retro summiert. Und plötzlich fragt man sich: Warum machen wir das eigentlich noch?</p>



<p class="wp-block-paragraph">Ich glaube, genau dieser Punkt ist der gefährlichste Kipppunkt jeder Retrokultur. Denn auch wenn das Gespräch gut war – wenn aus den Erkenntnissen keine Veränderung entsteht, schlägt Reflexion in Frustration um. Das Team spürt: Wir reden, aber es passiert nichts. Und mit jedem unerledigten Action Item sinkt die Bereitschaft, sich beim nächsten Mal einzubringen.</p>



<p class="wp-block-paragraph">Die Ursachen dafür sind vielseitig – und meist ganz banal. Maßnahmen werden vage formuliert („Wir sollten mehr aufeinander achten“), bleiben ohne Verantwortliche oder versickern einfach im Alltag. Besonders tückisch: Oft merkt es niemand sofort. Doch wenn es zur Gewohnheit wird, dass auf Retros keine Veränderung folgt, wird aus dem wichtigsten agilen Ritual ein frustrierendes Meeting mit Alibi-Charakter.</p>



<p class="wp-block-paragraph">Was hilft? Klare, konkrete Maßnahmen – versehen mit Zuständigkeit, Frist und Sichtbarkeit. Und: Mut zur Ehrlichkeit. Wenn ein Thema dem Team nicht wichtig genug ist, um Energie hineinzustecken, dann darf es auch bewusst verworfen werden. Alles andere ist Selbsttäuschung. Und ja, auch als Scrum Master oder Agile Coach sollte man sich nicht reflexartig jedes „verwaiste“ To-do greifen. Denn wenn sich niemand verantwortlich fühlt, ist das oft die deutlichere Botschaft als jede Diskussion.</p>



<p class="wp-block-paragraph">Nicht zuletzt hilft es, Erfolge auch sichtbar zu machen – und sei es nur ein kleiner Schritt. Denn nichts motiviert mehr als das Gefühl: Wir können etwas verändern.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<details class="wp-block-details foldable-info-box has-white-color has-text-color has-background has-link-color wp-elements-d4e93c5d17ef653236137ecb0b1a7ac9 is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary><strong>Anti-Pattern: Inspect-ohne-Adapt</strong></summary>
<p class="wp-block-paragraph">Teams reflektieren regelmäßig, aber ziehen daraus keine konkreten oder nachhaltigen Veränderungen. Maßnahmen bleiben vage, versickern im Alltag oder verschwinden unbeachtet in Jira. Die Retro wird zur Pflichtübung ohne Wirksamkeit.</p>



<p class="wp-block-paragraph"><br><strong>Typische Sätze:</strong></p>



<ul class="wp-block-list">
<li>„War das nicht schon letztes Mal ein Thema?“</li>



<li>„Was ist eigentlich aus dem To-do geworden?“</li>



<li>„Das steht irgendwo in Jira – glaub ich.“</li>
</ul>



<p class="wp-block-paragraph"><br><strong>Was tun?</strong></p>



<ul class="wp-block-list">
<li>Maßnahmen konkret formulieren: <em>Wer? Was? Bis wann?</em></li>



<li>Verantwortliche und Fristen benennen</li>



<li>Status regelmäßig reviewen – idealerweise im nächsten Sprint-Planning</li>



<li>Unerledigte Punkte auch bewusst verwerfen – statt sie weiter mitziehen</li>



<li>Sichtbare Erfolge schaffen, selbst bei kleinen Verbesserungen</li>
</ul>
</details>



<div style="height:60px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Zu große oder zu heterogene Teams</strong></h3>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e9b851&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e9b851" class="alignleft size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="683" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/10/image-2-1024x683.png" alt="Retro" class="wp-image-8681" style="width:400px" srcset="https://atra.consulting/wp-content/uploads/2025/10/image-2-1024x683.png 1024w, https://atra.consulting/wp-content/uploads/2025/10/image-2-768x512.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Wer kennt es nicht? Während beispielsweise der Scrum Guide 3 bis maximal 9 Teammitglieder für ein agiles Team empfiehlt, finden sich in der Realität oft riesige Teams von 10, 15 oder gar über 20 Teammitgliedern. Dies führt nicht nur unweigerlich zu „Teams in Teams“, sondern sorgt auch dafür, dass die Retro sich anfühlt wie ein Meeting-Marathon ohne Fokus. Oft sprechen nur wenige, während sich andere zurücklehnen oder gedanklich ausklinken. Einzelne Stimmen gehen unter oder wiederholen sich. Entscheidungen werden verwässert, Diskussionen enden in Allgemeinplätzen.</p>



<p class="wp-block-paragraph">In solchen Situationen hilft es, bewusst kleinere Gruppen zu bilden, etwa durch eine Retrospektive in Subteams mit anschließendem Austausch der Erkenntnisse. Auch das Wechseln der Perspektive – etwa durch gezielte Fragestellungen pro Teambereich – kann helfen, mehr Relevanz und Beteiligung zu erzeugen.&nbsp;</p>



<p class="wp-block-paragraph">Am Ende lässt sich dieses Problem jedoch nur bedingt im Team lösen: Wenn das Team zu groß ist, um gemeinsam wirklich reflektieren zu können, dann ist das kein Zeichen gegen die Retro – sondern ein klarer Hinweis auf ein organisatorisches Problem.&nbsp;</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<details class="wp-block-details foldable-info-box has-white-color has-text-color has-background has-link-color wp-elements-e0fbfee068094e68017e94d6523f1780 is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary><strong>Anti-Pattern: Teammarathon statt Teamreflexion</strong></summary>
<p class="wp-block-paragraph">Retros mit zu großen oder heterogenen Gruppen führen zu ermüdenden Diskussionen ohne Fokus. Einige dominieren die Gespräche, andere klinken sich aus – Reflexion wird zur Massenabfertigung.</p>



<p class="wp-block-paragraph"><br><strong>Typische Sätze:</strong></p>



<ul class="wp-block-list">
<li>„Ich glaube, das Thema betrifft uns gar nicht direkt.“</li>



<li>„Können wir das mal abkürzen?“</li>



<li>„Ich hab eh nix beizutragen – die anderen reden schon genug.“</li>
</ul>



<p class="wp-block-paragraph"><br><strong>Was tun?</strong></p>



<ul class="wp-block-list">
<li>Große Teams in Subgruppen aufteilen und Ergebnisse konsolidieren</li>



<li>Themen gezielt nach Team-Bereichen oder Rollen clustern</li>



<li>Rollen- oder themenspezifische Retros einführen (z. B. Dev-only, UX-only)</li>



<li>Teamzuschnitt grundsätzlich hinterfragen: Ist das wirklich <em>ein</em> Team?</li>
</ul>
</details>



<div style="height:60px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Retro overload</strong></h3>



<p class="wp-block-paragraph">Während so gut wie alle agilen Events, von Sprintplannung über Daily Standups bis zu Reviews, mehr oder weniger regelmäßig hinterfragt oder zumindest kritisiert werden, scheinen Retrospektiven in den meisten Teams heilig. Und das ist doch gut so, oder? </p>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e9c779&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e9c779" class="alignright size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="683" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/10/image-7-1024x683.png" alt="" class="wp-image-8693" style="aspect-ratio:1.499390872458064;object-fit:cover;width:400px" srcset="https://atra.consulting/wp-content/uploads/2025/10/image-7-1024x683.png 1024w, https://atra.consulting/wp-content/uploads/2025/10/image-7-768x512.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Immerhin ist Inspect &amp; Adapt der zentrale Gedanke agilen Arbeitens und ich selbst habe Woody Zuills Aussage zur Wichtigkeit von Retrospektiven zu Beginn dieses Artikels zitiert.</p>



<p class="wp-block-paragraph">Ganz so einfach ist es in meinen Augen dann aber doch nicht. Vermutlich haben die meisten bereits Retros erlebt, an dem die Leute verschlossen, abgelenkt, unmotiviert oder einfach genervt von Gott und der Welt waren. Natürlich kann man hier durch gute Vorbereitung und Moderation sowie einem gemeinsamen Verständnis der Wichtigkeit einer Retrospektive viel erreichen. Aber dennoch glaube ich, manche Retros sind von vornherein zum Scheitern verurteilt.</p>



<p class="wp-block-paragraph">Vielleicht sind die Teams noch nicht so weit, im vorgesehenen Rhythmus gemeinsam zu reflektieren. Vielleicht fehlt Vertrauen oder sind Verhaltensweisen oder Organisationen so festgefahren, dass Veränderung einfach eine gewisse Zeit brauchen. Es gibt viele Gründe, weswegen Teams zu viele Retros durchführen können. Dabei führen viele Retros eben nicht zu besonders viel Inspect &amp; Adapt, sondern zu kompletten Stillstand. Frei nach Paracelsus: Die Dosis macht das Gift.</p>



<p class="wp-block-paragraph">Gerade weil Retros so wichtig sind, trauen sich meiner Erfahrung nach die wenigsten Teams oder Coaches wirklich, ihre Retros kritisch zu hinterfragen. Dabei ist genau diese Reflektion zentral, um Meetings wirklich wertvoll zu machen. Und ich lade jedes Team herzlich ein, in der nächsten Retro einmal über den Sinn &#8211; und Unsinn der eigenen Retro zu diskutieren.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<details class="wp-block-details foldable-info-box has-white-color has-text-color has-background has-link-color wp-elements-f84879a92bb3430633f9657b07ada209 is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary><strong>Anti-Pattern: Zombie-Retros</strong></summary>
<p class="wp-block-paragraph">Retros finden zwar regelmäßig statt, aber ohne Energie, Fokus oder Veränderungswirkung. Das Team kommt pflichtbewusst zusammen, ohne echtes Interesse oder Beteiligung – die Retro lebt nur noch formal weiter.</p>



<p class="wp-block-paragraph"><br><strong>Typische Sätze:</strong></p>



<ul class="wp-block-list">
<li>„Schon wieder Retro? Haben wir überhaupt Themen?“</li>



<li>„Lass uns einfach schnell durchziehen.“</li>



<li>„Ich hab ehrlich gesagt grad keinen Nerv für das Meeting.“</li>
</ul>



<p class="wp-block-paragraph"><br><strong>Was tun?</strong></p>



<ul class="wp-block-list">
<li>Retro-Frequenz kritisch mit dem Team reflektieren – Qualität vor Quantität</li>



<li>Den Retro-Zweck offen thematisieren: <em>Was bringt uns das hier wirklich?</em></li>



<li>Temporär pausieren oder Format variieren (z. B. Lean Coffee, Walk &amp; Talk)</li>



<li>Teams Raum geben, erst Reife und Vertrauen zu entwickeln</li>
</ul>
</details>



<div style="height:60px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Fokus auf den Circle of Concern</strong></h3>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e9d68d&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e9d68d" class="alignleft size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="683" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/10/image-9-1024x683.png" alt="" class="wp-image-8695" style="width:400px" srcset="https://atra.consulting/wp-content/uploads/2025/10/image-9-1024x683.png 1024w, https://atra.consulting/wp-content/uploads/2025/10/image-9-768x512.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Eine Kunst bei Retrospektiven ist es, den Blick über den Tellerrand zu werfen und gleichzeitig vor allem das eigene Verhalten zu reflektieren.</p>



<p class="wp-block-paragraph">Allzu häufig beobachten wir jedoch eine Fixierung auf den „Circle of Concern“ – also Themen, die zwar die Arbeit des Teams beeinflussen, auf die es aber keinen direkten Einfluss hat. Da wird dann über Tools, die Unternehmensleitung, unklare Strategie oder die Organisation als Ganzes geschimpft. Und ja, manches davon ist durchaus berechtigt – aber selten produktiv.</p>



<p class="wp-block-paragraph">In Retros geht es vor allem um Selbstwirksamkeit. Um den „Circle of Influence“. Also um die Frage: Was können wir ändern? Wo liegt unser Gestaltungsspielraum? Sich das immer wieder bewusst zu machen und notfalls auch mal freundlich, aber bestimmt zurück auf den Einflussbereich zu lenken, ist eine der wichtigsten Aufgaben eines guten Facilitators.</p>



<p class="wp-block-paragraph">Manchmal hilft hier ein Perspektivwechsel: Etwa durch gezielte Fragen wie „Was war unser Anteil daran?“ oder „Was würden wir anders machen, wenn wir es allein entscheiden könnten?“ – und manchmal wandelt sich tatsächlich ein Ohnmachtsgefühl in einen konkreten Handlungsspielraum.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<details class="wp-block-details foldable-info-box has-white-color has-text-color has-background has-link-color wp-elements-91aace933c4501dbc2e3c65d2ecfbc11 is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary><strong>Anti-Pattern: Circle-of-Concern-Falle</strong></summary>
<p class="wp-block-paragraph">Das Team diskutiert in der Retro bevorzugt über Probleme außerhalb seines Einflussbereichs – von Managemententscheidungen über schlechte Tools bis hin zur Unternehmensstrategie. Die Reflexion bleibt folgenlos, Frust entsteht.</p>



<p class="wp-block-paragraph"><br><strong>Typische Sätze:</strong></p>



<ul class="wp-block-list">
<li>„Wenn die da oben endlich mal…“</li>



<li>„Mit diesem Tool ist doch eh nix zu machen.“</li>



<li>„Solange die Strategie unklar ist, bringt alles andere auch nix.“</li>
</ul>



<p class="wp-block-paragraph"><br><strong>Was tun?</strong></p>



<ul class="wp-block-list">
<li>Klarer Fokus auf den „Circle of Influence“ – was <em>können</em> wir verändern?</li>



<li>Perspektivwechsel fördern: „Was war unser Anteil daran?“</li>



<li>Themen außerhalb des Einflussbereichs bewusst parken oder anders adressieren (z. B. Impediment-Backlog, Eskalationskanäle)</li>



<li>Selbstwirksamkeit betonen und kleine, konkrete Veränderungen sichtbar machen</li>
</ul>
</details>



<div style="height:60px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Infantilisierung von Mitarbeitern und Monotonie</strong></h3>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e9e558&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e9e558" class="alignright size-full is-resized wp-lightbox-container"><img decoding="async" width="1536" height="1024" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/10/image-11.png" alt="" class="wp-image-8697" style="width:435px" srcset="https://atra.consulting/wp-content/uploads/2025/10/image-11.png 1536w, https://atra.consulting/wp-content/uploads/2025/10/image-11-1024x683.png 1024w, https://atra.consulting/wp-content/uploads/2025/10/image-11-768x512.png 768w" sizes="(max-width: 1536px) 100vw, 1536px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Viele Retros laufen nach einem sehr ähnlichen Muster ab. Zuerst gibt es einen Checkin, um ein gutes Gesprächsklima zu schaffen. Danach werden Eindrücke und Themen aus der vergangenen Iteration gesammelt. Hieraus werden (oftmals priorisiert durch Dot-Voting) Erkenntnisse gemeinsam diskutiert und abgeleitet, bevor sich das Team auf Action Items einigt und die Retro mittels eines Check-Outs abschließt. Auch wenn es hier von Lego-, über Dino- und Superhelden-Retros verschiedenste Flavour gibt und sich die Details sicherlich unterscheiden (und die Unterscheidung sehr sinnvoll sein kann!) fallen doch die meisten Retros in dieses Schema. Und ermüden die Teams. Eigentlich tolle Hilfsmittel, wie der <a href="https://retromat.org/" target="_blank" rel="noopener">Retromat</a> verstärken ein solches Muster nochmals.&nbsp;</p>



<p class="wp-block-paragraph">Natürlich wirkt sich dieser Faktor umso stärker aus, je weniger nachhaltige Ergebnisse die Retros wirklich produzieren (s.o.).</p>



<p class="wp-block-paragraph">Auch wenn es etwas harsch klingt: Ich habe oftmals das Gefühl, auch im agilen Kontext neigen wir dazu, Kolleginnen und Kollegen zu infantilisieren. Dies beginnt damit, dass Widerstände gegen Change gerne mal mit “fehlendem agilen Mindset” weggewischt werden oder dass wir glauben, dass sich ein Teammitglied schon öffnet, wenn wir ihm schon genügend, auflockernde und teambildende Checkins und Möglichkeiten bieten. Dabei ist es eigentlich eine Grundannahme des agilen, Menschen wie Erwachsene zu behandeln.</p>



<p class="wp-block-paragraph">Und genau dies ist meiner Erfahrung nach auch der richtige Weg: Das Team dort abholen, wo es startet und etwaige Störgefühle offen ansprechen. Zur Abwechslung auch mal gar keine oder nur eine minimale Struktur für die Retro vorzugeben und in einem offenen Format dem Team den Raum geben, Themen und Optimierungsmöglichkeiten zu besprechen, kann helfen, aus dem Trott auszubrechen. Auch abwechslungsreiche Formate wie ein <a href="https://t2informatik.de/wissen-kompakt/pre-mortem/" target="_blank" rel="noopener">Pre-Mortem</a> sind in diesem Kontext spannende Werkzeuge.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<details class="wp-block-details foldable-info-box has-white-color has-text-color has-background has-link-color wp-elements-c2cc45fed02dedde83d72ccf14181018 is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary><strong>Anti-Pattern: Schema-F-Retros</strong></summary>
<p class="wp-block-paragraph">Retros laufen stets nach demselben Ablauf ab – Check-in, Themen sammeln, Dot-Voting, Action Items, Check-out – oft ergänzt durch Gamification-Elemente. Die Methoden überlagern die Inhalte, echte Reflexion weicht Routine.</p>



<p class="wp-block-paragraph"><br><strong>Typische Sätze:</strong></p>



<ul class="wp-block-list">
<li>„Lass mich raten, wieder Dot-Voting?“</li>



<li>„Können wir den Check-in diesmal weglassen?“</li>



<li>„Ich weiß schon genau, was gleich kommt.“</li>
</ul>



<p class="wp-block-paragraph"><br><strong>Was tun?</strong></p>



<ul class="wp-block-list">
<li>Abwechslung einbauen: neue Formate (z. B. Pre-Mortem, Lean Coffee), offene Diskussion</li>



<li>Bewusst auf Elemente verzichten – z. B. ganz ohne Miro-Board</li>



<li>Retro gelegentlich vom Team selbst gestalten lassen</li>



<li>Struktur der Retro gemeinsam mit dem Team infrage stellen</li>
</ul>
</details>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<details class="wp-block-details foldable-info-box has-white-color has-text-color has-background has-link-color wp-elements-48812a218b214a7a39f45eb682693d3a is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary><strong>Anti-Pattern: Feel-Good-Facilitation</strong></summary>
<p class="wp-block-paragraph">Check-ins, Spielchen und Symbolarbeit sollen Teams zum Öffnen bringen – oft auch dann, wenn das eigentliche Problem ein strukturelles oder kulturelles ist. Das Team fühlt sich nicht ernst genommen, echte Themen bleiben unausgesprochen.</p>



<p class="wp-block-paragraph"><br><strong>Typische Sätze:</strong></p>



<ul class="wp-block-list">
<li>„Sollen wir wieder Superhelden ziehen?“</li>



<li>„Ich will kein Tier sein, ich hab ein Thema!“</li>



<li>„Wir spielen hier doch nicht Kindergarten.“</li>
</ul>



<p class="wp-block-paragraph"><br><strong>Was tun?</strong></p>



<ul class="wp-block-list">
<li>Erwachsene wie Erwachsene behandeln: echte Themen zulassen</li>



<li>Störungen ansprechen, statt sie mit Ritualen zu überdecken</li>



<li>Methoden als Mittel zum Zweck nutzen – nicht als Ziel</li>



<li>Dem Team zutrauen, auch ohne methodischen Rahmen gut zu arbeiten</li>
</ul>
</details>



<div style="height:60px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>Misstrauen (in das Management)&nbsp;</strong></h3>


<div class="wp-block-image">
<figure data-wp-context="{&quot;imageId&quot;:&quot;69e69a8e9f783&quot;}" data-wp-interactive="core/image" data-wp-key="69e69a8e9f783" class="alignleft size-large is-resized wp-lightbox-container"><img decoding="async" width="1024" height="683" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://atra.consulting/wp-content/uploads/2025/10/image-13-1024x683.png" alt="" class="wp-image-8699" style="width:400px" srcset="https://atra.consulting/wp-content/uploads/2025/10/image-13-1024x683.png 1024w, https://atra.consulting/wp-content/uploads/2025/10/image-13-768x512.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>
</div>


<p class="wp-block-paragraph">Ich denke manchmal an Asterix &amp; Obelix, wenn ich manche Teams in ihren Retros beobachte. Da sitzt ein gallisches Dorf zusammen, kämpferisch, eng verbunden, voller Stolz auf die eigene Selbstorganisation. Und draußen lauert das Imperium: das Management, die Enterprise Architekten, die fremdbestimmten Roadmaps. Was als gesunder Schutzmechanismus beginnt, kann schnell zur systemischen Trennung werden.</p>



<p class="wp-block-paragraph">Besonders in Retros wird dieses Muster sichtbar. Immer wieder kommen dieselben Themen auf: fehlende Entscheidungsspielräume, widersprüchliche Impulse von außen, Tooling, das bremst. Doch je häufiger solche Punkte ohne spürbare Reaktion bleiben, desto mehr verfestigt sich im Team ein Gefühl von: „Die da draußen machen ja doch, was sie wollen.“ Und damit auch: „Dann machen wir hier halt unser Ding.“ Die Retro wird zur Bühne der Selbstvergewisserung – aber nicht mehr zur Brücke nach außen.</p>



<p class="wp-block-paragraph">Agile Coaches tragen zu dieser Dynamik manchmal ungewollt bei. Indem sie Teams in ihrer Eigenständigkeit stärken, aber gleichzeitig versuchen, sie vor destruktiven oder unklaren Einflüssen von außen zu schützen. Das ist verständlich – aber auch gefährlich. Denn wenn das Team sich nur noch im Inner Circle bewegt, wird Selbstorganisation schnell zu Selbstabschottung. Die Retrospektive verkommt zur Selbstbespiegelung: Immer die gleichen Themen, immer die gleichen Perspektiven, keine echte Weiterentwicklung.</p>



<p class="wp-block-paragraph">Was hilft? Brücken bauen. Zum Beispiel durch „Retro Reviews“ mit Stakeholdern, durch Eskalationsschleifen mit Feedback-Rückkanal oder durch die bewusste Einbindung von Führungskräften – nicht als Kontrolle, sondern als Dialogpartner. Besonders wichtig ist in diesem Kontext die Rolle des Product Owners – und anderer Personen, die sich in übergreifenden Gremien und Abstimmungen bewegen, auf einer Ebene, die viele als Flight Level 2 bezeichnen würden. Gerade wenn diese Rollen über lange Zeit eng im Team verankert waren, neigen sie dazu, Konflikte zu vermeiden und übernehmen häufig unbewusst die Narrative des Teams als „Good Buddy“. Wenn es ihnen jedoch gelingt, sich aus dieser Sichtweise zu lösen und gezielt Impulse von außen ins Team zu tragen, kann das die Retro wieder öffnen – für neue Perspektiven und echte Veränderung.</p>



<p class="wp-block-paragraph">Denn ein gallisches Dorf ist stark – aber es muss anschlussfähig bleiben, wenn es nicht irgendwann alleine dastehen will.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<details class="wp-block-details foldable-info-box has-white-color has-text-color has-background has-link-color wp-elements-21b5e7247fa2019f00ca6bec718d843f is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary><strong>Anti-Pattern: Gallisches-Dorf-Reflex</strong></summary>
<p class="wp-block-paragraph">Das Team schottet sich gegenüber äußeren Einflüssen ab, sieht sich als letzte Bastion der Selbstorganisation – während das Umfeld (Management, andere Teams, Architektur) als Bedrohung erlebt wird. Die Retro dient nur noch der internen Selbststärkung.</p>



<p class="wp-block-paragraph"><br><strong>Typische Sätze:</strong></p>



<ul class="wp-block-list">
<li>„Die da oben verstehen eh nicht, wie wir arbeiten.“</li>



<li>„Wir müssen uns halt selbst schützen.“</li>



<li>„Lass uns lieber nichts sagen, sonst mischen die sich wieder ein.“</li>
</ul>



<p class="wp-block-paragraph"><br><strong>Was tun?</strong></p>



<ul class="wp-block-list">
<li>Brücken bauen: z. B. durch Retro-Reviews mit Stakeholdern oder Eskalationsfeedback</li>



<li>Führung als Dialogpartner einladen – nicht als Kontrolle</li>



<li>Product Owner und andere Flight-Level-2-Rollen gezielt ermutigen, systemische Impulse ins Team zu tragen</li>



<li>Externe Stimmen punktuell bewusst integrieren (z. B. andere Teams)</li>
</ul>
</details>



<div style="height:60px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Ein kleines Fazit&nbsp;</strong></h2>



<p class="wp-block-paragraph">Retrospektiven sind ein zentrales Werkzeug agiler Zusammenarbeit – und gleichzeitig anfällig für Abnutzung, Frustration und schleichende Bedeutungslosigkeit. Die in diesem Artikel beschriebenen Symptome von „Retro Fatigue“ habe ich nicht nur beobachtet, sondern teilweise selbst verursacht. Doch genau darin liegt auch eine Chance: Wenn wir den Mut haben, offen über unsere eigenen Routinen zu sprechen, können wir Retrospektiven wieder zu dem machen, was sie sein sollen – Räume für echte Reflexion, lernende Teams und kontinuierliche Verbesserung.</p>



<p class="wp-block-paragraph">Also was würde ich zukünftig denn nun anders machen? Als allererstes wohl offen mit dem Team sprechen. Und einmal reflektieren, welche Anti-Pattern gerade eigentlich auf uns zutreffen.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%">
<figure class="wp-block-image size-full"><img decoding="async" width="425" height="425" src="https://atra.consulting/wp-content/uploads/2025/01/profilbild-daniel-wochnik-500-x-500px.jpg" alt="Daniel Wochnik, Geschäftsbereichsleitung Finanzdienstleistungen" class="wp-image-3216" style="object-fit:cover" title="Team-Schwarze"/></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<h3 class="wp-block-heading">Daniel Wochnik</h3>



<p class="wp-block-paragraph">Geschäftsbereichsleitung »Finanzdienstleistungen«</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">Daniel ist seit 2017 in der IT-Branche aktiv und bringt seine umfassende Erfahrung als Senior Managing Consultant und Geschäftsbereichsleiter für Finanzdienstleistungen bei atra.consulting ein. Besonders begeistert ihn das Zusammenspiel technischer, methodischer und organisatorischer Aspekte. Als leidenschaftlicher Läufer und bekennender 1. FC Köln-Fan hat er seine Leidensfähigkeit auch privat mehrfach unter Beweis gestellt. Seine Kunden unterstützt er als Softwarearchitekt, agiler Coach und Berater bei der nachhaltigen und zielgerichteten Umsetzung von Entwicklungsprojekten.</p>



<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-8f761849 wp-block-group-is-layout-flex">
<p class="wp-block-paragraph"><a href="mailto:d.wochnik@atra.consulting">d.wochnik@atra.consulting</a>&nbsp; &nbsp;&nbsp;<a href="https://de.linkedin.com/in/daniel-wochnik" target="_blank" rel="noreferrer noopener"></a></p>



<ul class="wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a href="https://de.linkedin.com/in/daniel-wochnik" class="wp-block-social-link-anchor" target="_blank" rel="noopener"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li></ul>
</div>
</div>
</div>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
