在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