设计模型之DDD开发模式
MVC 设计模式
- 数据层(Model)
模型是应用程序的
数据和业务逻辑的表示
。它负责处理数据的读取、存储和操作,以及业务规则的处理
。模型通常是独立于用户界面的,可以在不同的视图和控制器之间共享和重用。
- 展示层(View)
视图是
用户界面的呈现部分
,负责展示数据给用户,并接收用户的输入。视图通常是根据模型的数据进行渲染和更新的,它可以是Web页面、图形界面或命令行界面等。
- 逻辑层(Controller)
控制器是
模型和视图之间的协调者
,负责接收用户的输入并根据输入调用相应的模型逻辑。控制器将用户的请求转发给模型进行处理,并将处理结果传递给视图进行展示。控制器还可以处理视图的事件和状态变化。
Controller : 前端交互,暴露接口 ↑
Service(#) :核心业务逻辑
Dao :数据库交互,数据存取 ↓
模式对比
传统模式
- Controller + VO
- Service + BO 完全数据逻辑隔离,~O只做数据结构;破坏了面向对象封装特性,是典型面向过程的编程风格
- Dao + Entity
不足:
传统架构模式存在关注点分离不足的问题,导致各层之间耦合度高,
业务逻辑与SQL查询交织在一起。这种方式难以维护和扩展应用,因为一个层面的改动通常需要跨多个层面进行修改。此外,服务层过度依赖SQL查询
,限制了灵活性,使得难以适应变化的需求或切换到不同的数据存储方案。
// Entity 实体类
public class User {
private int id;
private String username;
private String email;
// 省略其他属性和构造函数
}
// Repository 数据访问层
public class UserRepository {
public List<User> getUsers() {
// 执行 SQL 查询,获取用户数据
String sql = "SELECT * FROM users";
// 执行查询操作,返回结果集
// 省略数据库连接、执行查询等代码
return userList; // 假设从数据库获取了用户列表
}
}
// Service 业务逻辑层
public class UserService {
private UserRepository userRepository;
public UserService() {
this.userRepository = new UserRepository();
}
public List<User> getAllUsers() {
// 调用 UserRepository 获取用户列表
return userRepository.getUsers();
}
}
// Controller 控制器层
public class UserController {
private UserService userService;
public UserController() {
this.userService = new UserService();
}
public void getAllUsers() {
// 调用 UserService 获取所有用户
List<User> users = userService.getAllUsers();
// 处理用户数据,如返回给前端或进行其他操作
// 省略处理逻辑
}
}
DDD模式
DDD的分层架构
DDD整体设计框架
代码设计
一级目录
在领域驱动设计(DDD)架构中,通常将"common"作为一个通用的层级,用于存放领域模型中多个领域都通用的部分。
具体来说,在常见的DDD架构中,通常包括以下层级:
应用服务层(Application Service)
:处理用户请求,协调领域对象之间的交互,实现应用的用例或业务逻辑。
领域层(Domain)
:包含领域对象、实体、值对象、聚合根等,表达业务领域的概念和规则。
基础设施层(Infrastructure)
:提供支持应用程序运行的基础设施,例如数据库访问、日志、消息队列等。
common层(Common)
:作为一个通用层级,存放多个领域都通用的部分,如工具类、常量定义、通用方法等。
在common层中,通常会放置那些不属于特定领域的通用组件,以便多个领域可以共享和复用这些功能。这样能够提高代码的可维护性和可重用性,避免重复开发相似功能。总的来说,common层在DDD架构中扮演着促进代码重用和降低耦合度的重要角色。
二级目录
用户接口层(User Interface Layer)
用户接口层负责向用户显示信息和解释用户指令,并将数据传递给 Application 层。数据的组装、数据传输格式以及 Facade 接口等代码都会放在这一层目录里。这里的用户可能是:用户、程序、自动化测试和批处理脚本等等。
req(请求)
在接口层中,req 表示客户端发送给服务器的请求。请求可能包含用户的操作需求、所需的参数以及其他相关信息。req 用于描述客户端与服务器之间的通信过程中所发送的请求内容。
resp(响应)
resp 表示服务器发送给客户端的响应。响应包含了服务器处理请求后的结果、状态码、错误信息等。resp 用于描述客户端与服务器之间的通信过程中所接收到的响应内容。
service(服务)
在接口层中,service 表示提供给客户端调用的服务。服务封装了特定的业务逻辑或功能,并对外提供接口供客户端调用。service 用于实现客户端所需的具体功能,并处理客户端发送的请求,返回相应的响应。
应用层(Application Layer)
应用层是DDD架构中的核心层次之一,负责协调领域层和用户接口层之间的交互。它包含了应用服务(Application Services),
应用层是很薄的一层,理论上不应该有业务规则或逻辑,主要面向用例和流程相关的操作
。`但应用层又位于领域层之上,因为领域层包含多个聚合,所以它可以协调多个聚合的服务和领域对象完成服务编排和组合,协作完成业务操作。
controller(控制器)
在应用层中,controller 通常用于处理用户的请求和响应。它包含了应用程序的控制器(Controller),负责接收用户的请求、调用相应的服务(service)处理业务逻辑,并将处理结果返回给用户。控制器可以是针对不同功能或资源的处理器,用于实现用户接口层与应用层之间的交互。
job(任务)
在应用层中,job 可能指的是后台任务(Background Job)或定时任务(Scheduled Job)。后台任务通常用于处理一些异步任务或批处理任务,例如数据清理、邮件发送、报表生成等。定时任务用于按照一定的时间间隔或时间规则执行特定的任务。这些任务可能需要在应用层中进行处理和调度。
mq(消息队列)
在应用层中,mq 可能指的是与消息队列(Message Queue)相关的代码或模块。消息队列用于实现异步消息传递,允许应用程序之间发送和接收消息。在应用层中,可能会使用消息队列来处理异步任务、事件发布订阅、任务调度等功能。mq 目录可能包含与消息队列相关的代码、配置和实现。
领域层(Domain Layer)
领域层是应用程序的核心部分,包含了业务逻辑和领域对象的定义。在领域层中,开发人员使用领域驱动设计的原则来描述业务领域中的概念和规则。领域层通过领域模型描述业务逻辑,
并包含领域对象、实体、值对象、聚合根、领域服务等。
领域层负责保护领域逻辑的完整性和一致性,同时也是应用程序的灵魂和核心。
Entity(实体)–核心业务
实体代表领域中的概念或对象,它具有唯一的标识符,并且具有状态和行为。实体通常代表领域中的核心业务对象,例如订单、用户、产品等。实体通常封装了领域中的业务逻辑,负责处理自身状态的变化和行为的操作。实体的状态和行为应该与领域的业务规则密切相关,并且对外提供接口供应用层调用。
Service(服务)–跨实体的复杂业务逻辑
服务是一种用于封装领域逻辑的对象,它不属于任何特定的实体,而是用于处理跨实体的业务逻辑。服务通常包含了领域层中的复杂业务逻辑,例如计算、验证、处理事务等。服务通常用于实现那些不适合放在单个实体中的业务逻辑,或者需要跨多个实体进行协作的业务操作。服务的存在有助于保持实体的纯粹性和简洁性,同时促进领域逻辑的组织和重用。
基础设施层(Infrastructure Layer)
基础设施层包含了与外部系统进行交互和支持应用程序运行的所有代码和组件。它包括数据库访问、文件系统、消息队列、日志、缓存、外部API等。基础设施层提供了应用程序所需的技术基础设施,并负责处理与外部系统的通信和集成。基础设施层的目标是提供稳定可靠的基础设施,使应用程序能够正常运行并与外部系统进行通信。
- 基础层的二级目录下的子目录mapper作用
具体来说,mapper 目录可能包含了与数据映射相关的代码或模块,用于将领域对象(Domain Objects)与持久化存储(如数据库表)之间进行转换和映射。这种转换通常涉及将领域对象的属性值映射到数据库表的字段,或者将数据库表的查询结果映射为领域对象。
basic(基础)
“basic” 可能用来指代基本的通信协议或通信方式,例如 HTTP 协议、TCP 协议等。在基础层中,“basic” 可能包含与基本通信方式相关的代码或模块,用于实现应用程序与外部系统之间的通信。
rpc(远程过程调用)
“rpc” 可能用来实现远程过程调用(Remote Procedure Call)功能。在基础层中,“rpc” 可能包含与远程服务调用相关的代码或模块,用于实现不同系统之间的通信和集成。通过 RPC,一个系统可以调用另一个系统提供的服务或方法,实现跨系统的功能调用和数据交换。
service(服务)
“service” 可能用来指代提供特定服务或功能的代码或模块。在基础层中,“service” 可能包含各种与业务逻辑无关的服务,例如日志服务、缓存服务、认证服务等。这些服务提供了一些通用的功能和服务,供应用程序在需要时调用和使用。
mq(消息队列)
“mq” 可能用来指代与消息队列(Message Queue)相关的代码或模块。在基础层中,“mq” 可能包含与消息队列的集成和使用相关的代码或模块,用于实现应用程序之间的异步消息通信和事件驱动。通过消息队列,不同的应用程序可以发送和接收消息,实现解耦和异步通信。