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

Service 调用 Service 为什么有人不推荐

  •  
  •   vanishxiaoma · 2019-10-23 17:45:54 +08:00 · 7993 次点击
    这是一个创建于 1618 天前的主题,其中的信息可能已经有所发展或是发生改变。
    10 条回复    2019-10-24 10:04:08 +08:00
    lihongjie0209
        1
    lihongjie0209  
       2019-10-23 17:48:33 +08:00
    或许他们的高层 service 不叫 service, 叫其他的。

    简单一点的 controller > service -> dao
    复杂一点的 controller > service -> 叫什么都可以(low level service) > dao
    nekolr
        2
    nekolr  
       2019-10-23 17:52:52 +08:00
    猜想:service 一般会包含事务的吧,service 调用 service 是不是需要考虑事务的传播
    passerbytiny
        3
    passerbytiny  
       2019-10-23 18:12:36 +08:00
    一旦你放飞了,用不了多久就会碰上鸡和蛋的问题——A → B & B→ C &C→ A,调用链过长导致职责不明确的问题,以及任何面向函数编程回遇到的问题。

    Service 是一个高内聚的独立单元。假如 A 调用了 B,那么:A 强依赖于 B,从而铁定是高耦合的; B 也可能要考虑到向其它 Service 返回数据(原本它只需要考虑向上层返回数据)从而降低了内聚程度。
    uyhyygyug1234
        4
    uyhyygyug1234  
       2019-10-23 18:14:12 +08:00
    dimond

    你搞些微服务互相调,也可以。公司之间还互相依赖呢。不要死循环了就行
    Aresxue
        5
    Aresxue  
       2019-10-23 18:31:58 +08:00
    各有优劣,不做平级调用的好处是粒度更细,代码依赖更少,做优化的时候也更方便些,更符合单一职责原则。缺点就是开发代码量多,而且很可能会有冗余
    vanishxiaoma
        6
    vanishxiaoma  
    OP
       2019-10-23 18:33:34 +08:00
    @passerbytiny ServiceB 中的一个方法在别的 Service 中都会用到 , 为了解耦 需要在每个用到的 Service 中都写一边吗?如果这样是不是违背了 代码复用的原则
    mmdsun
        7
    mmdsun  
       2019-10-23 18:46:55 +08:00 via Android
    如果两个模块( service )之间没有直接关系,它们之间的联系完全是通过主模块( controller )的控制和调用来实现的,这就是非直接耦合。这种耦合的模块独立性最强。


    如果一个 service 访问另一个 service 时,彼此之间是通过数据参数(不是控制参数、公共数据结构或外部变量)来交换输入、输出信息的,则称这种耦合为数据耦合,这种也是可以接受的,但是独立性没有第一种好。

    (这种类比简单粗暴了。
    taogen
        8
    taogen  
       2019-10-23 20:04:09 +08:00 via iPhone
    复用的代码作为公共父类
    passerbytiny
        9
    passerbytiny  
       2019-10-24 09:14:47 +08:00
    @vanishxiaoma #6 如果 Service 层是独立设计的(至少可以利用 Mock 脱离上下层进行自主单元测试),那么这些共用的代码,可以抽取成 Service 层内部的独立类——这些类只能被常规 Service 调用。(实际上,Controller/Action、Dao 层受限于框架只能是固定的单类模式,但从来没有人说过 Service 层也必须是单类模式。)

    另外一种方式是在 Service 层和 Dao 层之间插入一层可选的 LowerService 层。

    以上两种方式,都很容易步入另一个坑——CommonService Hell。

    Controller/Action—Service—Dao,这是对应贫血领域模型的典型架构,它当初因为降低了 Java 的门槛而发扬光大,它之后因为暴漏的各种 Hell 以及面向过程编程的嫌疑而被多个(国外的)大佬批成了 SHI。现在研究它没啥意义,小项目建议 Controller/Action+SQL 模板(例如 Spring-Data-Jdbc ),大项目直接上领域模型设计。
    inwar
        10
    inwar  
       2019-10-24 10:04:08 +08:00 via Android
    循环依赖要处理,模块过度耦合,调用链混乱。不如再加曾 manager
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5408 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 08:38 · PVG 16:38 · LAX 01:38 · JFK 04:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.