<?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>Wed, 06 May 2026 07:32:30 +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>JAX 2026: Lessons from Claude Code in production</title>
		<link>https://atra.consulting/engineering/jax-2026-lessons-from-claude-code-in-production/</link>
		
		<dc:creator><![CDATA[Karsten Silz]]></dc:creator>
		<pubDate>Wed, 06 May 2026 07:32:26 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[KI]]></category>
		<category><![CDATA[Konferenz]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=9814</guid>

					<description><![CDATA[I’m reporting my experiences with Claude Code across nine production applications since July 2025: cloud microservices with Kotlin, Java monoliths, web applications, a mobile app, and marketing websites. ]]></description>
										<content:encoded><![CDATA[
<details class="wp-block-details foldable-info-box has-background is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary>Inhaltsverzeichnis</summary>
<p class="wp-block-paragraph"></p>



<div class="wp-block-rank-math-toc-block" id="rank-math-toc"><nav><ul><li class=""><a href="#summary￼">Summary￼</a></li><li class=""><a href="#logistics￼">Logistics￼</a><ul><li class=""><a href="#location￼">Location￼</a></li><li class=""><a href="#talk￼">Talk</a></li><li class=""><a href="#abstract">Abstract</a></li></ul></li><li class=""><a href="#slides￼">Slides￼</a></li><li class=""><a href="#repo-with-skills-subagents￼">Repo with Skills &amp; Subagents￼</a><ul><li class=""><a href="#the-sample-application￼">The Sample Application￼</a></li><li class=""><a href="#skills-subagents￼">Skills &amp; Subagents￼</a></li></ul></li><li class=""><a href="#training￼-1">Training￼</a><ul><li class=""><a href="#karsten-silz">Karsten Silz</a></li></ul></li></ul></nav></div>
</details>



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



<h2 id="summary￼" class="wp-block-heading">Summary<a href="https://atra-homepage.vercel.app/blog/claude-code-jax-2026#summary" target="_blank" rel="noopener"></a></h2>



<p class="wp-block-paragraph">Here’s what I learned from nine production projects with Claude Code:</p>



<ul class="wp-block-list">
<li>You must use Coding Agents if you haven’t yet!</li>



<li>“Is AI right?” is the most important question.</li>



<li>Treat Coding Agents as a non-deterministic, forgetful junior team that you should let write and test.</li>



<li>Skills automate tasks, Subagents write better code faster.</li>



<li>AI will steal “writing code” but not yet “AI team lead”.</li>
</ul>



<p class="wp-block-paragraph">Please see my slides for an explanation of why I came to this conclusion.</p>



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



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



<h2 id="logistics￼" class="wp-block-heading">Logistics<a href="https://atra-homepage.vercel.app/blog/claude-code-jax-2026#logistics" target="_blank" rel="noopener"></a></h2>



<h3 id="location￼" class="wp-block-heading">Location<a href="https://atra-homepage.vercel.app/blog/claude-code-jax-2026#location" target="_blank" rel="noopener"></a></h3>



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



<p class="wp-block-paragraph">I’ll give the talk at <a href="https://jax.de/big-data-machine-learning/erfahrungen-mit-claude-code-in-produktion" target="_blank" rel="noopener">JAX 2026</a>.</p>



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



<h3 id="talk￼" class="wp-block-heading">Talk</h3>



<p class="wp-block-paragraph">My talk is part of the JAX 2026 program — date and time are on the&nbsp;<a href="https://jax.de/big-data-machine-learning/erfahrungen-mit-claude-code-in-produktion" target="_blank" rel="noopener">session page</a>.</p>



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



<h3 id="abstract" class="wp-block-heading">Abstract</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">
<p class="wp-block-paragraph">Deutsch</p>



<p class="wp-block-paragraph">Ich berichte von meinen Erfahrungen mit Claude Code in neun Produktionsanwendungen seit Juli 2025: Cloud-Microservices mit Kotlin, Java-Monolithen, Web-Anwendungen, mobile App und Marketing-Webseiten. Vier dieser Projekte waren neu.</p>



<p class="wp-block-paragraph">Was habe ich gelernt? Für uns Enterprise-Entwickler bedeutet Agentic AI, viele „Junior-Ichs” anzuleiten, die den Großteil unserer Arbeit übernehmen können. Und das ist mehr als nur Code zu schreiben! Wie alle Junior-Entwickler müssen wir die AI einarbeiten, ihre Pläne prüfen und ihr beibringen, wann sie tatsächlich fertig ist. Anders als wir vergisst die AI aber leider alles, was wir ihr sagen — und lernt auch nichts von ihrer Arbeit für uns.</p>
</div>



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



<p class="wp-block-paragraph">I’m reporting my experiences with Claude Code across nine production applications since July 2025: cloud microservices with Kotlin, Java monoliths, web applications, a mobile app, and marketing websites. Four of these projects were brand-new.</p>



<p class="wp-block-paragraph">What have I learned? For us enterprise developers, Agentic AI means guiding many “Junior Me” who can take over the bulk of our work. And that’s more than just writing code! Like all junior developers, we have to onboard the AI, review its plans, and teach it when it’s actually finished. Unlike us, however, the AI unfortunately forgets everything we tell it — and doesn’t learn anything from the work it does for us.</p>
</div>
</div>



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



<p class="wp-block-paragraph">I’ve worked on nine production systems with Claude Code. I teach a sustainable, principled approach, not short-term tuning that’s outdated tomorrow. I’m also a Senior Editor in the InfoQ Java Team, which gives me valuable insights into today’s software industry.</p>



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



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



<h2 id="slides￼" class="wp-block-heading">Slides<a href="https://atra-homepage.vercel.app/blog/claude-code-jax-2026#slides" target="_blank" rel="noopener"></a></h2>



<div class="wp-block-file"><a id="wp-block-file--media-2da7e158-b5ff-465b-aafa-27b764b8d28e" href="https://atra.consulting/wp-content/uploads/2026/05/Claude-Code-Gelernt-JAX-2026.pdf" target="_blank" rel="noreferrer noopener">Claude Code Gelernt JAX 2026</a><a href="https://atra.consulting/wp-content/uploads/2026/05/Claude-Code-Gelernt-JAX-2026.pdf" class="wp-block-file__button wp-element-button" aria-describedby="wp-block-file--media-2da7e158-b5ff-465b-aafa-27b764b8d28e" download>Herunterladen</a></div>



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



<h2 id="repo-with-skills-subagents￼" class="wp-block-heading">Repo with Skills &amp; Subagents<a href="https://atra-homepage.vercel.app/blog/claude-code-jax-2026#repo-with-skills--subagents" target="_blank" rel="noopener"></a></h2>



<h3 id="the-sample-application￼" class="wp-block-heading">The Sample Application<a href="https://atra-homepage.vercel.app/blog/claude-code-jax-2026#the-sample-application" target="_blank" rel="noopener"></a></h3>



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



<p class="wp-block-paragraph">The repository with the sample CRM application from the talk is at <a href="https://github.com/atra-consulting/coding-with-ai-lab" target="_blank" rel="noopener">github.com/atra-consulting/coding-with-ai-lab</a>. The <a href="https://github.com/atra-consulting/coding-with-ai-lab/blob/main/README.MD" target="_blank" rel="noopener">README</a> describes the requirements and how to get it started.</p>



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



<h3 id="skills-subagents￼" class="wp-block-heading">Skills &amp; Subagents<a href="https://atra-homepage.vercel.app/blog/claude-code-jax-2026#skills--subagents" target="_blank" rel="noopener"></a></h3>



<p class="wp-block-paragraph">The <a href="https://github.com/atra-consulting/coding-with-ai-lab/tree/main/.claude/skills" target="_blank" rel="noopener">skills are here</a>, and the <a href="https://github.com/atra-consulting/coding-with-ai-lab/tree/main/.claude/agents" target="_blank" rel="noopener">subagents are here</a>. Both are for Claude Code and Claude Desktop. There are <a href="https://github.com/atra-consulting/coding-with-ai-lab/tree/main/.gemini" target="_blank" rel="noopener">outdated versions for Google Gemini</a> that are no longer actively maintained.</p>



<p class="wp-block-paragraph">Please see the talk slides for a description of the agents and skills.</p>



<p class="wp-block-paragraph" id="training￼">You can use the skills and subagents in your own projects. Copy the agents into your project. Then tell Claude:Training<a href="https://atra-homepage.vercel.app/blog/claude-code-jax-2026#training" target="_blank" rel="noopener"></a></p>



<pre class="wp-block-code"><code>Adapt these skills/agents to my technology stack here. Think hard when you do, and review them.</code></pre>



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



<h2 id="training￼-1" class="wp-block-heading">Training<a href="https://atra-homepage.vercel.app/blog/claude-code-jax-2026#training" target="_blank" rel="noopener"></a></h2>



<p class="wp-block-paragraph">atra.consulting offers <a href="https://atra-homepage.vercel.app/ki-loesungen/" target="_blank" rel="noopener">AI training</a>, including a hands-on workshop on agent-based coding.</p>



<div style="height:40px" 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" src="https://atra.consulting/wp-content/uploads/2026/05/karsten-silz.webp" alt="" class="wp-image-9800" 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">Karsten Silz</h3>



<p class="wp-block-paragraph">Senior Principal Consultant Software Engineering</p>



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



<p class="wp-block-paragraph">Karsten arbeitet seit 26 Jahren als Full-Stack-Java-Entwickler in Europa und den USA. Als Mitgründer leitete er 13 Jahre lang die Produktentwicklung eines Software-Produkt-Start-ups in den USA, das 2016 erfolgreich verkauft wurde. Im Jahr 2020 war er Mitgründer eines SaaS-Start-ups in England. Er ist seit 2003 auch Freiberufler. Seit Mai 2025 arbeitet er für atra.consulting in Stuttgart.</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:k.silz@expert.atra.consulting" data-type="mailto" data-id="mailto:k.silz@expert.atra.consulting">k.silz@expert.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>JAX 2026: How can I start Java faster—and when is it worth it?</title>
		<link>https://atra.consulting/engineering/jax-2026-start-java-faster/</link>
		
		<dc:creator><![CDATA[Karsten Silz]]></dc:creator>
		<pubDate>Tue, 05 May 2026 08:17:25 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">https://atra.consulting/?p=9768</guid>

					<description><![CDATA[This is how Java applications can start faster – sorted by ascending speed gains: Framework tuning, Class Data Sharing (CDS), Project Leyden/JEP 483 (from Java 24 onward), CRaC, and GraalVM Native Image. ]]></description>
										<content:encoded><![CDATA[
<details class="wp-block-details foldable-info-box has-background is-layout-flow wp-block-details-is-layout-flow" style="background-color:#828282"><summary>Inhaltsverzeichnis</summary>
<div class="wp-block-rank-math-toc-block" id="rank-math-toc"><nav><ul><li class=""><a href="#summary￼">Summary￼</a></li><li class=""><a href="#logistics￼">Logistics￼</a><ul><li class=""><a href="#location￼">Location￼</a></li><li class=""><a href="#talk￼">Talk￼</a></li><li class=""><a href="#abstract￼">Abstract</a></li></ul></li><li class=""><a href="#who-made-me-the-expert-￼">Who Made Me the Expert?￼</a></li><li class=""><a href="#benchmark-repo￼">Benchmark Repo￼</a><ul><li class=""><a href="#usage￼">Usage￼</a></li><li class=""><a href="#measuring-startup-time-and-memory￼">Measuring Startup Time and Memory￼</a></li><li class=""><a href="#notes￼">Notes￼</a></li></ul></li><li class=""><a href="#additional-talk-information￼">Additional Talk Information￼</a><ul><li class=""><a href="#intro￼">Intro￼</a></li><li class=""><a href="#is-it-worth-it-￼">Is it worth it?￼</a><ul><li class=""><a href="#information￼">Information￼</a></li><li class=""><a href="#sample-return-on-investment-calculation￼">Sample Return on Investment Calculation￼</a></li></ul></li><li class=""><a href="#how-to-start-faster-￼">How to start faster?￼</a><ul><li class=""><a href="#spring-boot-tuning￼">Spring Boot Tuning￼</a></li><li class=""><a href="#class-data-sharing-project-leyden￼">Class Data Sharing &amp; Project Leyden￼</a></li><li class=""><a href="#project-c-ra-c￼">Project CRaC￼</a></li><li class=""><a href="#graal-vm-native-image￼">GraalVM Native Image￼</a></li></ul></li></ul></li><li class=""><a href="#slides￼">Slides￼</a><ul><li class=""><a href="#karsten-silz">Karsten Silz</a></li></ul></li></ul></nav></div>
</details>



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



<h2 id="summary￼" class="wp-block-heading">Summary<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#summary" target="_blank" rel="noopener"></a></h2>



<p class="wp-block-paragraph">Starting Java faster could be worthwhile when you:</p>



<ul class="wp-block-list">
<li>use serverless computing (like Amazon Lambda),</li>



<li>run many servers, or</li>



<li>aim for very high availability.</li>
</ul>



<p class="wp-block-paragraph">By design, Java uses more time, more CPU, and more memory.</p>



<p class="wp-block-paragraph">We can get Java to start faster with:</p>



<ul class="wp-block-list">
<li>Spring Boot Tuning</li>



<li>Class Data Sharing (CDS) &amp; Project Leyden</li>



<li>Project CRaC</li>



<li>GraalVM Native Image</li>
</ul>



<p class="wp-block-paragraph">Please see my slides for why I came to this conclusion.</p>



<p class="wp-block-paragraph"><strong>Additional information about the slides <a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#benchmark-repo" target="_blank" rel="noopener">is below</a>.</strong></p>



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



<h2 id="logistics￼" class="wp-block-heading">Logistics<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#logistics" target="_blank" rel="noopener"></a></h2>



<h3 id="location￼" class="wp-block-heading">Location<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#location" target="_blank" rel="noopener"></a></h3>



<p class="wp-block-paragraph">I’ll give the talk at <a href="https://jax.de/performance-security/java-startup-time-performance-optimierung/" target="_blank" rel="noopener">JAX 2026</a>.</p>



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



<h3 id="talk￼" class="wp-block-heading">Talk<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#talk" target="_blank" rel="noopener"></a></h3>



<p class="wp-block-paragraph">My talk is part of the JAX 2026 program — date and time are on the <a href="https://jax.de/performance-security/java-startup-time-performance-optimierung/" target="_blank" rel="noopener">session page</a>.</p>



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



<h3 id="abstract￼" class="wp-block-heading">Abstract</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">
<p class="wp-block-paragraph">Deutsch</p>



<p class="wp-block-paragraph">So können Java-Anwendungen schneller starten – sortiert nach aufsteigendem Geschwindigkeitsgewinn: Framework-Tuning, Class Data Sharing (CDS), Project Leyden/JEP 483 (ab Java 24), CRaC und GraalVM Native Image. Aber: Je schneller der Start, desto größer sind Aufwand und Beschränkungen. Das kann sich lohnen, weil die Uptime der Anwendung steigt, die Anzahl der Standby-Instanzen sinkt oder Serverless Computing billiger wird.</p>



<p class="wp-block-paragraph">Der Vortrag demonstriert mit einem Spring-Boot-Beispiel-Projekt alle Optionen, erklärt Vor- und Nachteile und gibt Hinweise für die Wirtschaftlichkeitsberechnung.</p>
</div>



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



<p class="wp-block-paragraph">This is how Java applications can start faster – sorted by ascending speed gains: Framework tuning, Class Data Sharing (CDS), Project Leyden/JEP 483 (from Java 24 onward), CRaC, and GraalVM Native Image. However: The faster the startup, the greater the effort and limitations. This can be worthwhile because application uptime increases, the number of standby instances decreases, or serverless computing becomes cheaper.</p>



<p class="wp-block-paragraph">The talk demonstrates all options using a Spring Boot example project, explains pros and cons, and provides guidance for cost-benefit calculations.</p>
</div>
</div>



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



<h2 id="who-made-me-the-expert-￼" class="wp-block-heading">Who Made Me the Expert?<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#who-made-me-the-expert" target="_blank" rel="noopener"></a></h2>



<p class="wp-block-paragraph">In the spring of 2022, I was the editor of a highly popular <a href="https://www.infoq.com/articles/native-compilations-boosts-java/" target="_blank" rel="noopener">six-part article series about native Java on InfoQ</a>. I wrote several articles about Project Leyden, CRaC, and GraalVM Native Image, and gave talks about them too.</p>



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



<h2 id="benchmark-repo￼" class="wp-block-heading">Benchmark Repo<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#benchmark-repo" target="_blank" rel="noopener"></a></h2>



<h3 id="usage￼" class="wp-block-heading">Usage<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#usage" target="_blank" rel="noopener"></a></h3>



<p class="wp-block-paragraph"><a href="https://github.com/ksilz/spring-petclinic" target="_blank" rel="noopener">The repo</a> is a fork of the <a href="https://github.com/spring-projects/spring-petclinic" target="_blank" rel="noopener">official Spring Petclinic</a>. I added the shell scripts for building the project (<a href="https://github.com/ksilz/spring-petclinic/blob/main/compile-and-run.sh" target="_blank" rel="noopener"><code>compile-and-run.sh</code></a>) and for the training and benchmark runs (<a href="https://github.com/ksilz/spring-petclinic/blob/main/benchmark.sh" target="_blank" rel="noopener"><code>benchmark.sh</code></a>), added a small library for CRaC, and ignored some files. The scripts are <strong>only tested for Linux and macOS</strong>.</p>



<p class="wp-block-paragraph">You can run the six benchmarks yourself with <code>./compile-and-run.sh [scenario]</code>, where <code>scenario</code> is one of these:</p>



<ul class="wp-block-list">
<li><code>baseline</code> — the baseline scenario of plain Spring Boot, option 0 in my talk. Needs JDK 25.</li>



<li><code>tuning</code> — Spring Boot tuning, option 1 in my talk. Needs JDK 25.</li>



<li><code>cds</code> — Class Data Sharing, part of option 2 in my talk. Needs JDK 25.</li>



<li><code>leyden</code> — Project Leyden, part of option 2 in my talk. Needs JDK 25.</li>



<li><code>crac</code> — Project CRaC, option 3 in my talk. Needs JDK 25 from Azul with CRaC support, and only works on Linux.</li>



<li><code>graalvm</code> — GraalVM Native Image, option 4 in my talk. Needs GraalVM Oracle JDK 25 and a lot of memory — 16 GB weren’t enough.</li>
</ul>



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



<h3 id="measuring-startup-time-and-memory￼" class="wp-block-heading">Measuring Startup Time and Memory<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#measuring-startup-time-and-memory" target="_blank" rel="noopener"></a></h3>



<p class="wp-block-paragraph">The <a href="https://github.com/ksilz/spring-petclinic/blob/main/benchmark.sh" target="_blank" rel="noopener">benchmark script</a> performs three warmup runs, then seven benchmark runs. It discards the fastest and slowest benchmark run and then takes the average of the remaining five runs.</p>



<p class="wp-block-paragraph">Startup time is measured in two ways:</p>



<ul class="wp-block-list">
<li>For CRaC, the script looks for the text <code>restored JVM running for X ms</code> in the Spring Boot log.</li>



<li>For all other scenarios, it looks for <code>Started PetClinicApplication in X.XXX seconds</code>.</li>
</ul>



<p class="wp-block-paragraph">Memory consumption is measured by running the benchmarked application through <code>/usr/bin/time</code> and reading the memory from the output:</p>



<ul class="wp-block-list">
<li>macOS: uses <code>peak memory footprint</code> from <code>/usr/bin/time -l</code></li>



<li>Linux: uses <code>Maximum resident set size</code> from <code>/usr/bin/time -v</code></li>
</ul>



<p class="wp-block-paragraph">The script converts to KB for consistency, but displays in MB for output.</p>



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



<h3 id="notes￼" class="wp-block-heading">Notes<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#notes" target="_blank" rel="noopener"></a></h3>



<ul class="wp-block-list">
<li>I created these scripts with the <a href="https://cursor.com/" target="_blank" rel="noopener">AI IDE Cursor</a>, then updated them with <a href="https://www.claude.com/product/claude-code" target="_blank" rel="noopener">Claude Code</a>. This may account for some weirdness you see in the script.</li>



<li>I originally wanted to include Maven build commands. The skeleton’s still in there, but it does not work at all.</li>
</ul>



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



<h2 id="additional-talk-information￼" class="wp-block-heading">Additional Talk Information<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#additional-talk-information" target="_blank" rel="noopener"></a></h2>



<h3 id="intro￼" class="wp-block-heading">Intro<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#intro" target="_blank" rel="noopener"></a></h3>



<p class="wp-block-paragraph">Here is the <a href="https://www.infoq.com/articles/native-compilations-boosts-java/" target="_blank" rel="noopener">six-part article series about native Java on InfoQ</a> from 2022. I wasn’t the author, I was the editor. The articles and news items I wrote <a href="https://www.infoq.com/profile/Karsten-Silz/#allActivity" target="_blank" rel="noopener">are here</a>.</p>



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



<h3 id="is-it-worth-it-￼" class="wp-block-heading">Is it worth it?<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#is-it-worth-it" target="_blank" rel="noopener"></a></h3>



<h4 id="information￼" class="wp-block-heading">Information<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#information" target="_blank" rel="noopener"></a></h4>



<ul class="wp-block-list">
<li>AWS Lambda SnapStart is <a href="https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html" target="_blank" rel="noopener">described here</a>.</li>



<li>An example of Java being more expensive is <a href="https://www.infoq.com/news/2025/06/apple-swift-migration" target="_blank" rel="noopener">Apple’s migration to Swift</a> for parts of its password system.</li>



<li>The original description of Java appears in an InfoQ article on Java’s 30th birthday.</li>
</ul>



<h4 id="sample-return-on-investment-calculation￼" class="wp-block-heading">Sample Return on Investment Calculation<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#sample-return-on-investment-calculation" target="_blank" rel="noopener"></a></h4>



<p class="wp-block-paragraph">The scenario is that a microservice Java application on Kubernetes wants to reduce operational costs. The approach is to switch to GraalVM Native Image for compilation and reduce memory consumption. This will lead to more pods fitting on a Kubernetes node, reducing the servers needed.</p>



<p class="wp-block-paragraph">Here are the assumptions:</p>



<ul class="wp-block-list">
<li>The project runs on Kubernetes in Linux on Amazon EC2 T3.2XLarge servers (32 GB RAM, 8 CPUs). That server costs 280 Euro per month, which means 10,080 Euro over 36 months.</li>



<li>Developers work on macOS and debug production applications inside a Linux container.</li>



<li>A developer / admin has costs of 100 Euro/hour.</li>



<li>The investment has to have a positive Return on Investment (ROI) after three years.</li>
</ul>



<p class="wp-block-paragraph">Here are the labor costs:</p>



<ul class="wp-block-list">
<li>One-time introduction (changing build &amp; deployment, training developers): 120 hours = 12,000 Euro</li>



<li>Monthly maintenance: 4 hours × 30 months = 120 hours = 12,000 Euro</li>



<li>Upgrades every six months (Spring Boot, GraalVM): 16 hours × 5 = 80 hours = 8,000 Euro</li>



<li>Loss of productivity (debugging native executables for production problems): 4 hours × 35 months = 140 hours = 14,000 Euro</li>



<li><strong>Total labor cost over three years: 46,000 Euro</strong></li>
</ul>



<p class="wp-block-paragraph">Here are the operational costs:</p>



<ul class="wp-block-list">
<li>Amazon EC2 T3.2XLarge as additional build server (32 GB RAM, 8 CPUs): <strong>10,080 Euro</strong></li>
</ul>



<p class="wp-block-paragraph">The total cost is 46,000 Euro for labor plus 10,080 Euro for operations, for a <strong>grand total cost of 56,080 Euro</strong>.</p>



<p class="wp-block-paragraph">In order to have a positive ROI, using GraalVM Native Image needs to reduce the number of Amazon EC2 T3.2XLarge servers in Kubernetes by at least six, which would <strong>reduce costs by 10,080 Euro × 6 = 60,480 Euro</strong>. That <strong>saves 4,400 Euro over three years</strong>.</p>



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



<h3 id="how-to-start-faster-￼" class="wp-block-heading">How to start faster?<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#how-to-start-faster" target="_blank" rel="noopener"></a></h3>



<h4 id="spring-boot-tuning￼" class="wp-block-heading">Spring Boot Tuning<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#spring-boot-tuning" target="_blank" rel="noopener"></a></h4>



<ul class="wp-block-list">
<li>Spring AOT is <a href="https://docs.spring.io/spring-framework/reference/core/aot.html" target="_blank" rel="noopener">documented here</a>, the <a href="https://docs.spring.io/spring-boot/reference/packaging/efficient.html" target="_blank" rel="noopener">JAR extraction here</a>. <a href="https://www.baeldung.com/spring-6-ahead-of-time-optimizations" target="_blank" rel="noopener">This Baeldung article</a> describes both.</li>



<li>Here are some Spring tickets that were still open at the time of writing: <a href="https://github.com/spring-cloud/spring-cloud-stream/issues/3118" target="_blank" rel="noopener">one</a>, <a href="https://github.com/spring-projects/spring-statemachine/issues/1080" target="_blank" rel="noopener">two</a>, and <a href="https://github.com/spring-projects/spring-boot/issues/37101" target="_blank" rel="noopener">three</a>.</li>
</ul>



<h4 id="class-data-sharing-project-leyden￼" class="wp-block-heading">Class Data Sharing &amp; Project Leyden<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#class-data-sharing--project-leyden" target="_blank" rel="noopener"></a></h4>



<ul class="wp-block-list">
<li>Spring describes <a href="https://docs.spring.io/spring-boot/how-to/class-data-sharing.html" target="_blank" rel="noopener">Class Data Sharing here</a>.</li>



<li>This is <a href="https://openjdk.org/projects/leyden/" target="_blank" rel="noopener">Project Leyden’s home page</a>. Here’s <a href="https://www.infoq.com/news/2025/03/java-24-leyden-ships/" target="_blank" rel="noopener">my article about it shipping in JDK 24</a>.</li>



<li>These are the JEPs of Project Leyden: <a href="https://openjdk.org/jeps/483" target="_blank" rel="noopener">JEP 483</a>, <a href="https://openjdk.org/jeps/514" target="_blank" rel="noopener">JEP 514</a>, <a href="https://openjdk.org/jeps/515" target="_blank" rel="noopener">JEP 515</a>, <a href="https://openjdk.org/jeps/516" target="_blank" rel="noopener">JEP 516</a>, and a <a href="https://openjdk.org/jeps/8335368" target="_blank" rel="noopener">JEP draft</a>.</li>
</ul>



<h4 id="project-c-ra-c￼" class="wp-block-heading">Project CRaC<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#project-crac" target="_blank" rel="noopener"></a></h4>



<ul class="wp-block-list">
<li>This is <a href="https://openjdk.org/projects/crac/" target="_blank" rel="noopener">Project CRaC’s home page</a>.</li>



<li>Here Oracle’s Java Language Architect <a href="https://www.youtube.com/watch?v=O1Oz2-AXKKM&amp;t=3230s" target="_blank" rel="noopener">Brian Goetz discusses CRaC</a>.</li>



<li><a href="https://www.azul.com/products/components/crac/" target="_blank" rel="noopener">This is Azul’s OpenJDK with CRaC support page</a>, and here’s <a href="https://bell-sw.com/libericajdk-with-crac/" target="_blank" rel="noopener">Bellsoft’s Liberica JDK with CRaC support</a>.</li>



<li>Here are the releases of major Java frameworks that added CRaC support: <a href="https://www.infoq.com/articles/spring-boot-3-2-spring-6-1" target="_blank" rel="noopener">Spring Boot 3.2</a>, <a href="https://github.com/CRaC/docs?tab=readme-ov-file#quarkus" target="_blank" rel="noopener">Quarkus 2.10.0</a>, <a href="https://micronaut.io/2022/09/21/micronaut-framework-3-7-0-released/" target="_blank" rel="noopener">Micronaut 3.7</a>, and <a href="https://medium.com/helidon/helidon-4-2-released-fa94afe4945a" target="_blank" rel="noopener">Helidon 4.2</a>.</li>
</ul>



<h4 id="graal-vm-native-image￼" class="wp-block-heading">GraalVM Native Image<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#graalvm-native-image" target="_blank" rel="noopener"></a></h4>



<ul class="wp-block-list">
<li>This is the <a href="https://www.graalvm.org/latest/reference-manual/native-image/" target="_blank" rel="noopener">GraalVM documentation of Native Image</a>. And here’s the <a href="https://docs.spring.io/spring-boot/reference/packaging/native-image/introducing-graalvm-native-images.html" target="_blank" rel="noopener">Spring Boot documentation for it</a>.</li>



<li>Java frameworks like Spring Boot typically ship with the Native Image configuration information for their libraries, like Spring Security or Spring Data.</li>



<li>The <a href="https://github.com/oracle/graalvm-reachability-metadata" target="_blank" rel="noopener">GraalVM Reachability Metadata Repository</a> contains the Native Image configuration for popular Java libraries. Native Image uses it automatically.</li>



<li>These are features that are impossible with GraalVM Native Image:
<ul class="wp-block-list">
<li>creating new classes and methods at runtime,</li>



<li>executing new bytecode,</li>



<li>rather exotic classloader features, and</li>



<li>Java Agents (used for observability, for instance).</li>
</ul>
</li>



<li>Here are features that only work partially:
<ul class="wp-block-list">
<li>AWT and JavaFX (not on macOS),</li>



<li>JMX,</li>



<li>many Java Flight Recorder datapoints, and</li>



<li>some testing frameworks.</li>
</ul>
</li>



<li>These features require configuration:
<ul class="wp-block-list">
<li>reflection, and</li>



<li>explicit class loading.</li>
</ul>
</li>
</ul>



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



<h2 id="slides￼" class="wp-block-heading">Slides<a href="https://atra-homepage.vercel.app/blog/java-startup-jax-2026#slides" target="_blank" rel="noopener"></a></h2>



<p class="wp-block-paragraph">The PDF has more content and more text than my talking slides — the Keynote source is the actual deck I present from.</p>



<p class="wp-block-paragraph">My talking slides have less text than the PDF version, so you can see what I cut. I also animated them, so they’re more pleasant to watch. Or maybe you want to peek under the hood to see how I achieved specific effects. They have fewer words than the PDF — it’s a talk, not a read! But they do have speaker notes.</p>



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



<div class="wp-block-file"><a id="wp-block-file--media-d266e7c0-7bed-48d5-b6de-63da4fd2fd2f" href="https://atra.consulting/wp-content/uploads/2026/05/JAX-2026-Java-Startup-Schneller.pdf" target="_blank" rel="noreferrer noopener">JAX 2026 Java Startup Schneller</a><a href="https://atra.consulting/wp-content/uploads/2026/05/JAX-2026-Java-Startup-Schneller.pdf" class="wp-block-file__button wp-element-button" aria-describedby="wp-block-file--media-d266e7c0-7bed-48d5-b6de-63da4fd2fd2f" download>Herunterladen</a></div>



<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" src="https://atra.consulting/wp-content/uploads/2026/05/karsten-silz.webp" alt="" class="wp-image-9800" 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">Karsten Silz</h3>



<p class="wp-block-paragraph">Senior Principal Consultant Software Engineering</p>



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



<p class="wp-block-paragraph">Karsten arbeitet seit 26 Jahren als Full-Stack-Java-Entwickler in Europa und den USA. Als Mitgründer leitete er 13 Jahre lang die Produktentwicklung eines Software-Produkt-Start-ups in den USA, das 2016 erfolgreich verkauft wurde. Im Jahr 2020 war er Mitgründer eines SaaS-Start-ups in England. Er ist seit 2003 auch Freiberufler. Seit Mai 2025 arbeitet er für atra.consulting in Stuttgart.</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:k.silz@expert.atra.consulting" data-type="mailto" data-id="mailto:k.silz@expert.atra.consulting">k.silz@expert.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>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;6a22b6dfc1ddc&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfc1ddc" 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;6a22b6dfc3b1f&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfc3b1f" 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;6a22b6dfc659c&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfc659c" 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;6a22b6dfc76eb&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfc76eb" 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;6a22b6dfc8999&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfc8999" 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;6a22b6dfc9a5a&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfc9a5a" 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;6a22b6dfd86b7&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfd86b7" 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;6a22b6dfd97a2&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfd97a2" 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;6a22b6dfda32d&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfda32d" 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;6a22b6dfdb119&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfdb119" 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;6a22b6dfdbd2e&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfdbd2e" 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;6a22b6dfdc8de&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfdc8de" 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;6a22b6dfdd572&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfdd572" 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;6a22b6dfde25c&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfde25c" 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;6a22b6dfdede7&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfdede7" 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;6a22b6dfdfad4&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfdfad4" 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;6a22b6dfe0856&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe0856" 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;6a22b6dfe1931&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe1931" 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;6a22b6dfe2c2f&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe2c2f" 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;6a22b6dfe3b13&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe3b13" 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;6a22b6dfe4d53&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe4d53" 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;6a22b6dfe5ad4&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe5ad4" 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;6a22b6dfe6883&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe6883" 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;6a22b6dfe7574&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe7574" 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;6a22b6dfe8312&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe8312" 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;6a22b6dfe925f&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfe925f" 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;6a22b6dfea254&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfea254" 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;6a22b6dfeb085&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dfeb085" 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;6a22b6dff336a&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6dff336a" 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;6a22b6e0001a5&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6e0001a5" 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;6a22b6e001113&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6e001113" 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;6a22b6e002a36&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6e002a36" 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;6a22b6e00a0b7&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6e00a0b7" 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;6a22b6e00af46&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6e00af46" 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;6a22b6e00c6b4&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6e00c6b4" 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;6a22b6e011d5d&quot;}" data-wp-interactive="core/image" data-wp-key="6a22b6e011d5d" 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>
	</channel>
</rss>
