{"id":585,"date":"2023-07-11T22:38:43","date_gmt":"2023-07-11T22:38:43","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=585"},"modified":"2023-08-23T16:21:18","modified_gmt":"2023-08-23T16:21:18","slug":"implementing-domain-driven-design-java","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/","title":{"rendered":"Implementing Domain-Driven Design with Java"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is Domain-Driven Design?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Domain-Driven Design, commonly referred to as DDD, is an approach to software development that prioritizes a deep understanding of the business domain. It emphasizes modeling based on the reality of business as relevant to your use cases. The primary goal of DDD is to align the software model closely with its real-world counterpart to solve complex business problems effectively. This design methodology was first introduced by Eric Evans in his book &#8220;Domain-Driven Design: Tackling Complexity in the Heart of Software.&#8221;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Importance and Advantages of Domain-Driven Design<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In modern software development, Domain-Driven Design shines as a methodology that can navigate intricacies and nuances of business processes. Its significance cannot be overstated due to the following reasons:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Communication &amp; Understanding<\/strong>: DDD promotes a common language, the ubiquitous language, between all team members \u2013 from developers and designers to business analysts and stakeholders. This ensures everyone is on the same page, minimizing misunderstandings.<\/li>\n\n\n\n<li><strong>Complexity Management<\/strong>: DDD is excellent in managing complex systems by decomposing them into manageable parts known as bounded contexts.<\/li>\n\n\n\n<li><strong>Long-term Evolution<\/strong>: As business requirements change, software needs to adapt. DDD&#8217;s focus on the core domain helps the software evolve in parallel with the business domain, promoting long-term sustainability.<\/li>\n\n\n\n<li><strong>Quality<\/strong>: By focusing on the heart of the business domain, DDD improves the quality of software design, making it more robust, scalable, and maintainable.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Scope of the Article<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This article aims to guide you through implementing Domain-Driven Design with Java. We will explore DDD&#8217;s core concepts, including entities, value objects, aggregates, aggregate roots, repositories, services, and factories, and demonstrate how these are realized in Java code. We will also examine the importance of ubiquitous language and bounded contexts in DDD.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The approach taken in this article is practical and hands-on, complete with Java code examples for each concept. This walkthrough is designed to equip you, the reader, with the skills and knowledge required to effectively apply DDD principles in your Java-based software development projects. We&#8217;ll also discuss some best practices to follow when implementing DDD. Let&#8217;s get started!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Core Concepts of DDD<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Domain-Driven Design (DDD) is structured around several key concepts that drive its design philosophy. Let&#8217;s explore each of these concepts along with some Java code snippets to better understand their implementation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Entities<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Entities, or domain objects, are fundamentally defined by their identity rather than their attributes. They possess a unique identifier and can mutate over time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For instance, consider a <code><strong>User<\/strong><\/code> entity in an application:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">User<\/span> <\/span>{\r\n    <span class=\"hljs-keyword\">private<\/span> UserId id;\r\n    <span class=\"hljs-keyword\">private<\/span> String name;\r\n    <span class=\"hljs-keyword\">private<\/span> String email;\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">User<\/span><span class=\"hljs-params\">(UserId id, String name, String email)<\/span> <\/span>{\r\n        <span class=\"hljs-keyword\">this<\/span>.id = id;\r\n        <span class=\"hljs-keyword\">this<\/span>.name = name;\r\n        <span class=\"hljs-keyword\">this<\/span>.email = email;\r\n    }\r\n\r\n    <span class=\"hljs-comment\">\/\/ getters and setters<\/span>\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this case, even if the name or email of a user changes, they remain the same <code><strong>User<\/strong><\/code> because the identity (<code><strong>UserId<\/strong><\/code>) remains constant.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Value Objects<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Value objects are immutable and don&#8217;t possess an identity. They are defined by their attributes and are often used as the building blocks of entities.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A simple <code><strong>UserId<\/strong><\/code> value object might look like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserId<\/span> <\/span>{\r\n    <span class=\"hljs-keyword\">private<\/span> String value;\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">UserId<\/span><span class=\"hljs-params\">(String value)<\/span> <\/span>{\r\n        <span class=\"hljs-keyword\">this<\/span>.value = value;\r\n    }\r\n\r\n    <span class=\"hljs-comment\">\/\/ getter and equals\/hashCode methods<\/span>\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Aggregates and Aggregate Roots<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Aggregates are clusters of entities and value objects that are treated as a single unit. The Aggregate Root is the entity within the aggregate that serves as the gateway for all interactions with the aggregate.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Consider an <code><strong>Order<\/strong><\/code> aggregate:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Order<\/span> <\/span>{\r\n    <span class=\"hljs-keyword\">private<\/span> OrderId id;\r\n    <span class=\"hljs-keyword\">private<\/span> List&lt;OrderLine&gt; orderLines;\r\n    <span class=\"hljs-comment\">\/\/ Other fields<\/span>\r\n\r\n    <span class=\"hljs-comment\">\/\/ Only the aggregate root has the methods to mutate the state<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">addOrderLine<\/span><span class=\"hljs-params\">(OrderLine orderLine)<\/span> <\/span>{\r\n        <span class=\"hljs-keyword\">this<\/span>.orderLines.add(orderLine);\r\n    }\r\n\r\n    <span class=\"hljs-comment\">\/\/ getters and setters<\/span>\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this case, <code>Order<\/code> is the Aggregate Root, and <code><strong>OrderLine<\/strong><\/code> is part of the <code>Order<\/code> aggregate.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Repositories<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Repositories act as collections to retrieve and store aggregates. They provide an illusion of in-memory collection of all objects of a certain type.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For instance, an <code><strong>OrderRepository<\/strong><\/code> could look like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">OrderRepository<\/span> <\/span>{\r\n    <span class=\"hljs-function\">Order <span class=\"hljs-title\">find<\/span><span class=\"hljs-params\">(OrderId id)<\/span><\/span>;\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">save<\/span><span class=\"hljs-params\">(Order order)<\/span><\/span>;\r\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Domain Services<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Domain services hold operations that don&#8217;t naturally fit within an entity or value object. They are stateless operations on the domain model.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An example of a domain service might be <code><strong>PaymentService<\/strong><\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">PaymentService<\/span> <\/span>{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">processPayment<\/span><span class=\"hljs-params\">(PaymentDetails paymentDetails, Order order)<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ Implementation of payment process<\/span>\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Factories<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Factories are responsible for encapsulating complex creation logic of an object. They might be necessary when an object needs some specific state or parameters at the time of creation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Consider a factory for creating an <code><strong>Order<\/strong><\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OrderFactory<\/span> <\/span>{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> Order <span class=\"hljs-title\">createOrder<\/span><span class=\"hljs-params\">(UserId userId, List&lt;OrderLine&gt; orderLines)<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ Validation and creation of Order<\/span>\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Each of these core concepts forms the bedrock of Domain-Driven Design, and their correct use is vital for a successful DDD implementation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding Ubiquitous Language and Bounded Contexts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Domain-Driven Design (DDD) is about creating a common model that is shared by all members involved in a project. Two fundamental concepts that facilitate this shared understanding are the Ubiquitous Language and Bounded Contexts.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ubiquitous Language<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ubiquitous Language is a common, rigorous language established by all team members \u2014 developers, domain experts, business analysts, and stakeholders \u2014 to describe and discuss the domain. This language should be used in all aspects, from conversations and documentation to the very code itself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The use of Ubiquitous Language helps to eliminate misunderstandings and ensures that everyone has the same understanding of the business domain and its rules. It also eliminates the translation gap between different models, such as the business model, analysis model, and design model.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A simple example would be the <code><strong>Order<\/strong><\/code> class from our previous examples:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Order<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> OrderId id;\n    <span class=\"hljs-keyword\">private<\/span> List&lt;OrderLine&gt; orderLines;\n    <span class=\"hljs-comment\">\/\/ other fields<\/span>\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">addOrderLine<\/span><span class=\"hljs-params\">(OrderLine orderLine)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.orderLines.add(orderLine);\n    }\n\n    <span class=\"hljs-comment\">\/\/ getters and setters<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this case, terms like <code>Order<\/code>, <code><strong>OrderLine<\/strong><\/code>, and <code><strong>addOrderLine<\/strong><\/code> would be part of the Ubiquitous Language, and they should mean the same thing to everyone on the team.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Bounded Contexts<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A Bounded Context is a boundary within which a particular model is defined and applicable. It encapsulates a specific functionality and contains all its related models, behaviors, and artifacts. The main goal of a Bounded Context is to create a clear separation and prevent the mixing of various models, which can cause confusion and complexity.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, the <code><strong>Order<\/strong><\/code> model may exist within the context of a Sales bounded context. However, an entirely different model of <code><strong>Order<\/strong><\/code> may exist within a Shipping bounded context.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/ Within the Sales Bounded Context<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SalesOrder<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> OrderId id;\n    <span class=\"hljs-keyword\">private<\/span> List&lt;OrderLine&gt; orderLines;\n    <span class=\"hljs-comment\">\/\/ Other sales-specific fields and methods<\/span>\n}\n\n<span class=\"hljs-comment\">\/\/ Within the Shipping Bounded Context<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ShippingOrder<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> OrderId id;\n    <span class=\"hljs-keyword\">private<\/span> ShippingAddress shippingAddress;\n    <span class=\"hljs-comment\">\/\/ Other shipping-specific fields and methods<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this example, while <code><strong>SalesOrder<\/strong><\/code> and <code><strong>ShippingOrder<\/strong><\/code> share the same ubiquitous language term &#8216;Order&#8217;, they serve different purposes within their respective bounded contexts and thus have different properties and methods.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Understanding the concepts of Ubiquitous Language and Bounded Contexts, and their correct implementation, are essential to effectively apply DDD principles and design a maintainable, cohesive, and loosely coupled system.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Implementing DDD: Project Setup<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For implementing Domain-Driven Design in Java, we&#8217;ll leverage some widely-used tools and libraries such as Spring Boot, Spring Data JPA, and Hibernate.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tools and Libraries<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Spring Boot<\/strong>: Spring Boot is a framework that simplifies the setup and development of Spring applications. It provides a default setup that reduces boilerplate code.<\/li>\n\n\n\n<li><strong>Spring Data JPA<\/strong>: Spring Data JPA is a part of the larger Spring Data family. It makes it easy to implement JPA-based repositories and provides useful features like query creation and pagination.<\/li>\n\n\n\n<li><strong>Hibernate<\/strong>: Hibernate is an ORM (Object-Relational Mapping) library for Java. It maps Java classes to database tables (and Java data types to SQL data types), enabling Java developers to operate at the object level.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Now, let&#8217;s set up a new Spring Boot project.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Setting up a new project<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You can create a new Spring Boot project using Spring Initializr or directly through your IDE if it supports Spring Initializr integration. For our example, we&#8217;ll use <a href=\"https:\/\/start.spring.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Spring Initializr<\/a>:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the Spring Initializr at <a href=\"https:\/\/start.spring.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/start.spring.io\/<\/a>.<\/li>\n\n\n\n<li>Choose the following settings:\n<ul class=\"wp-block-list\">\n<li><strong>Project<\/strong>: Maven Project<\/li>\n\n\n\n<li><strong>Language<\/strong>: Java<\/li>\n\n\n\n<li><strong>Spring Boot version<\/strong>: The latest stable version<\/li>\n\n\n\n<li><strong>Project Metadata<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>Group<\/strong>: com.example<\/li>\n\n\n\n<li><strong>Artifact<\/strong>: ddd-example<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Packaging<\/strong>: Jar<\/li>\n\n\n\n<li><strong>Java version<\/strong>: 11 (or the version you prefer)<\/li>\n\n\n\n<li><strong>Dependencies<\/strong>: Spring Data JPA, Spring Web, MySQL Driver (if you plan to use MySQL)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Click on the &#8220;Generate&#8221; button to download the project.<\/li>\n\n\n\n<li>Extract the downloaded zip file to your workspace directory.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Your directory structure will look something like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Markdown\" data-shcb-language-slug=\"markdown\"><span><code class=\"hljs language-markdown\">ddd-example\n\u251c\u2500\u2500 src\n\u2502   \u251c\u2500\u2500 main\n\u2502   \u2502   \u251c\u2500\u2500 java\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 com\n\u2502   \u2502   \u2502       \u2514\u2500\u2500 example\n\u2502   \u2502   \u2502           \u2514\u2500\u2500 dddexample\n\u2502   \u2502   \u2502               \u2514\u2500\u2500 DddExampleApplication.java\n\u2502   \u2502   \u2514\u2500\u2500 resources\n\u2502   \u2502       \u251c\u2500\u2500 application.properties\n\u2502   \u2502       \u2514\u2500\u2500 ...\n\u2502   \u2514\u2500\u2500 test\n\u2502       \u2514\u2500\u2500 ...\n\u251c\u2500\u2500 .gitignore\n\u251c\u2500\u2500 pom.xml\n\u2514\u2500\u2500 ...<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Markdown<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">markdown<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You will find your main application file <code><strong>DddExampleApplication.java<\/strong><\/code> and your <code><strong>pom.xml<\/strong><\/code> file which includes all your project dependencies.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To connect with a database, you&#8217;ll need to configure <code><strong>application.properties<\/strong><\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Properties\" data-shcb-language-slug=\"properties\"><span><code class=\"hljs language-properties\"><span class=\"hljs-meta\">spring.datasource.url<\/span>=<span class=\"hljs-string\">jdbc:mysql:\/\/localhost:3306\/your_database<\/span>\n<span class=\"hljs-meta\">spring.datasource.username<\/span>=<span class=\"hljs-string\">your_username<\/span>\n<span class=\"hljs-meta\">spring.datasource.password<\/span>=<span class=\"hljs-string\">your_password<\/span>\n<span class=\"hljs-meta\">spring.jpa.hibernate.ddl-auto<\/span>=<span class=\"hljs-string\">update<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Properties<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">properties<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Now, you have a project set up and ready to implement DDD principles.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Note: This setup assumes familiarity with Java, Spring Boot, and your preferred IDE. If you&#8217;re new to these, there are many tutorials available that can help you get started.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Designing the Domain Model<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Creating a domain model involves understanding the business problem and translating it into a set of related concepts. These concepts include Entities, Value Objects, and Aggregates, among others. Let&#8217;s take an example of an online bookstore to demonstrate how we can create a domain model.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Business Requirements<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Consider the following simplified business requirements for our online bookstore:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Users can search for books.<\/li>\n\n\n\n<li>Users can place books into a shopping cart.<\/li>\n\n\n\n<li>Users can place an order with the books in their shopping cart.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Entities, Value Objects, and Aggregates<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">From these requirements, we can identify the following entities and value objects:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code><strong>User<\/strong><\/code>: An entity, as each user has a unique identity.<\/li>\n\n\n\n<li><code><strong>Book<\/strong><\/code>: An entity with a unique identifier like ISBN.<\/li>\n\n\n\n<li><code><strong>ShoppingCart<\/strong><\/code>: An entity that belongs to a user.<\/li>\n\n\n\n<li><code><strong>Order<\/strong><\/code>: An entity that contains the books a user wishes to purchase.<\/li>\n\n\n\n<li><code><strong>BookTitle<\/strong><\/code>, <code><strong>BookDescription<\/strong><\/code>, <code><strong>UserName<\/strong><\/code>: Value objects, as these can be considered attributes but don&#8217;t have an identity of their own.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The <code><strong>Order<\/strong><\/code> aggregate might include the <code><strong>Order<\/strong><\/code> entity as the Aggregate Root, and <code><strong>OrderLine<\/strong><\/code> entities, which connect each <code><strong>Book<\/strong><\/code> entity to the <code><strong>Order<\/strong><\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Implementing the Domain Model in Java<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s translate some of these into Java classes. We won&#8217;t handle persistence annotations for simplicity.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/ Value Objects<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">BookTitle<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> String value;\n    <span class=\"hljs-comment\">\/\/ Constructor, getters, equals\/hashCode<\/span>\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">BookDescription<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> String value;\n    <span class=\"hljs-comment\">\/\/ Constructor, getters, equals\/hashCode<\/span>\n}\n\n<span class=\"hljs-comment\">\/\/ Entities<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">User<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> UserId id;\n    <span class=\"hljs-keyword\">private<\/span> UserName name;\n    <span class=\"hljs-comment\">\/\/ Constructor, getters<\/span>\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Book<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> BookId id;\n    <span class=\"hljs-keyword\">private<\/span> BookTitle title;\n    <span class=\"hljs-keyword\">private<\/span> BookDescription description;\n    <span class=\"hljs-comment\">\/\/ Constructor, getters<\/span>\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OrderLine<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> OrderLineId id;\n    <span class=\"hljs-keyword\">private<\/span> Book book;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> quantity;\n    <span class=\"hljs-comment\">\/\/ Constructor, getters<\/span>\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Order<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> OrderId id;\n    <span class=\"hljs-keyword\">private<\/span> User user;\n    <span class=\"hljs-keyword\">private<\/span> List&lt;OrderLine&gt; orderLines;\n    \n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">addOrderLine<\/span><span class=\"hljs-params\">(OrderLine orderLine)<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ Business logic here<\/span>\n    }\n    <span class=\"hljs-comment\">\/\/ Constructor, getters<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This example illustrates a simplified scenario. In a real-world situation, you would need to consider more complex business rules, constraints, and behaviors, and model them accurately within your domain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By ensuring the domain model accurately captures the core business concepts and rules, we can create a software model that is a close reflection of the business domain, which is the primary goal of Domain-Driven Design.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Repositories and Data Access<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In Domain-Driven Design, Repositories act as a bridge between the domain and the data mapping layers using a collection-like interface for accessing domain objects.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Repositories handle the task of persisting and retrieving entities, providing the illusion of an in-memory collection of all objects of a certain type. They isolate the domain layer from infrastructure or technology-specific code, making the domain model ignorant of the specifics of the storage system.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Spring Data JPA allows us to avoid boilerplate code by using simple interfaces that follow a naming convention for CRUD operations. Let&#8217;s see how we can implement repositories for our online bookstore example.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">import<\/span> org.springframework.data.jpa.repository.JpaRepository;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.stereotype.Repository;\n\n<span class=\"hljs-meta\">@Repository<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">UserRepository<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">JpaRepository<\/span>&lt;<span class=\"hljs-title\">User<\/span>, <span class=\"hljs-title\">UserId<\/span>&gt; <\/span>{\n    <span class=\"hljs-comment\">\/\/ Spring Data JPA will automatically implement methods like save(), findById(), findAll(), etc.<\/span>\n}\n\n<span class=\"hljs-meta\">@Repository<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">BookRepository<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">JpaRepository<\/span>&lt;<span class=\"hljs-title\">Book<\/span>, <span class=\"hljs-title\">BookId<\/span>&gt; <\/span>{\n    <span class=\"hljs-comment\">\/\/ You can define additional methods as needed, Spring Data JPA will provide an implementation based on the method name<\/span>\n    <span class=\"hljs-function\">List&lt;Book&gt; <span class=\"hljs-title\">findByTitle<\/span><span class=\"hljs-params\">(BookTitle title)<\/span><\/span>;\n}\n\n<span class=\"hljs-meta\">@Repository<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">OrderRepository<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">JpaRepository<\/span>&lt;<span class=\"hljs-title\">Order<\/span>, <span class=\"hljs-title\">OrderId<\/span>&gt; <\/span>{\n    <span class=\"hljs-function\">List&lt;Order&gt; <span class=\"hljs-title\">findByUser<\/span><span class=\"hljs-params\">(User user)<\/span><\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In these examples, each interface extends <code><strong>JpaRepository<\/strong><\/code> which comes with several methods for common operations like saving, deleting, and finding entities. We also define custom methods, such as <code><strong>findByTitle<\/strong><\/code> in <code><strong>BookRepository<\/strong><\/code> and <code><strong>findByUser<\/strong><\/code> in <code><strong>OrderRepository<\/strong><\/code>, which Spring Data JPA will automatically implement based on the method name.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By using repositories, we keep our domain model clean and free from data access concerns. We can change the data access technology without impacting the domain model, thus adhering to the Separation of Concerns principle.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Domain Services and Application Services<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In Domain-Driven Design, services are an essential part of the design pattern. Services are used when an operation does not conceptually belong to any object. Depending on the nature and the layer in which they are used, services are categorized as Domain Services or Application Services.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Domain Services<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Domain Services contain business logic that doesn&#8217;t naturally fit within a domain object. They operate on one or more entities to perform operations specific to your business rules. The interfaces of domain services are part of the ubiquitous language, and their implementation contains business logic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For instance, consider a domain service <code><strong>BookCatalogService<\/strong><\/code> which includes business operations related to the book catalog.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">BookCatalogService<\/span> <\/span>{\n    <span class=\"hljs-function\">Book <span class=\"hljs-title\">findMostPopularBook<\/span><span class=\"hljs-params\">()<\/span><\/span>;\n}\n\n<span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">BookCatalogServiceImpl<\/span> <span class=\"hljs-keyword\">implements<\/span> <span class=\"hljs-title\">BookCatalogService<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> BookRepository bookRepository;\n\n    <span class=\"hljs-comment\">\/\/ Dependency injection<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">BookCatalogServiceImpl<\/span><span class=\"hljs-params\">(BookRepository bookRepository)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.bookRepository = bookRepository;\n    }\n\n    <span class=\"hljs-meta\">@Override<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> Book <span class=\"hljs-title\">findMostPopularBook<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ Implement the business logic here using the BookRepository<\/span>\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Application Services<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Application Services, on the other hand, are used to handle application-specific operations that do not belong to a domain model, such as orchestration, transaction management, security, etc. They define the interfaces that the outer layers (like UI or tests) interact with to talk to your application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s consider an application service <code><strong>OrderService<\/strong><\/code> that orchestrates the order placement process:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">OrderService<\/span> <\/span>{\n    <span class=\"hljs-function\">OrderId <span class=\"hljs-title\">placeOrder<\/span><span class=\"hljs-params\">(UserId userId, Map&lt;BookId, Integer&gt; books)<\/span><\/span>;\n}\n\n<span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OrderServiceImpl<\/span> <span class=\"hljs-keyword\">implements<\/span> <span class=\"hljs-title\">OrderService<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> UserRepository userRepository;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> BookRepository bookRepository;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> OrderRepository orderRepository;\n\n    <span class=\"hljs-comment\">\/\/ Dependency injection<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">OrderServiceImpl<\/span><span class=\"hljs-params\">(UserRepository userRepository, \n                            BookRepository bookRepository, \n                            OrderRepository orderRepository)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.userRepository = userRepository;\n        <span class=\"hljs-keyword\">this<\/span>.bookRepository = bookRepository;\n        <span class=\"hljs-keyword\">this<\/span>.orderRepository = orderRepository;\n    }\n\n    <span class=\"hljs-meta\">@Transactional<\/span>\n    <span class=\"hljs-meta\">@Override<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> OrderId <span class=\"hljs-title\">placeOrder<\/span><span class=\"hljs-params\">(UserId userId, Map&lt;BookId, Integer&gt; books)<\/span> <\/span>{\n        User user = userRepository.findById(userId)\n            .orElseThrow(() -&gt; <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException(<span class=\"hljs-string\">\"Invalid user ID\"<\/span>));\n\n        Order order = <span class=\"hljs-keyword\">new<\/span> Order(user);\n\n        <span class=\"hljs-keyword\">for<\/span> (Map.Entry&lt;BookId, Integer&gt; entry : books.entrySet()) {\n            Book book = bookRepository.findById(entry.getKey())\n                .orElseThrow(() -&gt; <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException(<span class=\"hljs-string\">\"Invalid book ID\"<\/span>));\n            OrderLine orderLine = <span class=\"hljs-keyword\">new<\/span> OrderLine(book, entry.getValue());\n            order.addOrderLine(orderLine);\n        }\n\n        order = orderRepository.save(order);\n\n        <span class=\"hljs-keyword\">return<\/span> order.getId();\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this example, the <code><strong>OrderService<\/strong><\/code> is an Application Service. It orchestrates the process of placing an order: loading the <code><strong>User<\/strong><\/code> and <code><strong>Book<\/strong><\/code> entities, creating <code><strong>OrderLine<\/strong><\/code> entities, adding them to the <code><strong>Order<\/strong><\/code>, and finally persisting the <code><strong>Order<\/strong><\/code> using a repository.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By clearly separating Domain Services from Application Services, we ensure that business logic is appropriately encapsulated within the domain model and that orchestration and infrastructural tasks are handled outside the domain model, leading to a cleaner, more maintainable architecture.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Implementing Factories<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In Domain-Driven Design, Factories are used to encapsulate the complexity of creating complex objects and aggregates. They ensure that the client code is not burdened with the intricate details of object creation and initialization, hence enhancing code maintainability and readability.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Factories are especially useful when object creation involves more than just instantiation &#8211; when it requires complex logic, validation, or setting of various fields.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s take our <code><strong>Order<\/strong><\/code> aggregate as an example. An order creation involves not only instantiating an <code><strong>Order<\/strong><\/code> object but also creating and adding <code><strong>OrderLine<\/strong><\/code> items. This creation logic can be abstracted into an <code><strong>OrderFactory<\/strong><\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OrderFactory<\/span> <\/span>{\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> Order <span class=\"hljs-title\">createOrder<\/span><span class=\"hljs-params\">(User user, Map&lt;Book, Integer&gt; books)<\/span> <\/span>{\n        Order order = <span class=\"hljs-keyword\">new<\/span> Order(user);\n\n        <span class=\"hljs-keyword\">for<\/span> (Map.Entry&lt;Book, Integer&gt; bookEntry : books.entrySet()) {\n            OrderLine orderLine = <span class=\"hljs-keyword\">new<\/span> OrderLine(bookEntry.getKey(), bookEntry.getValue());\n            order.addOrderLine(orderLine);\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> order;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In our <code><strong>OrderService<\/strong><\/code>, we replace the order creation logic with a call to our factory method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OrderServiceImpl<\/span> <span class=\"hljs-keyword\">implements<\/span> <span class=\"hljs-title\">OrderService<\/span> <\/span>{\n    <span class=\"hljs-comment\">\/\/ ... other code omitted for brevity<\/span>\n\n    <span class=\"hljs-meta\">@Transactional<\/span>\n    <span class=\"hljs-meta\">@Override<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> OrderId <span class=\"hljs-title\">placeOrder<\/span><span class=\"hljs-params\">(UserId userId, Map&lt;BookId, Integer&gt; books)<\/span> <\/span>{\n        User user = userRepository.findById(userId)\n            .orElseThrow(() -&gt; <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException(<span class=\"hljs-string\">\"Invalid user ID\"<\/span>));\n\n        Map&lt;Book, Integer&gt; bookMap = <span class=\"hljs-keyword\">new<\/span> HashMap&lt;&gt;();\n\n        <span class=\"hljs-keyword\">for<\/span> (Map.Entry&lt;BookId, Integer&gt; entry : books.entrySet()) {\n            Book book = bookRepository.findById(entry.getKey())\n                .orElseThrow(() -&gt; <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException(<span class=\"hljs-string\">\"Invalid book ID\"<\/span>));\n            bookMap.put(book, entry.getValue());\n        }\n\n        Order order = OrderFactory.createOrder(user, bookMap);\n        order = orderRepository.save(order);\n\n        <span class=\"hljs-keyword\">return<\/span> order.getId();\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The use of factories enhances the flexibility of your codebase. By centralizing object creation logic, factories promote consistency and reduce errors due to incorrect object initialization.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Validations and Exception Handling<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In Domain-Driven Design, validation is essential to ensure that the domain rules and constraints are not violated. The validation logic often resides in entities, value objects, or domain services. But when validation fails, we need a way to inform the client code about the problem, and this is where custom exceptions come into play.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Role of Validation in DDD<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Validation plays a critical role in maintaining the integrity of the domain model. By performing validations, we ensure that our domain objects always stay in a consistent state.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For instance, in our <code><strong>Order<\/strong><\/code> entity, we might want to enforce a rule that an order must contain at least one <code><strong>OrderLine<\/strong><\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Order<\/span> <\/span>{\n    <span class=\"hljs-comment\">\/\/ ... other code omitted for brevity<\/span>\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">addOrderLine<\/span><span class=\"hljs-params\">(OrderLine orderLine)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">if<\/span> (orderLine == <span class=\"hljs-keyword\">null<\/span>) {\n            <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IllegalArgumentException(<span class=\"hljs-string\">\"OrderLine cannot be null\"<\/span>);\n        }\n\n        <span class=\"hljs-keyword\">this<\/span>.orderLines.add(orderLine);\n\n        <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-keyword\">this<\/span>.orderLines.isEmpty()) {\n            <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> DomainRuleViolationException(<span class=\"hljs-string\">\"An order must contain at least one order line.\"<\/span>);\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this example, we perform validation in the <code><strong>addOrderLine<\/strong><\/code> method. If the validation fails, we throw an exception to signal that a domain rule has been violated.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Implementing Custom Exceptions for Better Error Handling<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When it comes to handling errors in DDD, custom exceptions can be a powerful tool. They allow us to provide meaningful error messages and categorize errors based on their type, which can simplify error handling in the client code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s how we might define a <code>DomainRuleViolationException<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">DomainRuleViolationException<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">RuntimeException<\/span> <\/span>{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">DomainRuleViolationException<\/span><span class=\"hljs-params\">(String message)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">super<\/span>(message);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">By throwing this custom exception when a domain rule is violated, we make it clear to the client code what kind of error has occurred. The client code can then catch this exception and handle it appropriately, for example by showing an error message to the user.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Here are some best practices to keep in mind while implementing DDD:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Understand the Business Domain<\/strong>: Spend ample time understanding the business domain, its rules, and its intricacies. The better you understand the business domain, the better your domain model will be.<\/li>\n\n\n\n<li><strong>Collaborate with Domain Experts<\/strong>: Work closely with domain experts to create a Ubiquitous Language and to ensure your domain model accurately reflects the business domain.<\/li>\n\n\n\n<li><strong>Isolate Business Logic<\/strong>: Keep your business logic within your domain model, isolated from infrastructure and application-specific code.<\/li>\n\n\n\n<li><strong>Design Small, Focused Bounded Contexts<\/strong>: Instead of creating a large, monolithic domain model, design small, focused Bounded Contexts. This helps in managing complexity and promotes loose coupling.<\/li>\n\n\n\n<li><strong>Continually Refactor and Improve Your Model<\/strong>: As you gain more understanding of the business domain, continually refactor and improve your domain model. DDD is not a one-off task, but a continuous journey of learning and improvement.<\/li>\n\n\n\n<li><strong>Value the Role of Testing<\/strong>: Ensure robust testing mechanisms to validate your models, their behaviors, and their interactions. DDD models tend to be rich and interconnected, and automated testing is essential to ensure their correct behavior.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Implementing Domain-Driven Design requires practice and patience, but the rewards &#8211; in terms of maintainable, evolvable, and business-aligned software &#8211; are well worth the effort. So, go ahead and try implementing DDD in your next Java project. Practice the concepts, learn from your mistakes, and continually improve your understanding of DDD.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction What is Domain-Driven Design? Domain-Driven Design, commonly referred to as DDD, is an approach to software development that prioritizes a deep understanding of the business domain. It emphasizes modeling based on the reality of business as relevant to your use cases. The primary goal of DDD is to align the software model closely with [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[5,4],"tags":[],"class_list":["post-585","post","type-post","status-publish","format-standard","category-java","category-programming-languages","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Implementing Domain-Driven Design with Java<\/title>\n<meta name=\"description\" content=\"This article aims to guide you through implementing Domain-Driven Design with Java. We will explore DDD&#039;s core concepts, including entities,\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Implementing Domain-Driven Design with Java\" \/>\n<meta property=\"og:description\" content=\"This article aims to guide you through implementing Domain-Driven Design with Java. We will explore DDD&#039;s core concepts, including entities,\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-07-11T22:38:43+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-23T16:21:18+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/implementing-domain-driven-design-java\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/implementing-domain-driven-design-java\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"Implementing Domain-Driven Design with Java\",\"datePublished\":\"2023-07-11T22:38:43+00:00\",\"dateModified\":\"2023-08-23T16:21:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/implementing-domain-driven-design-java\\\/\"},\"wordCount\":2579,\"commentCount\":0,\"articleSection\":[\"Java\",\"Programming Languages\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/implementing-domain-driven-design-java\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/implementing-domain-driven-design-java\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/implementing-domain-driven-design-java\\\/\",\"name\":\"Implementing Domain-Driven Design with Java\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2023-07-11T22:38:43+00:00\",\"dateModified\":\"2023-08-23T16:21:18+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"This article aims to guide you through implementing Domain-Driven Design with Java. We will explore DDD's core concepts, including entities,\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/implementing-domain-driven-design-java\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/implementing-domain-driven-design-java\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/implementing-domain-driven-design-java\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Implementing Domain-Driven Design with Java\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Implementing Domain-Driven Design with Java","description":"This article aims to guide you through implementing Domain-Driven Design with Java. We will explore DDD's core concepts, including entities,","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/","og_locale":"en_US","og_type":"article","og_title":"Implementing Domain-Driven Design with Java","og_description":"This article aims to guide you through implementing Domain-Driven Design with Java. We will explore DDD's core concepts, including entities,","og_url":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/","article_published_time":"2023-07-11T22:38:43+00:00","article_modified_time":"2023-08-23T16:21:18+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"Implementing Domain-Driven Design with Java","datePublished":"2023-07-11T22:38:43+00:00","dateModified":"2023-08-23T16:21:18+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/"},"wordCount":2579,"commentCount":0,"articleSection":["Java","Programming Languages"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/","url":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/","name":"Implementing Domain-Driven Design with Java","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2023-07-11T22:38:43+00:00","dateModified":"2023-08-23T16:21:18+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"This article aims to guide you through implementing Domain-Driven Design with Java. We will explore DDD's core concepts, including entities,","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/implementing-domain-driven-design-java\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"Implementing Domain-Driven Design with Java"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/585","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=585"}],"version-history":[{"count":12,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/585\/revisions"}],"predecessor-version":[{"id":598,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/585\/revisions\/598"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=585"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=585"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=585"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}