基于Clean Architecture实现创建客户端后聚合通知的方案咨询
Clean Architecture 下聚合通知逻辑实现方案
核心遵循Clean Architecture的依赖规则:所有依赖必须指向内层,内层代码完全不感知外层实现细节,仅依赖自身定义的抽象。
1. 实体层(Entities)改造
这一层存放核心业务属性和最基础的业务规则,不需要依赖任何外层代码:
- 在
UserEntity中补充用户偏好的通知渠道属性,属于和用户绑定的核心业务字段 - 新增领域事件实体
ClientAssignedEvent,包含客户端ID、负责人ID、事件触发时间等核心字段,作为跨组件传递通知触发信号的载体,不绑定任何外部实现逻辑
2. 用例层(Use Cases)逻辑编排
这一层只负责编排业务流程,完全不关心通知的具体发送实现:
- 原有
CreateClientUseCase完成客户端创建、负责人绑定的核心逻辑,数据落库完成后直接发布ClientAssignedEvent事件即可,不需要同步处理通知逻辑,避免核心创建流程和非核心通知逻辑耦合,通知发送失败也不会影响主流程 - 新增独立的
SendClientAssignedNotificationUseCase,专门处理该场景的通知逻辑:- 接收
ClientAssignedEvent作为入参 - 分别组装面向客户端的绑定负责人通知内容、面向负责人的新增负责客户端通知内容
- 调用用例层定义的抽象通知发送端口完成多渠道推送,这里仅依赖抽象接口,不关联具体的SMS/Email/Push实现
用例层定义的抽象通知端口示例:
- 接收
// 用例层定义的抽象通知契约,所有外层渠道实现都要满足该接口要求 type NotificationSender interface { Send(targetID string, content string, allowChannels ...string) error }
3. 接口适配器层(Interface Adapters)实现抽象
这一层负责做内层逻辑和外层服务的转换适配:
- 实现用例层定义的
NotificationSender接口,封装渠道路由逻辑:根据用户配置的通知渠道,自动匹配对应的渠道实现,屏蔽不同渠道的调用差异,对用例层暴露统一的调用方式 - 事件监听组件也放在这一层,监听
ClientAssignedEvent事件,触发SendClientAssignedNotificationUseCase的执行,实现核心创建流程和通知流程的完全解耦
4. 框架与驱动层(Frameworks & Drivers)
这一层存放最外层的第三方服务对接逻辑:
- 单独封装Email服务SDK、Push推送服务、SMS短信服务的具体调用逻辑,仅对接口适配器层暴露简单的调用方法,这一层的渠道替换、SDK升级等修改完全不会影响内层的业务逻辑
实现收益
- 核心业务逻辑和非核心通知逻辑完全隔离,可独立迭代、独立测试
- 后续新增通知渠道、修改通知规则仅需要改动适配器层和框架层代码,不需要修改实体层、用例层的核心业务逻辑,符合开闭原则
- 通知逻辑可独立复用,其他业务场景需要发送通知时可直接调用对应用例,不需要重复开发
内容的提问来源于stack exchange,提问作者Alexander Kiselev
相关产品推荐
相关产品推荐

