前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >DDD应用服务、领域服务傻傻分不清楚?看这篇就够了

DDD应用服务、领域服务傻傻分不清楚?看这篇就够了

作者头像
Louis XIV
发布于 2025-03-27 06:16:42
发布于 2025-03-27 06:16:42
14400
代码可运行
举报
文章被收录于专栏:支付进阶之路支付进阶之路
运行总次数:0
代码可运行

很多小伙伴在实践DDD的过程中,一直分不清应用服务 Application Service(后面简称App)领域服务 Domain Service(后面简称Domain)。最近在和几个同学在业余时间做一个小帅包子铺项目,同样遇到这些问题:

  1. App层和Domain层职责上有什么区别?
  2. 这两层的输入、输出分别是什么?
  3. 事务应该在哪一层管理?
  4. 即便业务逻辑非常简单也要拆两层吗,会不会显得太啰嗦?
  5. 这两层是不是都可以访问repository?

光讲概念就没意思了,下面我会结合小帅包子铺中的一个小场景说一说。

1. 举一个🌰

如果你第一次访问小帅包子铺系统(后面简称系统),会要求通过手机号登录,输入手机号、获取验证码,提交登录就可以了。

讲个题外话,这个系统是真实存在的,完全基于DDD开发,预计在4月底会上线。文末有对这个项目的介绍。

在你提交登录后,系统需完成这些事:

  1. 验证短信验证码的正确性。如果验证不通过,则登录失败
  2. 判断该手机号是否已注册,如果还未注册,自动注册一个新用户,并开通余额账户
  3. 注册成功将会发送一条短信:欢迎你来到小帅包子铺
  4. 设置登录状态

我们尝试用时序图画一下这个过程,假设这时只有一个Service层:

这个时序图没什么大毛病,只是直觉上看起来,好像Service承担的东西有点多

2. 职责拆分

这时很容易能想到,把职责稍微拆分一下,分给其他的Service,我们忽略掉其他要素,只保留Service,大概是这样:

这时你会发现,Service的层级就显示出来了,LoginService是在组合其他几个Service的能力,这就是App和Domain Service的第一个区别

  • App层是在对Domain层的服务进行编排组合
  • Domain层提供的是原子能力

仅此而已吗?为了做一个简简单单的登录,居然用了4个Service!!当然不是,划分出来的Domain层会有更大的用途。

3. 复用

现在我们有第二个需求:如果用户是在包子铺门店直接买包子,可以向收银员报一个手机号,假如这个手机号还未注册,则直接注册成为一个新用户。(收银员会在收银机上操作,下单时录入手机号)

咦?在门店买包子和登录,这两件事居然有交集了!它们都有可能发生用户注册。这时就可以把用户注册进行复用了,同时优化一下Service之间的关系:

这就是App和Domain Service的第二个区别

  • Domain Service能提供复用能力
  • App层尽量不去复用,例如登录也可以分为短信验证码登录、微信登录、邮箱登录,但这几种登录方式逻辑上有本质区别,应在App层提供多种不同的登录接口

4. 输入和输出

App层和Domain层的输入、输出(也就是入参、出参)有区别吗?

当然有区别,例如不同的登录方式,App层接口定义可能是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface LoginAppService {
// 短信登录,需要手机号、验证码
// 返回通用Response,带user id
Response<String> smsLogin(SMSLoginReq req);

// 邮箱登录,邮箱、密码
// 返回通用Response,带user id
Response<String> emailLogin(EmailLoginReq req);
}

在App层,为了保证与客户端交互上的一致性,会使用通用的返回体Response,如果发生了异常,需要在Response里设置错误码。

但在Domain层,为保证最大程度可以复用,不能把App层的req对象透传下来,而是需要先转化为领域对象,因此Domain层的接口定义是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface UserService {
  // Domain层直接以领域对象做为入参,注册是一个写请求,无需返回值
  void register(User user);
}

这是App和Domain Service的第三个区别

5. 其他区别

  • 事务应该在哪一层管理?

通常情况下,事务应该是在App层管理,App既然做为编排组合的组织者,需要保证事务性

  • 即便业务逻辑非常简单也要拆两层吗,会不会显得太啰嗦?

我的个人习惯来说,如果业务逻辑足够简单,且没有可复用的部分,可以不需要Domain层

  • 这两层是不是都可以访问repository?

都可以的,只是说如果有Domain层进行了一些原子化封装,就可以尽量把对repository的访问下沉到Domain

在架构上新增一个层,不仅是加了一层这么简单,层数的增加意味着架构变得复杂,需要考虑的因素也要更多。我只看是否能解决某些问题,若不能解决问题,加再多层也只是增加负担。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 支付进阶之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 举一个🌰
  • 2. 职责拆分
  • 3. 复用
  • 4. 输入和输出
  • 5. 其他区别
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档