V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ljzxloaf
V2EX  ›  程序员

看了代码优雅实现的帖子想到的实践思路

  •  
  •   ljzxloaf · 2021-08-16 23:13:23 +08:00 · 1789 次点击
    这是一个创建于 1179 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前情提要:https://www.v2ex.com/t/796126?p=1#r_10794970

    实践中,我们一般可以同时提供两种接口:一种是不依赖其他业务的“原子”接口;另一种是依赖其他业务的“组合”接口。

    比如搜索,我可以同时提供:返回 id 集合的接口和返回 item 集合的接口。item 信息是我从 item 服务拿到的,这样我等于组合了 item 服务和搜索。反过来也类似,比如敏感内容过滤,我也可以提供两种接口:传参 id 集合和传参 item 集合,如果只传 id 我需要去 item 服务查 item 信息,就是组合接口;如果传给我 item 集合,我就不需要去依赖 item 服务。

    这种做法有什么好处呢?我们可以先考虑这样一个问题,我们有底层服务 A ( atom ),有两个上层服务 C1 、C2 ( combination ),现在有个需求要调用 C1 的接口 C1.I1 和 C2 的接口 C2.I1 ,这两个接口都要调用 A 的接口 A1.I1 ,这样我们为何不先调 A1.I1 ,然后把返回的信息传给 C1 和 C2 呢?当然当我们没有这种冗余调用的时候,还是用原来的接口,这样更方便。

    我分析下来这样做从性能方面应该是有利无害的。从 IO 方面来看,虽然直接传递 item 信息增加了传递参数的网络开销,但是由于不需要去查 item 服务,减少了一次 item 服务返回 item 信息的网络开销,这两者已经抵消了。而后者还减少了查 item 的请求网络开销,item 服务的计算开销,和依赖服务或 db 的计算和网络开销。所以性能无疑是提高了很多。

    上面只讨论了最简单的情况,其实实践中远比这复杂。上层服务会依赖多个下层服务,组合是千变万化的,不可能为每种组合都开个接口。比如 C 依赖 A1 和 A2,那就要四个接口,依赖 A1 的接口( A2 信息通过传参);依赖 A2 的接口( A1 信息通过传参);都不依赖(全部信息通过传参);都依赖。假设依赖 n 个服务,就需要(排列组合 n 选 n 、n-1...1,0 加和)个接口(科里化?),所以还是要根据实际情况具体问题具体分析,只提供那些用户普遍需要的组合,必要的时候可以另起服务以维护业务模型的清晰性( message passing -> multiple dispatch?)。

    XDM 觉得这种实践靠不靠谱,欢迎分享讨论

    6 条回复    2021-08-18 19:47:39 +08:00
    qin20
        1
    qin20  
       2021-08-17 09:32:53 +08:00
    前端,我上一个项目就是这样写的,禁止直接把原子组件放在页面上然后去写绑定业务逻辑,我抽象了一层,业务组件,页面中只能用业务组件。
    之前受到名言 never repeat you code 影响,一直是在代码的重复上去考虑是否封装,其实重用和重复确实存在区别,重复不等于重用,如果单纯的从代码的重复性去考虑代码的封装,并没有从业务去考虑这么好用。
    shilianmlxg
        2
    shilianmlxg  
       2021-08-17 09:50:10 +08:00
    @qin20 我们的产品 你在的话会跟吃 shi 一样难受。同一个模块,不同页面的相同组件,他说不是一个东西,我高度封装吃了 shi 一样,所以之后干脆封的差不多得了
    CasualYours
        3
    CasualYours  
       2021-08-17 10:45:01 +08:00
    微服务的目的就是降低服务之间的耦合性,从开发的角度讲,一个业务需求只需要调用 C1 和 C2,就不应该调用 A,从而达到和 A 解耦的目的。你这种先拿到 A 再去调用 C1 和 C2 的方案是为了性能而丧失了服务间的解耦,得不偿失。
    qin20
        4
    qin20  
       2021-08-17 11:27:51 +08:00
    @shilianmlxg 前端达成共识很难。。。
    xuanbg
        5
    xuanbg  
       2021-08-17 16:39:05 +08:00
    从来就没有什么依赖其他业务的“组合”接口。“原子”接口要不要依赖其他服务看情况。
    golangLover
        6
    golangLover  
       2021-08-18 19:47:39 +08:00
    @qin20 有具体的例子吗,想学习一下。谢谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2688 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 15:00 · PVG 23:00 · LAX 07:00 · JFK 10:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.