32

我查看了http://solitarygeek.com/java/developing-a-simple-java-application-with-spring/comment-page-1#comment-1639上的示例

我试图弄清楚为什么在他提供的示例中首先需要服务层。如果你把它拿出来,那么在你的客户中,你可以这样做:

UserDao userDao = new UserDaoImpl();
Iterator users = userDao.getUsers();
while (…) {
…
}

看起来服务层只是 DAO 的一个包装器。有人可以给我一个案例,如果服务层被删除,事情可能会变得一团糟?我只是不明白从服务层开始的意义。

4

3 回答 3

32

让服务层成为 DAO 的包装器是一种常见的反模式。在您给出的示例中,它肯定不是很有用。使用服务层意味着您可以获得以下好处:

  • 您可以清楚地区分最好在控制器中完成的 Web 类型活动和与 Web 无关的通用业务逻辑。您可以将与服务相关的业务逻辑与控制器逻辑分开测试。

  • 您可以指定事务行为,因此如果您调用多个数据访问对象,您可以指定它们发生在同一个事务中。在您的示例中,有一个对 dao 的初始调用,然后是一个循环,它可能包含更多的 dao 调用。将这些调用保留在一个事务中意味着数据库做的工作更少(它不必为每个对 Dao 的调用创建一个新事务),但更重要的是,这意味着检索到的数据将更加一致。

  • 您可以嵌套服务,以便如果一个具有不同的事务行为(需要自己的事务),您可以强制执行。

  • 您可以使用 postCommit 拦截器来执行诸如发送电子邮件之类的通知工作,这样就不会破坏控制器。

通常,我的服务包含单一类型用户的用例,服务上的每个方法都是该用户将执行的单个操作(在单个请求 - 响应周期中完成的工作),并且与您的示例不同的是通常不仅仅是一个简单的数据访问对象调用。

于 2010-09-10T22:18:11.143 回答
21

看看下面的文章:

http://www.martinfowler.com/bliki/AnemicDomainModel.html

这一切都取决于您要将逻辑放在哪里 - 在您的服务或域对象中。

如果您有一个复杂的体系结构并且需要与您的 DAO 和数据不同的接口,则服务层方法是合适的。为客户调用提供粗略的方法也很好——调用多个 DAO 来获取数据。

但是,在大多数情况下,您想要的是一个简单的架构,因此请跳过服务层并查看域模型方法。Eric Evans 的领域驱动设计和这里的 InfoQ 文章对此进行了扩展:

http://www.infoq.com/articles/ddd-in-practice

于 2010-09-10T22:18:22.437 回答
20
于 2010-09-11T05:36:03.260 回答