问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

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

创作时间:
作者:
@小白创作中心

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

引用
1
来源
1.
https://cloud.tencent.com/developer/article/2508359

在领域驱动设计(DDD)实践中,应用服务(Application Service)和领域服务(Domain Service)是两个容易混淆的概念。本文通过一个"小帅包子铺"的登录场景,详细解释了两者的区别,包括职责划分、复用性、输入输出等方面的差异。

很多开发者在实践DDD的过程中,一直分不清 应用服务 Application Service(后面简称App)领域服务 Domain Service(后面简称Domain) 。让我们结合一个具体的场景来说明它们的区别。

1. 举一个🌰

假设你第一次访问小帅包子铺系统(后面简称系统),需要通过手机号登录。登录流程包括:输入手机号、获取验证码,提交登录。

在你提交登录后,系统需完成以下任务:

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

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

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

2. 职责拆分

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

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

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

3. 复用

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

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

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

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

4. 输入和输出

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

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

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层的接口定义 是:

public interface UserService {
  // Domain层直接以领域对象做为入参,注册是一个写请求,无需返回值
  void register(User user);
}

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

5. 其他区别

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

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

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

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

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

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号