领域驱动分层实践
三类对象:DTO,领域对象,PO
一、分层参考
a、基础设施层infrastructure
--client
--common
--event
--api
--util
b、领域层
domain
leave
--entity
--valueobject(包含结构体,枚举等)
xxDomainObject(唯一标识,字段,方法 return this 操作属性集合)
--event
xxEvent
xxEventType
--repository
facade
xxInterface
mapper
xxDao
persistence
xxRepositoryImpl
po
xxPO
--service
xxService(返回具体的领域对象)
xxFactory (领域对象与PO对象转换)重要创建Factory***
c、聚合服务层
application.service
xxxService (聚合层服务,领域服务编排,操作领域对象)
d、对外接口层 interfaces
--assembler (领域对象与DTO转换)
--dto
--facade
xxApi
---------------------------------------
xxDomainObject示例
@Data
public class Leave {
String id;
Applicant applicant;
Approver approver;
LeaveType type;
Status status;
Date startTime;
Date endTime;
long duration;
//审批领导的最大级别
int leaderMaxLevel;
ApprovalInfo currentApprovalInfo;
List<ApprovalInfo> historyApprovalInfos;
public long getDuration() {
return endTime.getTime() - startTime.getTime();
}
public Leave addHistoryApprovalInfo(ApprovalInfo approvalInfo) {
if (null == historyApprovalInfos)
historyApprovalInfos = new ArrayList<>();
this.historyApprovalInfos.add(approvalInfo);
return this; //重点返回this
}
xxEvent示例
@Data
public class LeaveEvent extends DomainEvent {
LeaveEventType leaveEventType;
public static LeaveEvent create(LeaveEventType eventType, Leave leave){
LeaveEvent event = new LeaveEvent();
event.setId(IdGenerator.nextId());
event.setLeaveEventType(eventType);
event.setTimestamp(new Date());
event.setData(JSON.toJSONString(leave));
return event;
}
}
common.event
@Data
public class DomainEvent {
String id;
Date timestamp;
String source;
String data;
}
xxService示例
@Transactional
public void submitApproval(Leave leave, Approver approver) {
LeaveEvent event;
if ( ApprovalType.REJECT == leave.getCurrentApprovalInfo().getApprovalType()) {
//reject, then the leave is finished with REJECTED status
leave.reject(approver);
event = LeaveEvent.create(LeaveEventType.REJECT_EVENT, leave);
} else {
if (approver != null) {
//agree and has next approver
leave.agree(approver);
event = LeaveEvent.create(LeaveEventType.AGREE_EVENT, leave);
} else {
//agree and hasn't next approver, then the leave is finished with APPROVED status
leave.finish();
event = LeaveEvent.create(LeaveEventType.APPROVED_EVENT, leave);
}
}
leave.addHistoryApprovalInfo(leave.getCurrentApprovalInfo());
leaveRepositoryInterface.save(leaveFactory.createLeavePO(leave));
leaveRepositoryInterface.saveEvent(leaveFactory.createLeaveEventPO(event));
eventPublisher.publish(event);
}
xxApi示例
@GetMapping("/findFirstApprover")
public Response findFirstApprover(@RequestParam String applicantId, @RequestParam int leaderMaxLevel) {
Person person = personApplicationService.findFirstApprover(applicantId, leaderMaxLevel);
return Response.ok(PersonAssembler.toDTO(person));
}
------------------------------------------------------------------------------------------------------------------
调单系统代码研究
1、6边形架构
外6边形(技术域)
in:定时任务、Web接入点、RPC接入点、MQ消费者
out:MQ适配器、RPC适配器、仓库(mysql、redis、lucence.net)
内6边形(业务域)
应用服务->创建工厂->创建领域对象(聚合根、实体、值对象、事件)
-----更新-----领域对象(聚合根、实体、值对象、事件)
2、Assembler
1、负责PO对象与领域对象转换
2、负责Active当前对象与存量对象转换
3、复杂对象组成方式
@Slf4j
@Service
public class BatchManipulateCollectsRequestAssembler {
private final BatchManipulateCollectionBuilderFactory batchManipulateCollectionBuilderFactory;
private final CollectionBuilderFactory collectionBuilderFactory;
private final UpdateCollectionBuilderFactory updateCollectionBuilderFactory;
private final FinishCollectionBuilderFactory finishCollectionBuilderFactory;
private final TerminateCollectionBuilderFactory terminateCollectionBuilderFactory;
@Autowired
public BatchManipulateCollectsRequestAssembler(BatchManipulateCollectionBuilderFactory batchManipulateCollectionBuilderFactory,
CollectionBuilderFactory collectionBuilderFactory,
UpdateCollectionBuilderFactory updateCollectionBuilderFactory,
FinishCollectionBuilderFactory finishCollectionBuilderFactory,
TerminateCollectionBuilderFactory terminateCollectionBuilderFactory) {
this.batchManipulateCollectionBuilderFactory = batchManipulateCollectionBuilderFactory;
this.collectionBuilderFactory = collectionBuilderFactory;
this.updateCollectionBuilderFactory = updateCollectionBuilderFactory;
this.finishCollectionBuilderFactory = finishCollectionBuilderFactory;
this.terminateCollectionBuilderFactory = terminateCollectionBuilderFactory;
}
xxFactroy: 检验器xxxValidator + xxxBuilder.create()方法
@Component
public class BatchManipulateCollectionBuilderFactory {
private final FieldsFormatValidator fieldsFormatValidator;
public BatchManipulateCollectionBuilderFactory(FieldsFormatValidator fieldsFormatValidator) {
this.fieldsFormatValidator = fieldsFormatValidator;
}
public BatchManipulateCollectionReqBuilder create() {
return new BatchManipulateCollectionReqBuilder(this.fieldsFormatValidator);
}
}
toDo(service层:领域对象),toDTO(control层:DTO),toPO(持久层:PO)
3、Sharding jdbc指定库表
@DS("cddcollect")
public interface TCollectManagerMapper extends CustomBaseMapper<TCollectManager> {
@Select({"<script> SELECT * from cdd_collect_${dbIndex}.t_collect_manager_${tabIndex} ",
"where Fwaiting_collection_count>0 ",
"limit 1000;",
"</script>"})
List<TCollectManager> queryShouldFuseCollectManager(@Param("dbIndex") String dbIndex,
@Param("tabIndex") String tabIndex);
}
4、ExceptionFactry 异常工厂
+bizException业务异常
+sysException系统异常
+retryableBizException 可重试异常
-----------------------------------------------------
内6边形(业务域)
应用服务->创建工厂->创建领域对象(聚合根、实体、值对象、事件)
-----更新-----领域对象(聚合根、实体、值对象、事件)
application:聚合服务层,负责领域服务的流程编排以及领域事件的发布
domain:具体领域,基于接口编程
- model 包含聚合根,实体、值对象、常量、请求参数类、返回参数类
- validate: 字段检验规则
- factory: 包含validate检验器,以及XxxBuilder.create()方法(生产者模式)
当创建领域对象时,调用build()方法,赋值Builder字段给领域对象时,前置先检验字段是否合法
- exception
- repository:定义接口
- serivce: 领域服务接口+具体实现
--------------------------------------------------------------------------------------------------------------------
外6边形(技术域)
in:定时任务、Web接入点、RPC接入点、MQ消费者
out:MQ适配器、RPC适配器、仓库(mysql、redis、lucence.net)
adapter
in:
mq消费者:
task定时任务:发件箱
web: 接口、运维接口
out
mq生产者:发布事件
仓库:mysql
RPC适配器:业务服务、配置服务、Qf发送消息服务、分布式锁(redis,zk)服务、发件箱服务
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix