mvc模式中如何减少service之间的耦合?关联查询归属于哪个model?

我们项目用的是传统的mvc框架(CI框架),为了更好的复用业务逻辑,我们新增了services逻辑层,在开发过程中代码复用性确实好了很多,但也遇到了问题:

  1. 最明显的就是service之间的互相调用,我感觉这增加了service之间的耦合性。本来最开始想按照业务逻辑分模块划分不同的service,每个service只提供自己业务相关的方法,由controller层分别去调用不同的service层方法得到数据,然后组装成最终想要的数据输送给view层。但是遇到个这个问题,我需要提供一个方法给同事调用,这个方法要求会做很多业务逻辑处理,这会涉及到多个service,这个方法如果写在controller层,同事就无法在它的controller中使用,写在controller的父类中感觉这个方法仅仅是他的控制器能用到,于是最终我写在了一个service中,这个方法会分别去调用不同的service,然后组装并输出数据,这样就产生了耦合。。不知道有没有更好的解决方案,特别是在实际的开发过程中?
  2. 然后就是model层的一些问题:我们原则上是一个数据表对应一个model,每个model只负责对应数据表的增删改查,由service层按照业务逻辑去调用不同的model获得数据,我们项目中很少有关联查询,这既有好处,也有坏处。有时关联查询更方便,但是这个查询方法写在哪个model里呢?放在哪个model的原则又是什么呢?
  3. 最后,跨层调用不知道是否合理,有时controller层会直接调用model层。

我的service层存在耦合不知道是不是和设计不当有关。打个比方:学生在线做试卷,做一道选择题,就计算“选择题题型”的完成进度,然后再计算整张试卷的完成进度(根据不同题型和各自完成量按照一定规则计算得出);我把“选择题题型”相关操作做成一个service,它负责提供选择题列表、计算选择题完成进度、计算选择题得分情况等等方法,把整张试卷相关操作做成另一个service,它负责计算整个试卷的完成进度等等其它的方法。于是在学生完成一道选择题时,我需要在controller中分别调用两个service完成本题型和试卷的完成进度。不知道这样做是否合理?当我给同事提供完整的进度更新方法供他在controller中调用时,我不能把我自己写的controller方法给他,因为controller不能直接调用controller,互相调用也不合理。怎么办呢?谢谢。

十分感谢。

阅读 542
评论 更新于 2019-07-11
    3 个回答

    mvc里面的model是指提交给jsp或者其他模板引擎,用于渲染的数据,是加工过的方便界面显示的数据,而数据库表的数据是原始的数据。所以model应该不直接对应数据库表。

    一般来说不需要model层,model只是存放数据的对象,一般是ORM里面的bean,增删查改的逻辑由service层调用ORM实现。关联查选也由service层调用ORM实现。model只是一些实体类,pojo对象,不是一个包含业务逻辑代码的层。

    service层可以互相调用,但双向调用很不好,改造为单向调用比如serviceA调用serviceB,那么serviceB就不要调用serviceA。controller层的职责就是组合service层的功能,由controller来调用service组装是最好的。

    评论 赞赏 2019-07-09

      我做PHP的时候也遇到过这个问题。后面看了下java的分层之后好了很多。

      业务上其实是很少存在直接耦合的,有时候耦合仅仅是判断状态或者查询数据。

      可以参考以下分层

      • controller 控制器(验证提交的数据,格式化service返回的数据)
      • service (业务层,不直接操作数据库,只写业务代码)
      • repository (数据库操作层,接收model,将其写入数据库,不写业务)
      • model (提供ORM)

      如果service需要操作多个数据表的时候,注入多个repository操作数据库即可。这样可以很清晰的处理业务和数据库之间的关系

      评论 赞赏 2019-07-10

        service 调用其他 service,可以在 service 的构造函数里,传入其他 service,反正用依赖注入,不就解决耦合了吗,,

        评论 赞赏 2019-07-17
          撰写回答

          登录后参与交流、获取后续更新提醒