SSM框架分层及使用接口

一、SSM框架下分层

1. 持久层:Dao层(mapper)

Dao层:Dao层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此

  • Dao层的设计首先是设计Dao的接口;
  • 然后在Spring的配置文件中定义此接口的实现类;
  • 然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰;
  • Dao层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置。
2. 业务层:Service层

Service层:Service层主要负责业务模块的逻辑应用设计

  • 首先设计接口,再设计其实现的类;
  • 接着在Spring的配置文件中配置其实现的关联,这样就可以在应用中调用Service接口来进行业务处理;
  • Service层的业务实现,具体要调用到已定义的Dao层的接口;
  • 封装Service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性,程序显得非常简洁。
3. 表现层:Controller层(Handler层)

Controller层:Controller层负责具体的业务模块流程的控制

  • 在此层里面要调用Service层的接口来控制业务流程;
  • 控制的配置也同样是在Spring的配置文件里面进行,针对具体的业务流程,会有不同的控制器,在具体的设计过程中可以将 流程进行抽象归纳,设计出可以重复利用的子单元流程模块,这样不仅使程序结构变得清晰,也大大减少了代码量。
4. View层

View层 此层与控制层结合比较紧密,需要二者结合起来协同工发

  • View层主要负责前台JSP页面的表示。

二、各层联系

  • Dao层、Service层都可以单独开发,互相的耦合度很低,完全可以独立进行,这样的一种模式在开发大项目的过程中尤其有优势;

  • Service逻辑层设计是建立在Dao层之上的,建立了Dao层后才可以建立Service层,而Service层又是在Controller层之下的,因而Service层应该既要调用Dao层的接口,又要提供接口给Controller层的类来进行调用,它刚好处于一个中间层的位置。每个模型都有一个Service接口,每个接口分别封装各自的业务处理方法;

  • Controller层、View层因为耦合度比较高,因而要结合在一起开发,但是也可以看作一个整体独立于前两个层进行开发。这样,在层与层之前我们只需要知道接口的定义,调用接口即可完成所需要的逻辑单元应用,一切显得非常清晰简单。

转载:SSM框架下各个层的解释说明


三、Dao层和Service层使用接口原因

看了这么多回答,很多回答都扯到了面向对象的解耦云云,说得都很好,然而,都没有从根本上回答题主的问题:为什么一定要用接口?不用接口并不代表就不能解耦,就不是OOP,尤其是在事实上,99.99%的case都是接口与实现类严格的1:1实现的,在这种情况下,接口究竟有什么意义?是JVM的基于接口的动态代理吗?但既然基于cglib的动态继承也同样可以实现AOP,所以技术上的理由同样是不成立的。所以,这个问题真的是一个非常好的问题。

先说一说我的工程实践,首先,在Dao层,我们是只用了一个通用的CommonDao实现,这个好不好,合不合理,可以放在一边,跟这个问题相关的是,我们没有用接口,只有一个CommonDao实现类。我大略扫了一下其他回答,也有很多人提到Dao层可以不用接口。那么,这里的问题是,为什么Dao层可以不用接口?接下来,service层,我们的系统的service分为了两类,一类,是既有接口,也有实现类,一类,是只有实现类,没有接口。看上去有点奇怪哈,首先有接口的那一类,为什么会有接口?因为实实在在的,他们都有多个实现类,这就是其他很多答案提到的解耦,所以,我们的系统是可以在运行期动态的选择service的实现的,这个需求导致了我们必须使用接口来抽象service。然后,是剩下来的那一部份,只有实现类没有接口的service,为什么?为什么我们不为他们定义接口,这究竟是对还是错?

It depends,depends on what?depends on你的团队的技术能力以及你对开发成本以及开发质量的平衡考量。所以,我们的团队,不使用接口直接使用类定义service,是正确的选择,但对你们,却未必正确。那么,判断的标准是什么?我们先来看一下使用接口的情况,使用接口的好处是什么?暂时看不出来有什么特别的好处,坏处呢?坏处就是我们不得不同时维护两份同构的代码,一份接口声明,一份具体实现。看来接口真的没啥意义,那么我们试试不用接口吧,只用类如何?有什么好处吗?好处当然有,不用维护两份同构代码,代码量下降了,也更易于变更。坏处呢?这就是本回答的重点了。

简单的说,就是不可控的类信息暴露控制。说起来有点拗口,可能也看不懂啥意思,我来举一个简单的例子比较容易理解。我不确定我们的系统哪些设计细节是不能公开的,所以,我决定用一个更一般的例子来说明,比如我们打算用AOP来实现service方法级别的缓存,并用annotation来标记需要缓存的方法和并附加详细的缓存控制声明。如果使用接口呢,就很简单了,在接口的方法声明上标记annotation就可以了,如果没有接口呢?显然,我们只能把annotation直接标记到类方法上,没啥区别,是吗?但是,直接在类方法上标记可能会导致一个意外的错误,就是程序员有时会将annotation标记到private方法上去,很多同学这时候应该已经会心一笑了,基于cglib的类继承AOP是不能在private方法上生效的,所以,程序员会自以为已经缓存了一个很重的方法实现,但实际上却完全没有生效。反过来,这样的错误,在基于接口的方式下,是几乎不可能出现的,程序员如果发现需要缓存一个很重的private方法,要么会很省事的把这个方法改为public并追加到接口,或者更有责任心一下考虑一下如果变更设计让整个service的体系结构更加合理。

上面说过的错误,我们实际上是的的确确出现过的,但这个错误,是在我们一开始决定不使用接口的情况下就非常清楚这个风险的,我们在事前经过讨论,认为这个风险是可以接受的,同样在工程实践中,即使真正出现了这样的错误,我们讨论评估之后的结论仍然是,我们可以接受偶尔出现这样的错误,所以我们决定继续这样的设计风格。为什么我们这样顽固?理由有三:1. 我们是小团队,大家的技术水平相对较高且平均,出现这样的错误情况并不多见,从概率上可以接受。2. 同样,因为是小团队,所以虽然没有刻意的做代码review,但是在编码的同时代码的交叉review是相当频繁的,所以,即使出现错误,发现的概率也是很高的。3. 我们不是面向企业的业务系统开发,我们是做公开的service site,是面向互联网的服务,我们的业务逻辑变更非常频繁,所以,没有接口的情况下,我们可以少写代码,也更易于变更,少了一个接口抽象层,代码阅读体验也大大提高,这点让我们觉得更加重要。那么,哪些情况下不适合我们这样的选择呢?答案是大多数情况。。。因为大多数java web开发,要么是面向企业应用的开发,坦率的说,开发人员的技术水平是参差不齐的,要么,是非常大型的开发团队,这两种情况下,意外错误的风险都会被放大,而通过interface来约束并保证不出现意外就显得更加重要了。

转载:Java web中Dao层和Service层都使用接口,是否是为使用接口而使用接口?

  • 4
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值