我真的需要服务层吗?

我的Web应用程序是使用Spring MVC + Hibernate编写的。

  • 我的模型是“客户”实体POJO。
  • 我有一个DAO对象“CustomerDAO”,它的方法“saveCustomer(c)”包含与Hibernate交互的代码;
  • 然后我创建了一个“ CustomerService with”saveCustomer(c)“方法,只需将客户对象传递给dao进行保存;
  • 最后有“CustomerController”和customer.jsp,他们负责视图层,jsp的表单字段绑定到控制器端的Customer对象。 控制器调用该服务。

我看到很多应用程序遵循这个(最佳)实践,但我想知道为什么我需要一个服务层。

也许它对解耦目的很有用:我可以向控制器展示一个通用的外观并注入服务HibernateDAO,GaeDAO,MyDAO等等……但是我也可以在没有服务的情况下做到这一点:使用接口。

我也考虑过:validation。 我将在服务中进行客户validation,但是……在Spring控制器中进行validation会更加方便。

请帮我理解这个概念:)

不需要服务层。 但它可以帮助你

  • 解耦组件
  • 您可以在服务层中强制执行特定的业务规则,这些规则应该与您的存储库无关
  • 让服务外观一个或多个存储库。 让我们考虑以下示例
class Service { private DatabaseBarRepo barRepo; private DatabaseFooRepo fooRepo; @Transactional public void serviceRoutine() { barRepo.doStuff(); fooRepo.doStuff(); } } 

在这里,我们让两个独立的存储库参与同一个事务。 这是特定于数据库的,尽管这些原则对其他系统也是有效的。

关键是交易行为。 如果您没有服务层,您将在哪里划分交易?

  • 在表示层中:这不是事务划分所属的位置,并且您将无法使用声明式事务划分
  • 在DAO层中:您将无法在单个事务中创建客户及其联系人(例如),因为它将使用两个不同的DAO

此外,您希望UI层尽可能简单,并且在特定组件中隔离业务代码(有时比调用DAO方法要复杂得多)。 这允许

  • 通过模拟服务层来对UI层进行unit testing
  • 通过模拟DAO层来对服务层(业务代码)进行unit testing

现在,您的服务层是微不足道的,因为您的服务是围绕数据库访问的简单包装。 是所有的应用程序? 如果没有,当您开始构建非平凡部分时,您的服务层将会扩展。

您可以通过使BaseService具有所有CRUD操作来保存详细程度,并委托给其中注入的BaseDAO。

除了CRUD之外,几乎所有其他东西都具有业务逻辑和数据库特定操作的独立逻辑。 另一件事 – 通过使用@Transactional注释服务层方法,您可以让事务跨越多个数据库操作

您在服务层还有其他一些事情。 有时它会在将任何操作传递给DAO之前应用业务规则。 有时,一个服务需要与其他服务交互,DAO用于业务规则要求。

告诉我们如何在没有服务器层和界面的情况下做到这一点……高水平的想法,将帮助我告诉你更多。