将数据传递到服务层的最佳实践

时间:2013-02-07 10:46:20

标签: spring design-patterns spring-mvc

我正在按照MVC模式在春季开发一个Web应用程序,并且想知道什么被认为是制作可靠服务层的“最佳实践”。这个问题的原因如下:

加载了用于编辑用户信息的页面。提交此表单后,我将我的控制器方法中的所有数据收集到一个特定的Command类中,该类仅包含后续操作所需的数据(更新用户)。

我现在可以想到几种情况将这些信息传递给我的服务层:

  • 传递命令本身:userService.save(command);
  • 传递在控制器中获取的模型类:userService.save(user);
  • 传递模型类和命令:userService.save(user,command);
  • 单独传递所有参数:userService.save(command.getName(),...)

在我看来,传递命令类本身看起来是最优雅的解决方案,因为我可以首先使用框架自动验证所有值,然后将它们传递给我的服务。我担心的是,当我从另一个类(而不是通过我的表单/控制器)调用该方法时,我可以使用无效数据填充此命令对象,从而导致服务层中可能出现错误。

你会推荐什么?为什么?

4 个答案:

答案 0 :(得分:1)

看到你之后我有以下想法 传递命令本身:userService.save(command);

  

这可能不是一个好主意,因为您的服务层是不必要的   依赖于Command对象

Passing a model class, fetched in the controller: userService.save(user);
  

我会为此投票。服务层只是它真正应该的   知道

Passing both a model class and the command: userService.save(user, command);
  

没有。与第一个选项

相同
Passing all of the parameters individually: userService.save(command.getName(), ...)
  嗯......不确定......未来可能会成为维护费用。

I think if you want to do the validation, Use validation util classes to do the validation 
    which can be used for both Service and UI layer. Here a lot validation can be centralized.

答案 1 :(得分:0)

在他的MVC书中,Dino Esposito建议创建一个“worker”类,它接受并返回一个视图模型。控制器使用viewmodel调用worker,然后根据需要委托worker。我没有在实践中使用它,但理论上它似乎是一个很好的解决方案。

答案 2 :(得分:0)

使用Command对象的任何选项都会造成麻烦。它打破了松耦合。现在,您的服务层与服务层紧密耦合。请不要这样做。

(编辑:在下面我的回答中,当我说模型用于表示层时,我说的是视图模型,而对于服务层,它是域模型) 发送Model对象看起来是个不错的选择。但是,这取决于模型的创建方式。有时,表示层需要不同的模型结构,服务层需要一个moderatley /完全不同的结构。

如果两个图层都有不同的需求,那么您需要创建2个模型结构。这样,当表示层更改时,服务层的模型结构不必更改。这很重要,因为服务可能有多个消费者,并且在表示层更改时可能无法更改。

如果它们没有不同的结构,我仍然会从服务层的角度创建它们,因为服务是这里真正的可重用组件。

答案 3 :(得分:0)

在多层系统中处理命令时要遵循的一个好方法是使用CommandBus服务将命令路由到特定的处理程序。这样,您可以将控制器与服务分离(同时将其与通用路由系统耦合)。

commandBus.handle(command);

您必须在配置命令总线处理程序方面做更多的工作,但是当您能够重用该路由信息时,它将长期付款:

commandBus.register(commandType, handlerService);

然后您可以移动commandBus服务中的命令验证(即使这意味着对commandBus的一些关注点混合)

commandBus.registerValidator(commandType, validatorsCollection);