Service层在MVC框架中的意义和职责
https://blog.csdn.net/u012562943/article/details/53462157
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大类:
model侧的Service:也就是封装每个model与业务相关的通用数据接口,比如:查询订单。(我认为:访问远程服务获取数据也应该归属于这一类Service)
中间的Service:封装通用的业务逻辑,比如:计算订单折扣(会用到1中的Service)。
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层是否必要呢?
见仁见智,我认为长时间维护的大型项目通过更精细的分层,更加有利于功能的迭代升级。
而对于中小项目,多一层就意味着更多的代码,而且在设计时还要考虑通用性以及通用性的粒度问题,还不如少动点脑子多写点冗余代码了。
Service层在MVC框架中的意义和职责的更多相关文章
- 谈谈service层在mvc框架中的意义和职责
mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面. mvc模式是web开发中的基础模式,采用的是分层设计, ...
- Java Web学习总结(30)——Service层在MVC框架中的意义和职责
mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面. mvc模式是web开发中的基础模式,采用的是分层设计, ...
- [原]命令模式在MVC框架中的应用
其实在项目开发中,我们使用了大量的设计模式,只是这些设计模式都封装在框架中了,如果你想要不仅仅局限于简单的使用,就应该深入了解框架的设计思路. 在MVC框架中,模式之一就是命令模式,先来看看模式是如何 ...
- 命令模式在MVC框架中的应用
事实上在项目开发中,我们使用了大量的设计模式,不过这些设计模式都封装在框架中了,假设你想要不只局限于简单的使用,就应该深入了解框架的设计思路. 在MVC框架中,模式之中的一个就是命令模式,先来看看模式 ...
- 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成相应的响应发送到客户端。前端控制器既可以使用Filter实现(Struts2采用这种方式),也可以使用Servlet来实现(spring MVC框架)。
本文转自http://www.cnblogs.com/davidwang456/p/4090058.html 感谢作者 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并 ...
- 找到MVC框架中前端URL与后端同步的解决方案
基本思路: 先用URL标签生成完整的URL字符,前端动态参数的部分以适配符先填充,最后动态参数利用正则匹配进行替换. 这种方式,可以在各种MVC框架中适用,妙. 不废话,上码. var url = & ...
- asp.net MVC 框架中控制器里使用Newtonsoft.Json对前端传过来的字符串进行解析
下面我用一个实例来和大家分享一下我的经验,asp.net MVC 框架中控制器里使用Newtonsoft.Json对前端传过来的字符串进行解析. using Newtonsoft.Json; usin ...
- 在ASP.NET MVC 框架中调用 html文件及解析get请求中的参数值
在ASP.NET MVC 框架中调用 html文件: public ActionResult Index() { using (StreamReader sr = new StreamReader(P ...
- MVC框架中的值提供机制(三)
在MVC框架中NameValueCollectionValueProvider采用一个NameValueCollection作为数据源,DictionnaryValueProvider的数据源类型自然 ...
随机推荐
- [Algo] 646. Store Number Of Nodes In Left Subtree
Given a binary tree, count the number of nodes in each node’s left subtree, and store it in the numN ...
- MyBatis从入门到精通(第6章):6.3 使用枚举或其他对象
6.3 使用枚举或其他对象 在 sys_role 表中存在一个字段 enabled,这个字段只有两个可选值,0 为禁用,1 为启用.但是在 SysRole 类中,我们使用的是 Integer enab ...
- 支付宝H5支付demo
支付宝H5支付 首先我们必须注册一个支付宝应用(本案例就直接用支付宝的沙箱环境,这个沙箱也就是支付宝提供给开发者的一个测试环境) 登录地址:https://open.alipay.com/platfo ...
- codeforce 1189C Candies! ----前缀和
题目大意:给你一个数组每个数不大于9,然后给你m个区间,每个区间的长度都是2的k次方(k=0 1 2.....) 有一种操作是把奇数位和偶数位相加 用和来代替之前的两个数,如果和大于等于10就要膜 ...
- mysql之DTS的那些事
最近才考虑数据库迁移,想起了之前做DTS踩过的那些坑. 基于数据库迁移,比如从源A库迁移到源B库,包括但不限于数据库上云. 数据库迁移方案有两种场景: (1).停机迁移方案 这种方案是允许停服的场景, ...
- Linux服务器性能查看命令
一.uptime命令 [root@#test~]# uptime15:26:42 up 101 days, 18:44, 3 users, load average: 0.18, 0.22, 0. ...
- [USACO09DEC]牛收费路径Cow Toll Paths(floyd、加路径上最大点权值的最短路径)
https://www.luogu.org/problem/P2966 题目描述 Like everyone else, FJ is always thinking up ways to increa ...
- i春秋web作业2.24
Web安全工程师(入门班) [全国线上入门班53期]课后作业 2020-2-24 DorinXL 分别尝试安装一个Windows和Linux操作系统 想要在虚拟机上装系统,首先需要下载对应的镜 ...
- 一个http的Post请求问题,unable to resolve host <我的域名>:no address associated with hostnam
原因:你应用中写入的测试服务器地址baseURL解析不了,服务器端设置的原因: 解决:找服务端修改设置,或者Android应用中把测试地址改为上线服务器地址.
- 系统学习Javaweb10----BootStrap2
学习内容: 1.BootStrap-轮播图 2.BootStrap-排版对齐方式 3.BootStrap-表单元素 4.BootStrap-分页条