领域驱动模型设计简单应用
2023年4月8日大约 3 分钟
专业术语
Domain-Driven Design 领域驱动设计
DataAccessobjects DAO 数据存取对象
PersistenceObject PO 持久化层对象
DataTransferObject DTO 数据传输对象
ViewObject VO 视图对象
DomainObject DO 领域对象
view 展现层
service 服务层
po 数据持久化层
防腐 领域之间互相访问获取到的其他域的模型需要转换映射到自己域的模型(域之间可能会有相互的依赖,需要注意域之间的防腐,并且依赖注入的方式注入而不是直接New其他域的对象出来使用)
界限 域拆分依据业务水平拆分,平行而非上下
领域驱动三层架构 API层\Domain层\Repository层
领域驱动三层架构
API层\Domain层\Repository层
API层负责对外的rpc\http接口
Domain层领域逻辑层,负责组装数据源代理层 po 返回的数据模型,转换为领域模型Domain Object
Repository层是数据源代理层,比如有一层抽象 interface GetUser 那么这个User内部可能有多
个实现有 Elastic\MySQL\MongoDB,也可以是以HTTP或者RPC为数据源
而数据源代理层再底层就是持久化层或者RPC依赖等
有什么用?
按照数据流向是一个垂直分层的结构
PO层可以随时更换比如MySQL更换为MongoDB
Domain域模型是固定的,逻辑是抽象可更改实现
API层负责对外模型与前端或者其他微服务
1. 单元测试,解耦有利于对每一层测试覆盖
2. 可扩展性,解耦有利于各个业务之间剥离比如将两个同属一个微服务的域拆成两个微服务或者独立他们依赖的持久化层
领域驱动下的项目层级
├── application
│ ├── admin_service
│ │ ├── dto
│ │ └── user.go
│ │ └── grpc
│ │ └── user_rpc.go
│ ├── event
│ └── user_event.go
│ ├── message
│ └── user_message.go
│ └── front_service
│ ├── dtos
│ └── http
│ └────── init.go
├── config
│ └── config.go
├── domain
│ ├── common
│ │ ├── entity
│ │ └──----------- do.go
│ │ └── repository
│ │ └──----------- repository.go
│ │ └──----------- po.go
│ │ └──----------- mysql_po.go
│ │ └──----------- elastic_po.go
│ │ service.go
│ ├── user
│ │ ├── entity
│ │ └──----------- do.go
│ │ └── repository
│ │ └──----------- repository.go
│ │ └──----------- po.go
│ │ └──----------- mysql_po.go
│ │ └──----------- elastic_po.go
│ │ service.go
├── global
│ ├── cache
│ ├── enum
│ └── router
├── cmd
│ └── main.go
└── helper
└── times.go
如上所示
1. domain里有通用域common、业务域user等
2. application提供对外的API层(http或者rpc形式)同时 application 依赖 domain.user\domain.book等
3. event 是领域事件,这里没有写入domain而是直接挂一级目录,承载各个定时程序
4. message 消息处理,这里负责对一些外部消息接收处理比如kafka的messsage.consumer
5. config 配置依赖处理
6. cmd 编译入口也是程序执行入口
7. global 与helper不一样的是这里的都是耦合业务的一些通用的枚举值、缓存key管理、路由等
8. helper 工具类
其他的私有Git库依赖
- util 工具库(完全与业务无耦合)
- config 通用配置结构体定义(配置结构体\nacos配置加载\填充团队的默认配置比如kafka的消费心跳、poll数量、mongodb的集群配置样例等)
- proto RPC接口(具体实现的server和调用client在其他微服务)
- logger 日志类库(实现与zap\logrus\log一致的抽象、接入企业微信告警、邮箱告警、Elastic持久化日志(异步主动push形式采集或者打印标准输出宿主机的Filebeat采集))
- common_errors 通用错误定义(错误码\错误提示\国际化等)
- gin-middleware 通用的中间件(prometheus.request.metrics\jwt\encrypt请求解密\敏感字符过滤器等)
- common 微服务中通用基础库(与业务有耦合定义kafka\redis\mysql\elastic的客户端client.Builder)