V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
yeqiu
V2EX  ›  问与答

一个 业务逻辑代码 的设计的问题

  •  
  •   yeqiu · 2021-08-24 14:56:14 +08:00 · 1116 次点击
    这是一个创建于 1182 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在的项目有一个业务逻辑层,层中的每一个类( business )都针对一个业务模型( model )。

    我现在有两个 business,dockBusiness (针对的 model 是 dock )和 serviceBusiness (针对的 model 是 service )。

    现在有一段逻辑是这样的:

    1. 通过 dock_id 获取 dock
    2. 然后使用 dock 创建一个 service
    3. 然后再根据 dock 的内容,修改 service 的某些字段。

    这种情况下应该把这段代码放到哪里?感觉放在 dockBusiness 和 serviceBusiness 都不合适。

    我有一个想法是创建一个新的 business (例如 dock_serviceBusiness ),但项目中这种情况很多,岂不是要创建很多这样的 business 么,这样很不优雅。

    小伙伴,你们是怎么做的?

    11 条回复    2021-08-25 09:13:34 +08:00
    micean
        1
    micean  
       2021-08-24 15:03:06 +08:00
    别纠结这种问题,凭直觉~
    kkkkkrua
        2
    kkkkkrua  
       2021-08-24 15:06:35 +08:00
    dockBusiness 调用 serviceBusiness 不可以吗
    //dockBusiness
    1.getdock
    2.serviceBusiness.create();
    3.serviceBusiness.update();
    yeqiu
        3
    yeqiu  
    OP
       2021-08-24 15:10:21 +08:00
    @kkkkkrua #2

    考虑到 business 的原子性,所以设定了 business 之间不能互相调用的规则。

    只有上层(表现层,api 等)才可以调用 business 层。
    kkkkkrua
        4
    kkkkkrua  
       2021-08-24 15:14:45 +08:00
    @yeqiu #3 那调用下层的呢?
    //dockBusiness
    1.getdock
    2.servicemapper.create();
    3.servicemapper.update();
    yeqiu
        5
    yeqiu  
    OP
       2021-08-24 15:22:03 +08:00
    @kkkkkrua #4

    那就违背了 业务逻辑集中 这一个出发点,变成一个 business 对应两个 model 了

    servicebusiness 就是为了把跟 service 相关的业务逻辑集中在一起的,例如创建 service 时的价格、日志、产品等逻辑
    timethinker
        6
    timethinker  
       2021-08-24 15:57:48 +08:00
    感觉你的 business 上面应该还有一个应用层吧,针对具体的用例封装这些逻辑,每一个方法都是一个独立事务,没必要复用应用层了,相反 business 可以被复用。如果是我的话直接一个 service 可能就结束了,没必要搞复杂,顺手就行了,效率才是最重要的。
    yeqiu
        7
    yeqiu  
    OP
       2021-08-24 16:12:02 +08:00
    @qwe520liao #6

    对,目前的做法确实是在应用层调用了 busines 。
    主要是 dockBusiness.getdock,serviceBusiness.create,serviceBusiness.edit 这三个方法。
    这种情况下存在的问题是。
    1. 进行了多次数据库操作,create 和 edit 中至少两次保存了数据,为了保证一致性,需要增加额外的事务相关的代码。
    2. “然后再根据 dock 的内容,修改 service 的某些字段”这其中的逻辑也是复用的,需要封装到 business 中。

    所以感觉目前的方法并不好,想看看小伙伴们都怎么处理。
    kkkkkrua
        8
    kkkkkrua  
       2021-08-24 16:31:23 +08:00
    @yeqiu #5 不管什么情况,总有都要同时调用多个 business 的,那你这个调用点在哪就写哪
    timethinker
        9
    timethinker  
       2021-08-24 16:50:00 +08:00
    那我建议你最好不要把事务放到 business 上面,粒度小会影响性能,如果不考虑用例你将无法预料会被怎样调用,事务边界应该是按照某一个用例来的,而不是按照增删改查这种没有什么语义的偏技术功能性的方法。在我看来 edit 这种就是没有什么业务语义的方法(类似 update ),把它当作了偏底层的 DAO/MAPPER 来用了。
    ccde8259
        10
    ccde8259  
       2021-08-25 08:29:50 +08:00 via iPhone   ❤️ 1
    这种流程的相互支配性明显是 dock 盖过了 service 。因此设计上完全可以调转方向,依靠 dock 向 service 单向发射指令的方式实现。
    具体实现可以是 dockBusiness 里面执行第二步的时候调用 fireServiceCreated(dock)。由 serviceBusiness 实现 onServiceCreate(Dock dock)方法。在第三步调用 fireServiceUpdate(dock),由 serviceBusiness 实现 onServiceUpdate(Dock dock)方法。
    中间的消息流转机制可以简单的用同步实现,也可以采用异步消息队列实现。serviceBusiness 需要对上面调用考虑是否需要补偿机制。
    yeqiu
        11
    yeqiu  
    OP
       2021-08-25 09:13:34 +08:00
    @ccde8259 #10

    懂了,好办法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3689 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 04:25 · PVG 12:25 · LAX 20:25 · JFK 23:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.