使用Spring+Spring MVC对服务层的设计思考

翻译 2012年03月26日 12:16:48
服务层在客户与系统两方面扮演了重要的角色。
对于客户,它暴露和封装了粗粒度的系统功能(用例)从而简化了使用。所谓粗粒度的方法是指那些高级别的方法,封装了广泛的工作流并避免了客户与系统许多小的交互。服务层是客户与系统交互的唯一途径,由于所有实现用例的POJO交互对于客户是隐蔽的,所以服务层要保持低耦合性。
对于系统,服务层方法代表工作的事务单元。这意味着当调用一个方法时,许多POJO及其交互就会在一个事务下执行。在服务层执行所有的工作使客户和系统的通信降到最少(实际上降到只有一个调用)。在一个事务众多的系统中,保持事务生命跨度最小是很重要的。另外一个好处是把事务移到单独一层易于集中进行事务配置。
在服务层的每个方法都应该是无状态的。就是说,每次调用服务方法都不会再实现服务接口的对象上创建状态。任何一个在服务对象上的方法调用都不应该假设之前的方法调用过它自己。整个方法调用的任何状态都应保持在领域模型中。
通常在MVC应用中,一个单独的服务层对象将处理执行多个并发线程,因而保持无状态是避免一个线程和另外一个线程冲突的唯一办法。这是事实带来了更简单的设计,因为它不需要服务对象缓冲池的要求。这种设计的性能好与实例池,因为它不需要对对象进入或者离开缓冲池进行检查管理。对每个服务对象使用单例同样也使内存使用降到最低。
该层尝试提供所有系统用例的封装。用例通常是一个事务工作单元,所以这两方面存在服务层中是有道理的。它同样使得为所有高层次的系统功能引用一层变得容易。
服务层之后的工作单元为最终用户和客户进入系统创建了一个单一入口点。将众多的客户通信机制放在一个单一的服务接口上现在变得很容易。例如,因为Spring具有远程功能,可以通过SOAP、RMI、HTTP上Java序列化,当然还有标准的XHTML来暴露相同的服务。它通过从传输机制或者用户界面解耦事务工作单元,支持代码复用和及其重要的DRY(不要重复自己)原则。
●举例
刚才提到,服务层给客户提供了一个接口,这种接口有非常粗粒度的方法,通常像代码清单1所以。


public interface AccountManager{
  void activeAccount(String accId);


  void unactiveAccount(String accId);


  Account getAccByUserName(String userName);
}


可以看出为什么这些方法被认为是粗粒度的。对于客户它使用了一个简单的调用完成一个单一的用例。对于细粒度的接口可知,细粒度接口可能需要许多不同的对象使用多次调用来完成一个用例。


public interface FindGraineAccountManager{
  Account findAccountByUsername(String userName);


  void setAccountToActive(Account acc);


  boolean accountAbleToBeActivated(Account acc);


  void sendActivationEmail(Account acc, Mailer mailer);
}


上述例子中,交给了客户过多的责任。方法调用的正确次序如何?如果失败了会发生什么?我们无法保证对每个调用使用的是同一个account实例。这种细粒度接口将使客户过于紧密耦合到用例实现的方式上。
在客户是远程的环境下,粗粒度接口是一种很重要的设计元素。序列化不是一种廉价的操作,因而每次调用服务层至多序列化一次,这一点很重要。即使系统中的客户在同一虚拟机内,要分离系统关注,是解耦及测试更容易进行时,该层扮演着至关重要的角色。


●依赖
服务层依赖于领域模型和持久层上,它结合并协助数据库访问对象非的调用。服务层绝不能依赖试图或者Web层。
值得注意的是,通常该层不必依赖于框架特定的代码或者基础构造代码,如事务管理。Spring框架爱显示引入系统的方面做得很好,这样代码便能保持高解耦性。


●Spring对服务层的支持
Spring框架不提供用于实现服务层业务方面的任何接口或类。不必惊讶,因为服务层是针对具体的应用程序的。
Spring并非定义业务接口而是有助于编程模型。一般来说,Spring框架的ApplicationContext将服务实例注入到Web控制器。当确定需要的时候,Spring会提供一些服务(比如事务管理、性能检测甚至缓冲池)来增强服务层。


●小结
为了系统交互,服务层提供了无状态、粗粒度的接口给客户使用。服务层的每种方法一般代表一个用例,同时也是一个事务工作单元。
使用服务层同样保持了系统和客户的第耦合性。它降低了用户所需的调用数量,使系统使用更方便。在远程环境中,这便大大提高了性能。

spring三层示例controller层,service层示例,dao层示例

Spring框架提倡面向接口编程,所以在写以下类时,最好能先写好接口,让以下的类去实现接口 1.Spring框架中controller层示例 package org.tarena.note...

spring+mybatis通用dao层、service层的一些个人理解与实现

首先声明,本文所述只是鉴于本人在开发一些应用时的心得,仅供参考。 1、现在的绝大多数web应用,通常都以action、service、dao三层去组织代码,这样划分结构很清晰,分工明确 2...

RSA、DES 、AES、MD5加密、解密

加密的Demo,欢迎下载 JAVA端的加密解密,读者可以看我同事的这篇文章:http://www.jianshu.com/p/98569e81cc0b 最近做了一个移动项目,是有服务器和客...

Java后台SSM框架的简单使用

使用步骤: Controller类  ---> Service接口(serviceImpl实现Service接口类)-->DAO接口(DaoImpl实现DAO接口类)-->Mapper接口(通过My...

使用Spring MVC创建REST服务简单例子

  • 2017年05月17日 21:03
  • 6.27MB
  • 下载

使用Spring MVC 搭建Rest服务.doc

  • 2013年10月10日 11:51
  • 125KB
  • 下载

使用Spring MVC 搭建Rest服务

使用Spring MVC 搭建Rest服务 (2011-06-24 21:48:28) 转载▼ 标签: restful spring mvc it 分类:jav...
  • pfyuit
  • pfyuit
  • 2014年04月20日 16:32
  • 967

Spring Mvc那点事---(40)SSM服务框架使用aop进行数据验证

数据验证是每个系统都经常要做的,大多数情况下,我们是直接在方法里面使用if语句判断是否为空,判断是否是数字类型,判断是否满足条件,如果不满足,就返回客户端错误信息,这样的话,就会显得麻烦,可能同样的判...

使用Spring MVC创建REST服务

Spring MVC REST
  • wu_boy
  • wu_boy
  • 2017年05月17日 21:00
  • 187

spring mvc 自定义注解ResponseEncryptBody、RequestDecryptBody统一处理加密、解密数据,供移动端使用的rest服务

spring mvc 自定义注解ResponseEncryptBody、RequestDecryptBody统一处理加密、解密数据,供移动端使用的rest服务 自定义两个注解: /** * 类似...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用Spring+Spring MVC对服务层的设计思考
举报原因:
原因补充:

(最多只允许输入30个字)