2015-10-26 28 views
0

在Grails框架中,我看到了命令对象模式,但其用法对我来说不是很清楚。另外Grails文档给出的大多数例子都是关于域类而不是命令对象的(可能简化代码示例)。命令对象只在控制器中,还是可以传递给服务层?

1 - 命令对象是在视图和控制器层之间使用的东西,必须留在那里?

2 - 或者将命令对象传递给服务层是一种很好的做法吗?

为了说明点2:

class MyController { 

    def updateUserPassword (UserPasswordCommand cmd) { 
     ... 
     myService.updatePassword(cmd) 
     ... 
    } 
} 

如果点2是一个不好的做法,那你怎么提交的数据传递给服务层?通过域类? 编辑:似乎确定

[编辑]

如果我使用命令对象,而不是域类在这种情况下该怎么做:

def signup(UserCreateCommand cmd) 
{ 
    if (!cmd.hasErrors()) { 
      def userInstance = userService.signup(cmd) 
     } 
    } 
    if (cmd.hasErrors()) { 
     /* Stay on form in order to display errors */ 
     render(view:"/app/authentication/_signupForm", model:[userCreateCommand: cmd]) 
     return 
    } 
    ... 
} 

什么发生,如果在用户业务办理结束时,有数据库突然出现异常(因为刷新数据不尊重模式约束)?

在我的观点的问题是,有两个疑问:

首先 - 呼叫cmd.hasErrors()时,有一个持续的要求对电子邮件唯一约束例如

其次 - 当服务事务结束时,有一个对数据库的刷新(在我的情况下会导致一个SQL插入),并且可能引发具有唯一约束的列电子邮件上的例外

Test cmd.hasErrors()不会阻止大小写数据库引发违反约束唯一例外,或者我错了?

+2

将命令对象发送到服务是一种非常好的做法。 –

+0

@JoshuaMoore感谢您的建议,我编辑了我的问题,并用命令对象指定了一个特定的案例,您的建议将会很有趣 – Nico

+1

我认为命令对象的目的是做数据绑定并将http请求包装进一个对象而不是隐含的参数。在我看来,服务层不应该知道命令对象,而应该知道业务实体,它们可能是您的域或DTOS,它们被dao层用来实际更新实体。想象一下,服务层被其他客户端暴露并在企业中重用,这些客户端可能不是一个窗体,因此没有可用的Command,但他们可能通过传递User或UserDto来调用该服务。有什么想法吗? – Viriato

回答

2

这是将请求参数传递给服务层的最佳方式。我看到有人通过params服务,这实际上是最糟糕的做法。我们的控制器应该是转储,控制器方法中的最大5-8 LOC是我公司的指导原则。

Command对象给你这么大的权力出像验证,方法等

+0

谢谢Uday,我编辑了我的问题与一个特定的情况下,如果你有一个建议,它将受到欢迎 – Nico

0

约束喜欢独特这就需要从数据库中验证的,不能命令对象上应用的盒子。在这种情况下,您可以使用验证器http://grails.github.io/grails-doc/2.5.1/ref/Constraints/validator.html

您还可以使用importFrom约束将所有约束形成User域到命令对象http://grails.github.io/grails-doc/2.5.1/guide/validation.html

+0

我已经这样做,但如果我验证我的命令对象与cmd.hasErrors()返回true( cmd.email =“[email protected]”),但是当我决定调用userService.saveMyUser(cmd)时,其他用户只在数据库中保存电子邮件[email protected]。当我的事务完成时,对数据库的刷新可能会抛出异常,因为我尝试插入[email protected],但它已经在数据库中。我希望我的例子很清楚。 – Nico

+0

,因为数据库中会有两个查询,第一个用于唯一:真正的电子邮件,第二个用于数据库刷新用户。 – Nico

+0

对不起,我的意思是cmd.hasErrors()返回false,并且userService发现错误 – Nico

相关问题