Domain Driven Development with Java and Spring Boot ~ Layers and Modules ~

About Domain Driven Development

As the name implies, domain-driven development is not just an implementation pattern, but a development method that involves members other than development personnel.

Why divide into 3 layers

In the design of Domain Driven Development, software is designed in the following three layers.

--Application layer --Domain layer --Infrastructure layer

Why do you make such a division? The mobile app version may suddenly start developing, and the DB may suddenly cease to be an RDB. In such a case, what can be reused between software of the same domain is domain knowledge, and what includes this is the domain layer.

** Application layer **

--Main function --Application services (session management, etc.) --Controller --Presentations such as views, email templates, etc. --Value object for view, DPO

** Domain layer **

--Domain service --Something --Value object --Aggregation -* Repository interface *

** Infrastructure layer **

--Repository

You can see that the implementation class of the repository is the infrastructure layer. But why is the interface a domain layer? This is because if an interface is an infrastructure layer, the implementation of the domain layer that calls it will inevitably depend on the infrastructure layer. In other words, you will not be able to select the infrastructure library to use.

Strengths of Spring DI

He explained that the interface of the repository is put in the domain layer so that the domain layer does not depend on the infrastructure layer. So where do you initialize an instance of the repository that contains implementation knowledge? Simply thinking, it seems that there is no choice but to initialize it at the application layer and propagate it to the domain service. However, if you use Spring DI and declare an implementation class that inherits the domain service class and interface as a component, Spring DI will solve this problem. There is no need to prepare a Factory pattern or ╩╗ApplicationContextAware`.

@Repository
public class Repository extends IRepository {
  ...
}

Use the constructor @Autowired instead of the field @Autowired to resolve the Dependency. It makes it easier to write unit tests. It can be written more easily with Lombok's @RequiredArgsConstructor.

@Service
@RequiredArgsConstructor
public class Service {
  private final IRepository repository;
}
IRepository mockRespository = new MockRepository();
var service = new Service(mockRespotory);

Module division

I wrote that the software was designed in three layers, but should the Maven module also be divided into three layers? If the software is single, it is enough to divide it into packages.

On the contrary, if you want to divide the module, prepare a parent module.

/pom.xml


<modules>
  <module>./web</module>
  <module>./mobile</module>
  <module>./domain</module>
  <module>./infrastructure</module>
</modules>

As

/application/pom.xml


<parent>
  <groupId>me.yong_ju.application</groupId>
  <artifactId>parent</artifactId>
  <version>...</version>
  <relativePath>../</relativePath>
</parent>
...
<dependencies>
  <dependency>
    <groupId>me.yong_ju.application</groupId>
    <artifactId>domain</artifactId>
    <version>...</version>
  </dependency>
  <dependency>
    <groupId>me.yong_ju.application</groupId>
    <artifactId>infrastructure</artifactId>
    <version>...</version>
  </dependency>
</dependencies>

You can do it. By defining the child module first in the parent module, when that module is added to the dependency, it will be retrieved locally instead of in the Maven repository. (However, the versions must match)

Spring Configuration definition

If you divide the package into three layers, you will immediately run into a problem. That's because we put @ SpringBootApplication in the application package, so Spring's component scan only injects application layer components.

what to do. You can use scanBasePackages to change the packages you want to scan to the upper layer, but we don't recommend it.

Here, we have prepared a Configuration class with Component Scan enabled in the domain layer and infrastructure layer, and explicitly @Import the Configuration used by the application.

@Configuration
@ComponentScan
public class DomainConfiguration {
  ...
}
@Configuration
@ComponentScan
public class InfrastructureConfiguration {
  ...
}
@SpringBootApplication
@Import({ DomainConfiguration.class, InfrastructureConfiguration.class })
public class Application {
  ...
}

Anti-pattern

Service is a resource unit

A pattern in which a service you often see has become just a repository wrapper. It should be serviced in meaningful operation units, and if it is not known yet, it is even faster to turn it into a service. (In connection with this, I often see patterns that have been @Transactional in a completely meaningless operation unit.)

Too particular about mounting patterns

I personally think that implementation patterns are generally a tool for stopping thinking while avoiding fatal design mistakes in software development with poor planning prospects. Therefore, it is a mess to waste time wandering around seeking best practices for everything. Java and its peripheral frameworks are constantly evolving. In some cases, they can be used for less redundant and safer implementation.

If I have free time, I will focus on what I took time to understand.

Recommended Posts

Domain Driven Development with Java and Spring Boot ~ Layers and Modules ~
Hot deploy with Spring Boot development
Handle Java 8 date and time API with Thymeleaf with Spring Boot
[Java] LINE integration with Spring Boot
Implement REST API with Spring Boot and JPA (domain layer)
Compare Hello, world! In Spring Boot with Java, Kotlin and Groovy
HTTPS with Spring Boot and Let's Encrypt
Start web application development with Spring Boot
Spring Boot + Docker Java development environment construction
Vending machine made with Java (domain driven)
Introduction to Java development environment & Spring Boot application created with VS Code
[Java] Hello World with Java 14 x Spring Boot 2.3 x JUnit 5 ~
[Java] Article to add validation with Spring Boot 2.3.1.
Create a Spring Boot development environment with docker
Download with Spring Boot
Create a portfolio app using Java and Spring Boot
Try using DI container with Laravel and Spring Boot
Switch environment with Spring Boot application.properties and @Profile annotation
[Java] [Spring Boot] Specify runtime profile --Spring Boot starting with NetBeans
Spring Security usage memo: Cooperation with Spring MVC and Boot
Spring Boot with Spring Security Filter settings and addictive points
Until you start development with Spring Boot in eclipse 1
Until you start development with Spring Boot in eclipse 2
Attempt to SSR Vue.js with Spring Boot and GraalJS
Connect Spring Boot and Angular type-safely with OpenAPI Generator
[Java] Development with multiple files using package and import
Java + Spring development environment construction with VirtualBox + Ubuntu (Xfce4)
Form and process file and String data at the same time with Spring Boot + Java
Use Lambda Layers with Java
[Java / Kotlin] Escape (sanitize) HTML5 support with unbescape [Spring Boot]
Generate barcode with Spring Boot
Hello World with Spring Boot
Java Config with Spring MVC
Implement GraphQL with Spring Boot
Get started with Spring boot
Implement REST API with Spring Boot and JPA (Application Layer)
Implement REST API with Spring Boot and JPA (Infrastructure layer)
Hello World with Spring Boot!
Run LIFF with Spring Boot
SNS login with Spring Boot
[Java] Thymeleaf Basic (Spring Boot)
File upload with Spring Boot
Spring Boot starting with copy
Until INSERT and SELECT to Postgres with Spring boot and thymeleaf
How to call and use API in Java (Spring Boot)
CICS-Run Java application-(4) Spring Boot application
Spring Boot starting with Docker
Hello World with Spring Boot
Set cookies with Spring Boot
Use Spring JDBC with Spring Boot
Add module with Spring Boot
Getting Started with Spring Boot
[Java] [Spring] Spring Boot 1.4-> 1.2 Downgrade Note
Create microservices with Spring Boot
Introducing Spring Boot2, a Java framework for web development (for beginners)
Send email with spring boot
Build WebAPP development environment with Java + Spring with Visual Studio Code
[Java] Sample project for developing web applications with Spring Boot
Easily develop web applications with STS and Spring Boot. In 10 minutes.
Comparison of WEB application development with Rails and Java Servlet + JSP
Image Spring Boot app using jib-maven-plugin and start it with Docker