{"id":708,"date":"2026-07-02T23:38:16","date_gmt":"2026-07-02T22:38:16","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=708"},"modified":"2026-07-07T23:38:55","modified_gmt":"2026-07-07T22:38:55","slug":"domain-driven-design-im-code-erzwingen-mit-jmolecules-archunit","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=708","title":{"rendered":"Domain-Driven Design im Code erzwingen mit jMolecules &amp; ArchUnit"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Domain-Driven Design (DDD) verspricht bessere Software durch eine gemeinsame Sprache und klare Architekturmuster. In der Praxis scheitert DDD oft an einem: Der Code verletzt die Regeln, die das Design vorschreibt. Repositories geben keine Aggregates zur\u00fcck, Value Objects sind nicht immutable, und Entities werden direkt statt \u00fcber ihre Aggregate Root angesprochen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">jMolecules l\u00f6st dieses Problem, indem es DDD-Konzepte als Java-Annotationen und Typsystem ausdr\u00fcckt \u2014 und ArchUnit erzwingt deren Einhaltung zur Build-Zeit.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">jMolecules 2.0: DDD im Typsystem verankern<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">jMolecules (aktuell&nbsp;<strong>2.0.1<\/strong>) unterscheidet sich fundamental von anderen DDD-Bibliotheken: Es geht nicht um Code-Generierung, sondern um die&nbsp;<strong>Abbildung fachlicher Konzepte im Code<\/strong>&nbsp;\u2014 ohne Suffixe wie&nbsp;<code>CustomerEntity<\/code>&nbsp;oder&nbsp;<code>MoneyVO<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Die Annotationen<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">import org.jmolecules.ddd.annotation.*;\nimport java.util.UUID;\n\n@AggregateRoot\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Bestellung<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> @Identity BestellId id;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">List<\/span>&lt;Bestellposten&gt; posten = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();\n    <span class=\"hljs-keyword\">private<\/span> Geld gesamtbetrag = Geld.EURO(<span class=\"hljs-number\">0<\/span>);\n\n    <span class=\"hljs-keyword\">private<\/span> Bestellung() {}\n\n    <span class=\"hljs-keyword\">public<\/span> Bestellung(BestellId id) { this.id = id; }\n\n    <span class=\"hljs-keyword\">public<\/span> void postenHinzufuegen(BestellpostenId id, String beschreibung,\n                                   Geld preis, Menge menge) {\n        Bestellposten p = <span class=\"hljs-keyword\">new<\/span> Bestellposten(id, beschreibung, preis, menge);\n        this.posten.add(p);\n        this.gesamtbetrag = this.gesamtbetrag.add(p.positionssumme());\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> BestellId getId() { <span class=\"hljs-keyword\">return<\/span> id; }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">List<\/span>&lt;Bestellposten&gt; getPosten() { <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">List<\/span>.copyOf(posten); }\n    <span class=\"hljs-keyword\">public<\/span> Geld getGesamtbetrag() { <span class=\"hljs-keyword\">return<\/span> gesamtbetrag; }\n}\n\n@Entity\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Bestellposten<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> @Identity BestellpostenId id;\n    <span class=\"hljs-keyword\">private<\/span> String beschreibung;\n    <span class=\"hljs-keyword\">private<\/span> Geld preis;\n    <span class=\"hljs-keyword\">private<\/span> Menge menge;\n\n    <span class=\"hljs-keyword\">private<\/span> Bestellposten() {}\n\n    <span class=\"hljs-keyword\">public<\/span> Bestellposten(BestellpostenId id, String beschreibung,\n                          Geld preis, Menge menge) {\n        this.id = id;\n        this.beschreibung = beschreibung;\n        this.preis = preis;\n        this.menge = menge;\n    }\n\n    Geld positionssumme() {\n        <span class=\"hljs-keyword\">return<\/span> preis.multiplizieren(menge.wert());\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Die&nbsp;<code>@Identity<\/code>-Annotation markiert das ID-Feld innerhalb von&nbsp;<code>@Entity<\/code>&nbsp;oder&nbsp;<code>@AggregateRoot<\/code>&nbsp;\u2014 essenziell f\u00fcr JPA-Mapping und Konsistenzpr\u00fcfungen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Value Objects \u2014 unver\u00e4nderlich per Design<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;em&gt;<span class=\"hljs-comment\">\/\/ Records sind der nat\u00fcrliche Value-Object-Typ in modernem Java&lt;\/em&gt;<\/span>\n@ValueObject\n<span class=\"hljs-keyword\">public<\/span> record BestellId(UUID wert) {\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> BestellId neu() { <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> BestellId(UUID.randomUUID()); }\n}\n\n@ValueObject\n<span class=\"hljs-keyword\">public<\/span> record Geld(long betragInCent, String waehrung) {\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> Geld EURO(long betragInCent) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Geld(betragInCent, <span class=\"hljs-string\">\"EUR\"<\/span>);\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> Geld add(Geld other) {\n        <span class=\"hljs-keyword\">if<\/span> (!waehrung.equals(other.waehrung))\n            <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException(<span class=\"hljs-string\">\"W\u00e4hrungen stimmen nicht \u00fcberein\"<\/span>);\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Geld(betragInCent + other.betragInCent, waehrung);\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> Geld multiplizieren(int faktor) {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Geld(betragInCent * faktor, waehrung);\n    }\n}\n\n@ValueObject\n<span class=\"hljs-keyword\">public<\/span> record Menge(int wert) {\n    <span class=\"hljs-keyword\">public<\/span> Menge {\n        <span class=\"hljs-keyword\">if<\/span> (wert &lt; <span class=\"hljs-number\">1<\/span>)\n            <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException(<span class=\"hljs-string\">\"Menge muss positiv sein\"<\/span>);\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Repository \u2014 das Tor zum Aggregate<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">@Repository\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">Bestellungen<\/span> <\/span>{\n    Bestellung speichern(Bestellung bestellung);\n    Optional&lt;Bestellung&gt; findeNachId(BestellId id);\n    <span class=\"hljs-keyword\">List<\/span>&lt;Bestellung&gt; findeAlle();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">ArchUnit: DDD-Regeln automatisch pr\u00fcfen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Das jMolecules-ArchUnit-Modul (<code>jmolecules-archunit<\/code>) liefert vier eingebaute Regeln:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">com<\/span><span class=\"hljs-selector-class\">.tngtech<\/span><span class=\"hljs-selector-class\">.archunit<\/span><span class=\"hljs-selector-class\">.junit<\/span><span class=\"hljs-selector-class\">.AnalyzeClasses<\/span>;\n<span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">com<\/span><span class=\"hljs-selector-class\">.tngtech<\/span><span class=\"hljs-selector-class\">.archunit<\/span><span class=\"hljs-selector-class\">.junit<\/span><span class=\"hljs-selector-class\">.ArchTest<\/span>;\n<span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">com<\/span><span class=\"hljs-selector-class\">.tngtech<\/span><span class=\"hljs-selector-class\">.archunit<\/span><span class=\"hljs-selector-class\">.lang<\/span><span class=\"hljs-selector-class\">.ArchRule<\/span>;\n<span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">org<\/span><span class=\"hljs-selector-class\">.jmolecules<\/span><span class=\"hljs-selector-class\">.archunit<\/span><span class=\"hljs-selector-class\">.JMoleculesDddRules<\/span>;\n\n<span class=\"hljs-keyword\">@AnalyzeClasses<\/span>(packages = <span class=\"hljs-string\">\"com.meinefirma.shop\"<\/span>)\npublic class DddRegelnTest {\n\n    <span class=\"hljs-keyword\">@ArchTest<\/span>\n    ArchRule dddRegeln = JMoleculesDddRules.all();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Diese vier Regeln werden gepr\u00fcft:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Entities nur innerhalb ihres Aggregates verwenden<\/strong>\u00a0\u2014 Ein\u00a0<code>Bestellposten<\/code>, der\u00a0<code>Bestellung<\/code>\u00a0als Owner deklariert, darf nicht in einem anderen Aggregate referenziert werden<\/li>\n\n\n\n<li><strong>Aggregate-Referenzen nur per ID oder\u00a0<code>Association<\/code><\/strong>\u00a0\u2014 Keine direkten Objektreferenzen auf andere Aggregate Roots<\/li>\n\n\n\n<li><strong><code>@Identity<\/code>-Feld ist Pflicht<\/strong>\u00a0\u2014 Jedes\u00a0<code>@Entity<\/code>\u00a0und\u00a0<code>@AggregateRoot<\/code>\u00a0muss ein\u00a0<code>@Identity<\/code>-Feld haben<\/li>\n\n\n\n<li><strong>Value Objects enthalten keine Entities<\/strong>\u00a0\u2014 Value Objects d\u00fcrfen weder Entities noch Aggregate Roots referenzieren<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Eigene Regeln definieren<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Neben den Built-in-Regeln kannst du eigene, dom\u00e4nenspezifische Constraints formulieren:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">static<\/span> <span class=\"hljs-selector-tag\">com<\/span><span class=\"hljs-selector-class\">.tngtech<\/span><span class=\"hljs-selector-class\">.archunit<\/span><span class=\"hljs-selector-class\">.lang<\/span><span class=\"hljs-selector-class\">.syntax<\/span><span class=\"hljs-selector-class\">.ArchRuleDefinition<\/span>.*;\n<span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">org<\/span><span class=\"hljs-selector-class\">.jmolecules<\/span><span class=\"hljs-selector-class\">.ddd<\/span><span class=\"hljs-selector-class\">.annotation<\/span>.*;\n<span class=\"hljs-selector-tag\">import<\/span> <span class=\"hljs-selector-tag\">org<\/span><span class=\"hljs-selector-class\">.jmolecules<\/span><span class=\"hljs-selector-class\">.architecture<\/span><span class=\"hljs-selector-class\">.annotation<\/span>.*;\n\n<span class=\"hljs-keyword\">@AnalyzeClasses<\/span>(packages = <span class=\"hljs-string\">\"com.meinefirma.shop\"<\/span>)\npublic class EigeneDddRegeln {\n\n    <span class=\"hljs-keyword\">@ArchTest<\/span>\n    ArchRule repositoriesNurAggregates = methods()\n        .that().areDeclaredInClassesThat()\n            .areAnnotatedWith(Repository.class)\n        .<span class=\"hljs-keyword\">and<\/span>().arePublic()\n        .should().haveRawReturnType(classes().that()\n            .areAnnotatedWith(AggregateRoot.class));\n\n    <span class=\"hljs-keyword\">@ArchTest<\/span>\n    ArchRule valueObjectsSindRecords = classes()\n        .that().areAnnotatedWith(ValueObject.class)\n        .should().beRecords();\n\n    <span class=\"hljs-keyword\">@ArchTest<\/span>\n    ArchRule servicesOhneZustand = fields()\n        .that().areDeclaredInClassesThat()\n            .areAnnotatedWith(Service.class)\n        .should().beFinal();\n\n    <span class=\"hljs-keyword\">@ArchTest<\/span>\n    ArchRule factoriesNurImDomainLayer = classes()\n        .that().areAnnotatedWith(Factory.class)\n        .should().resideInAnyPackage(<span class=\"hljs-string\">\"..domain..\"<\/span>);\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Layered- und Onion-Architecture erzwingen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">jMolecules unterst\u00fctzt auch Architekturstile:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ package-info.java im Domain-Package<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span>\n@DomainLayer\npackage com.meinefirma.shop.domain;\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ package-info.java im Application-Package<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span>\n@ApplicationLayer\npackage com.meinefirma.shop.application;\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ package-info.java im Infrastructure-Package<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span>\n@InfrastructureLayer\npackage com.meinefirma.shop.infrastructure;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Die ArchUnit-Regel&nbsp;<code>JMoleculesArchitectureRules.ensureLayering()<\/code>&nbsp;pr\u00fcft dann, dass die Infrastructure-Schicht nicht direkt vom Application-Layer abh\u00e4ngt, dass Domain keine \u00e4u\u00dferen Schichten kennt, usw.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr Onion-Architektur:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">@ArchTest\nArchRule onion = JMoleculesArchitectureRules.ensureOnionSimple();\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ Domain \u2282 Application \u2282 Infrastructure<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ Keine Ring-\u00dcberspringungen, keine Abh\u00e4ngigkeiten von au\u00dfen nach innen<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">ByteBuddy: DDD-Annotationen zu JPA\/Spring mappen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Das&nbsp;<code>jmolecules-bytebuddy<\/code>-Plugin \u00fcbersetzt jMolecules-Annotationen automatisch in Framework-Annotationen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@AggregateRoot<\/span>         \u2192  @javax.persistence.Entity + implements Persistable\n@Identity              \u2192  @javax.persistence.EmbeddedId oder @Id\n@ValueObject (record)  \u2192  @javax.persistence.Embeddable + implements Serializable\n@Repository            \u2192  @org.springframework.stereotype.Repository\n@Service               \u2192  @org.springframework.stereotype.Service\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Maven-Konfiguration:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">plugin<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>net.bytebuddy<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>byte-buddy-maven-plugin<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.17.5<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">executions<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">execution<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">goals<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">goal<\/span>&gt;<\/span>transform-extended<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">goal<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">goals<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">execution<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">executions<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">configuration<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">classPathDiscovery<\/span>&gt;<\/span>true<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">classPathDiscovery<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">configuration<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">plugin<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Damit bleiben deine Domain-Klassen frei von JPA\/Spring-Imports \u2014 die Framework-Integration passiert transparent zur Compile-Zeit.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dependencies<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependencyManagement<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.jmolecules<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>jmolecules-bom<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>2025.0.2<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">type<\/span>&gt;<\/span>pom<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">type<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">scope<\/span>&gt;<\/span>import<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">scope<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependencyManagement<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.jmolecules<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>jmolecules-ddd<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.jmolecules.integrations<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>jmolecules-archunit<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">scope<\/span>&gt;<\/span>test<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">scope<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.jmolecules.integrations<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>jmolecules-spring<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">scope<\/span>&gt;<\/span>runtime<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">scope<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>com.tngtech.archunit<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>archunit-junit5<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.4.2<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">scope<\/span>&gt;<\/span>test<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">scope<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">DDD scheitert nicht am Design, sondern an der mangelnden Durchsetzung im Code. jMolecules und ArchUnit schlie\u00dfen diese L\u00fccke: jMolecules dr\u00fcckt DDD-Konzepte im Typsystem aus (ohne Framework-Abh\u00e4ngigkeiten), ArchUnit pr\u00fcft deren Einhaltung bei jedem Build, und ByteBuddy \u00fcbersetzt sie nahtlos in JPA\/Spring.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Ergebnis ist selbstdokumentierender Code, der&nbsp;<em>beweist<\/em>, dass er DDD-konform ist \u2014 nicht nur behauptet. F\u00fcr jedes Projekt mit nicht-trivialer Dom\u00e4ne ein klares Plus.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Domain-Driven Design (DDD) verspricht bessere Software durch eine gemeinsame Sprache und klare Architekturmuster. In der Praxis scheitert DDD oft an einem: Der Code verletzt die Regeln, die das Design vorschreibt. Repositories geben keine Aggregates zur\u00fcck, Value Objects sind nicht immutable, und Entities werden direkt statt \u00fcber ihre Aggregate Root angesprochen. jMolecules l\u00f6st dieses Problem, indem [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-708","post","type-post","status-publish","format-standard","hentry","category-plain_java"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/708","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=708"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/708\/revisions"}],"predecessor-version":[{"id":709,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/708\/revisions\/709"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=708"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=708"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=708"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}