领域驱动设计(DDD)代码风格
目录
- 介绍
- DDD核心概念
- 项目结构
- 包的结构
- 代码示例
- 总结
介绍
领域驱动设计(DDD)是一种软件设计方法,通过以领域模型为中心的方式构建复杂的系统。DDD强调领域专家和开发团队之间的协作,并将业务逻辑集中在领域模型中。本文档详细介绍了如何在项目中应用DDD,包括项目结构、包的布局和代码示例。
DDD核心概念
领域(Domain): 业务领域,是问题空间的核心部分。
子域(Subdomain): 领域内的子部分,可以是核心域、支撑域或通用域。
限界上下文(Bounded Context): 定义了模型的适用范围和边界。
实体(Entity): 具有唯一标识的对象。
值对象(Value Object): 无唯一标识的对象,描述某些特性。
聚合(Aggregate): 一组关联的实体和值对象,具有一致性的边界。
仓储(Repository): 提供对聚合的持久化操作。
服务(Service): 封装业务逻辑的操作。
项目结构
一个典型的DDD项目结构如下:
- project-root
- infrastructure
- frame
- system
- server
- domain
- application
- interface
- messaging (可选)
- Application.java
比如若以:
包的结构
- Infrastructure (基础设施模块)
包含基础设施相关的代码,如数据库配置、外部服务接口、工具类和通用配置。
- infrastructure
- config
- DatabaseConfig.java
- external
- ExternalServiceClient.java
- utils
- CommonUtils.java
- config
- Frame (框架模块)
包含项目框架和安全相关的配置,包括AOP、配置类等。
markdown
- frame
- security
- SecurityConfig.java
- aop
- LoggingAspect.java
- config
- AppConfig.java
- security
- System (系统模块)
处理系统级别的功能,比如用户管理、角色权限管理等。
- system
- user
- UserController.java
- UserService.java
- User.java
- role
- RoleController.java
- RoleService.java
- Role.java
- permission
- PermissionController.java
- PermissionService.java
- Permission.java
- menu
- MenuController.java
- MenuService.java
- Menu.java
- user
- Server (业务模块)
处理核心业务逻辑,包括领域服务和应用服务。
- server
- domain
- model
- User.java
- Order.java
- service
- UserService.java
- OrderService.java
- repository
- UserRepository.java
- OrderRepository.java
- model
- application
- UserApplicationService.java
- OrderApplicationService.java
- interface
- UserController.java
- OrderController.java
- startup
- ApplicationStartup.java
- domain
- Messaging (可选)扩展的魔窟奥
包含消息队列和事件处理的相关代码。
- messaging
- queue
- MessageQueueService.java
- event
- EventListener.java
- queue
总结
通过将项目划分为多个模块和层次,并使用适当的注解和结构,可以构建一个符合DDD原则的清晰且可维护的项目。以下是一些关键点:
领域模型和业务逻辑:放在各自模块的领域层和应用层中。
接口层:放在各自模块中,直接使用该模块的领域模型。
通用功能:放在基础设施模块中,以便在多个模块间共享。
合理使用注解:在合适的地方使用合适的注解,如 @Service、@Repository、@Mapper 等,以确保代码清晰可维护。
比如Mpapper注解更多的是对于mybatis的使用如果其他orm框架应该使用@Repository,@Repository是对数据进行交互的组件注解,准确来说比如Mybatis-x生成的Service应该用这个注解注入,而Service注解更应该关心的是业务方面
比如mybatis中一个Service只是对一个数据库相关的业务实现,那么如果设计到多个表的操作,是不是再用这个@sercie又不太合理了,并且Service接口就是应该要发挥多实现的特性,业务层的多实现,服务命名为反映业务操作的名称