分布式系统中有三种接口粒度:
1.
内部用的domain service接口。这个接口最精致。
a. 出入参数跟数据库表有比较强的对应,基本上一个对象对应一张表。
b. 入参数据都假定已清洗,不必再校验。
c. 业务逻辑主要是CRUD+高度可重用的核心业务逻辑。
d. 返回数据一般是数据对象或者它们的类集。错误信息一般直接通过exception返回。
2.
供移动或web前端调用、或者供外部系统调用、面向use case的app service接口。这个接口最重。
a. 出入参数一般对应数据库中的多张表中的数据,还会有一些use case特有的字段,比如一个“帖子”对象中会给出“帖子作者的头像”、“当前用户能否删除本贴”、“帖子被评论次数”等。 这一层的数据对象是DTO(value object), 一般要从多个domain层对象的字段中组合而来。
b. 入参数据由用户直接输入或非可信系统输入,所以需要校验。
c. 业务逻辑一般需要通过组合多个domain service实现,比如 N个crud + 1个权限校验 + 1个展示层数据填充等,很难重用。
d. 返回数据一般是Result对象: 数据对象 + 错误码 + 错误信息, 不再抛exception.
3.
给内部可信系统调用的rpc service接口。这个接口的轻、重介于上面两种之间。
a. 出入参数包含的字段往往比domain层参数的稍多一点,比app层参数的少一些或少很多。
b. 入参数据基本已清洗(比如字符串都trim过了),但为了系统健壮性还是要做些校验,尤其是空值判断。
c. 业务逻辑基本上就是domain service, 顶多按特定业务做一些增补。
d. 由于远程调用的特殊性,直接通过exception返回错误信息可能会引起报文过大;所以返回数据对象一般也可以是Result对象: 数据对象 + 错误码 + 错误信息。
很多情况下domain service可以直接用作rpc service. 问题在于domain层可能变化比较频繁并且不保证版本向下兼容,为了不让调用方困扰,一般还是要专门搞一套。