mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面。

mvc模式是web开发中的基础模式,采用的是分层设计,各层之间职责分明。然而事与愿违,当我们日积月累的基于mvc模式开发之后,会逐渐的感受到层与层之间存在粘连和职责模棱两可的地方,这就是service层出现的重要原因。

问题是什么

要提出解决方案,重要的是发现问题的本质。mvc模式在实践过程中,主要面临下面几个难受的问题:

  • 在C层直接实现业务逻辑,这将导致:

    • 不同的controller之间,无法共享通用的业务逻辑,比如:折扣计算,反作弊判定,这必然是不合理的。
    • 业务逻辑升级,需直接在原代码上做修改兼容,导致controller代码不断膨胀复杂。
    • 远程服务协议或者调用方式升级,需要找到所有controller里的调用点,逐一修改。
    • DAO发生替换(比如从oracle迁移mysql),需要找到所有controller里的调用点,逐一修改。
  • 在M层(DAO+model或者ActiveRecord,下面以model泛指)里实现业务逻辑,这将导致:
    • model承担了过多的业务逻辑,导致业务逻辑升级需要修改model,然而model的职责并不是业务,这是很矛盾的。
    • 调用1个model中的业务代码没有问题,但是遇到跨表事务又该由哪个model管理呢?
    • 业务逻辑实现在model中,如果model发生变更,那么里面写的业务逻辑也得粘贴复制到新的model中,这就是耦合的代价。

我仔细的回想了一下之前的MVC开发模式,上面的问题我几乎都遇到过并且试图解决过,比如:

  • 为了提升代码复用,我会把一些通用的功能实现为单独的工具类(校验登录),并在controller中提供调用。
  • 为了给controller提供业务相关的数据,我在ActiveRecord里实现了业务相关的增删改查方法供controller调用,更有意思的是:每次表变更字段,我通过工具gii重新生成ActiveRecord都会把我实现的方法覆盖,这就是耦合的代价。

问题的本质是:业务逻辑粘连了C层和M层,应该从C层&M层解耦出来,成为独立的Service层。由此,在C层可以灵活的替换Service保持高度的简洁,而M层保持职责单一仅仅为Service提供数据,Service层则实现所有复杂的业务逻辑与通用的业务逻辑。

Service层的职责

根据上面的分析,Service夹在C层和M层中间,从逻辑上大致划分为3大类:

  1. model侧的Service:也就是封装每个model与业务相关的通用数据接口,比如:查询订单。(我认为:访问远程服务获取数据也应该归属于这一类Service)
  2. 中间的Service:封装通用的业务逻辑,比如:计算订单折扣(会用到1中的Service)。
  3. controller侧的Service:基于1、2中的Service进一步封装对外接口的用户业务逻辑,当然也不排斥直接访问DAO而不使用上述2个Service(不建议)。

在实践中,应该会很自然的用到这三类Service,在了解了这些概念之后再进行代码设计,就不会对Service的职责产生困惑了,自然也对MVC有了新的认识。

关于抽象

Controller里调用"controller侧的Service"直接完成业务处理,意味着Controller依赖了具体是哪个Service类。

Service里调用"DAO/AR"实现数据库的访问,意味着Service依赖了具体是拿个"DAO/AR"类。

Service里调用Service,意味着Service依赖了具体是拿个Service类。

为了解除这种耦合,在Web领域一般采用的都是IOC依赖注入来实现"依赖反转",JAVA和PHP都可以基于反射实现这个能力,各个mvc框架都有相似的实现。

Service层是否必要呢?

见仁见智,我认为长时间维护的大型项目通过更精细的分层,更加有利于功能的迭代升级。

而对于中小项目,多一层就意味着更多的代码,而且在设计时还要考虑通用性以及通用性的粒度问题,还不如少动点脑子多写点冗余代码了。

Java Web学习总结(30)——Service层在MVC框架中的意义和职责的更多相关文章

  1. 谈谈service层在mvc框架中的意义和职责

    mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面. mvc模式是web开发中的基础模式,采用的是分层设计, ...

  2. Service层在MVC框架中的意义和职责

    https://blog.csdn.net/u012562943/article/details/53462157 mvc框架由model,view,controller组成,执行流程一般是:在con ...

  3. [原创]java WEB学习笔记30:Cookie Demo 之显示最近浏览的记录

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  4. Java Web 学习路线

    实际上,如果时间安排合理的话,大概需要六个月左右,有些基础好,自学能力强的朋友,甚至在四个月左右就开始找工作了.大三的时候,我萌生了放弃本专业的念头,断断续续学 Java Web 累计一年半左右,总算 ...

  5. Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

    本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...

  6. Java Web学习系列——Maven Web项目中集成使用Spring

    参考Java Web学习系列——创建基于Maven的Web项目一文,创建一个名为LockMIS的Maven Web项目. 添加依赖Jar包 推荐在http://mvnrepository.com/.h ...

  7. [原创]java WEB学习笔记11:HttpServlet(HttpServletRequest HttpServletRsponse) 以及关于 Servlet 小结

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. [原创]java WEB学习笔记95:Hibernate 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. Java web 学习之旅

    java web学习之旅 来公司十天了,感觉已经慢慢地融入了这个环境中,几个学长人都很好,都是在他们帮助下,我才能比较顺利的开始了学习java web的旅途. 来这里学习的第一个阶段是做一个简单的用户 ...

随机推荐

  1. Shell脚本下条件测试(eq.ne.....)(转载)

    转载:http://cxj632840815.blog.51cto.com/3511863/1168709 Shell编程中的条件测试 在Linux编程中经常会用到判断数值的大小,字符串是否为空这样或 ...

  2. Django day 33 vue中使用element-ui的使用,课程的相关介绍,vue绑定图片,课程列表接口,课程详情页面

    一:vue中使用element-ui的使用, 二:课程的相关介绍, 三:vue绑定图片, 四:课程列表接口, 五:课程详情页面

  3. vim 跳行查看日志

    VIM 跳跃行号 一.显示行号 在命令模式下输入 :set nu   或者   :set number 即可显示行号 二.跳跃行号 在编辑模式下输入 ngg 或者 nG [n为指定的行数(如25)] ...

  4. Java多线程(九) synchronized 锁对象的改变

    public class MyService { private String lock = "123"; public void testMethod() { synchroni ...

  5. linux学习之路1 Linux系统安装

    VMware workstation虚拟器 网上下载VMware workstation,然后安装任一系统的linux系统,不过选的系统一定要跟你下载好的linux镜像保持一致,博主装的是Red Ha ...

  6. ACM_求补集的交集

    求补集的交集 Time Limit: 2000/1000ms (Java/Others) Problem Description: 给定一个集合,然后再给出两个该集合的子集,求他们对应补集的交集. I ...

  7. Node“getTextContent() is undefined for the type Node”处理办法

    最近一个项目在MyEclipse导入后总是报getTextContent() is undefined for the type Node错误. 经过查找原来是因为Node类为JDK中自带的(org. ...

  8. 406 Queue Reconstruction by Height 根据身高重建队列

    假设有打乱顺序的一群人站成一个队列. 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数. 编写一个算法来重建这个队列.注意:总人数少于1100人.示 ...

  9. 全面学习ORACLE Scheduler特性(6)设置Repeat Interval参数

    3.3 设置Repeat Interval Job 和Schedule中REPEAT_INTERVAL参数都是用来控制执行的频率或周期,虽然说周期是一个时间性概念,不过REPEAT_INTERVAL指 ...

  10. jQuery学习笔记(2)-选择器的使用

    一.选择器是什么 有了jQuery的选择器,我们几乎可以获取页面上任意一个或一组对象 二.Dom对象和jQuery包装集 1.Dom对象 JavaScript中获取Dom对象的方式 <div i ...