在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()不会阻止大小写数据库引发违反约束唯一例外,或者我错了?
将命令对象发送到服务是一种非常好的做法。 –
@JoshuaMoore感谢您的建议,我编辑了我的问题,并用命令对象指定了一个特定的案例,您的建议将会很有趣 – Nico
我认为命令对象的目的是做数据绑定并将http请求包装进一个对象而不是隐含的参数。在我看来,服务层不应该知道命令对象,而应该知道业务实体,它们可能是您的域或DTOS,它们被dao层用来实际更新实体。想象一下,服务层被其他客户端暴露并在企业中重用,这些客户端可能不是一个窗体,因此没有可用的Command,但他们可能通过传递User或UserDto来调用该服务。有什么想法吗? – Viriato