如果是本地调用
interface UserService {
User getUser(int userId);
}
返回的 user 可以有行为, 调用方不必取出 user 字段来进行逻辑判断.
但如果是 RPC 调用, 返回的 User 一般都没有行为. 调用方会取出数据字段来进行业务处理, 这样, 业务逻辑代码会分散到各个地方.
如果 RPC 调用返回的对象也是充血多好.
铁子们, 你们是如何处理 RPC 返回贫血模型呢? 如果返回贫血模型, 如何避免业务逻辑分散在各个地方?
1
xuanbg 2021-01-09 18:43:42 +08:00
你完全可以反序列化成充血模型
|
2
gjkv86 2021-01-09 18:51:43 +08:00
RPC 为何要返回充血模型?这种主要是传输对象的状态吧。 其结果需要有基于可以传输的 user 再有一到两层的包装再使用。你传输的只是对象的状态,这个可传输的对象确实没必要很复杂。 但上层使用时,需要有再次的封装,而不是直接拿来用。这样也避免了传输的模型发生了变化,把变化波及的上层。
|
3
wangyanrui 2021-01-09 19:06:11 +08:00 via Android
rpc 传输的是 dto,业务方使用时自行定义 bo 包裹一下呀🙄
|
4
chendy 2021-01-09 19:54:00 +08:00
把业务封装进模型到处传播,不还是把业务分散掉了么
|
5
daimazha 2021-01-09 19:54:23 +08:00
看一下六边形架构
|
6
YouLMAO 2021-01-10 00:46:36 +08:00 via Android
你们说的中文真的是脑壳疼了,微服务啊,user 服务当然是跟 user 相关的读写都在 user 微服务,怎么可能你取出 user rpc 的字段写自己逻辑呢,万一逻辑变了,你不就造成事故了吗,当然是 user 微服务做逻辑而不是上层做逻辑
|
7
yzbythesea 2021-01-10 06:05:10 +08:00
充血和贫血给我头都看晕了。
|
8
yzbythesea 2021-01-10 06:06:39 +08:00
你的意思是想执行 User.SayHi( ) 这种?这个正确做法是在 User Service 执行,然后提供 API,sayHiFromUser( )
|
9
taowen 2021-01-10 09:12:21 +08:00 via Android
user service 封装 user 可以做的一切事情,那啥事 user service 是不管的?
|
10
Kirsk 2021-01-10 10:23:22 +08:00 via Android
写一个公共项目 只放 service 接口 通过接口调用
|
11
Kirsk 2021-01-10 10:26:45 +08:00 via Android
@Kirsk 实现与调用分离 也就是长见的一个接口一个实现 不过如果实现写的垃圾比较容易出问题 至少保证每个业务实现的独立性
|
12
asanelder OP @xuanbg #1 铁子意思是在 User 中添加相关业务方法? User 一般不都是生成的么?比如 thrift 使用 idl 定义, 然后生成 user 类。然后在生成的 User 类中再添加自定义方法?
@gjkv86 #2 @wangyanrui #3 也就是使用方有个 UserWrapper 之类的, 然后这个类有业务逻辑? @daimazha #5 这个看过, 但不知道使用六边形架构怎么解决俺的问题, 铁子请明示 @YouLMAO #6 如果说微服务做业务逻辑,然后通过接口给 client 使用, 会出现这样一个问题。 可能 client 的业务要基于 user 的多个字段做操作, 比如 age 和 sex, 然后有四种结果, 然后把这个业务逻辑放到微服务中, 通过接口提供可能无法方便返回四种结果。 @yzbythesea #8 简单的业务逻辑可以放到微服务,但感觉有些复杂的, 通过一个接口不好满足。 @Kirsk #10 铁子的意思还是把业务放到接口后面? |
13
yzbythesea 2021-01-10 11:21:01 +08:00
@asanelder 你举一个比较困惑的例子呢?有可能业务复杂是因为你们各服务过于耦合。
|
14
daimazha 2021-01-10 11:42:09 +08:00
@asanelder #12 很简单,六边形架构里面,你 rpc 查询的数据会有个 adapter 来转换成系统的领域对象
|
16
ychost 2021-01-11 15:28:24 +08:00
提供二方包的时候打包一个 userValidator 公用等静态工具类就行了,直接返回充血模型不太友好,而且大多时候模型都是 idl 直接生成的,万一改漏了就麻烦了
|
17
asanelder OP |
18
gjkv86 2021-01-11 22:44:03 +08:00 via iPhone
你叫 wrapper 也可以,或其他什么都行。但是从职责上,正如有朋友指出的,传输的确实是 dto 一类的东西。而你说的对象包括业务行为的这种类,应该是属于你自己建模的一部分,他应该不依赖于 user 数据是 rpc 来的还是 db 来的。我理解的不一定符合这理论那理论,但代码之所以这样那样的封装,很重要的一个目的就是为了适应变化,封装变化。最大限度的自己掌控适应变化。
|