2013-02-25 64 views
5

我正在看樣品寵物診所grails應用程序github良好的可維護的方式添加一個保存方法grails服務

它具有用於創建寵物稱爲PetclinicService具有用於添加寵物的方法的服務:

Pet createPet(String name, Date birthDate, long petTypeId, long ownerId) { 
    def pet = new Pet(name: name, birthDate: birthDate, type: PetType.load(petTypeId), owner: Owner.load(ownerId)) 
    pet.save() 
    pet 
} 

正被從控制器使用像這樣:

def pet = petclinicService.createPet(params.pet?.name, params.pet?.birthDate, 
    (params.pet?.type?.id ?: 0) as Long, (params.pet?.owner?.id ?: 0) as Long) 

我很想知道這是否是在Grails中保存某些東西的最佳方式?通過這種方法,如果我在Pet域中添加了另一個字段,例如String color,那麼我需要觸摸三個類(Pet, PetController, and PetclinicService)才能使更改完成。

有沒有一種方法可以將整個params對象發送到服務中並讓它自動映射到域?

回答

7

我做了改變,因爲標準是在params地圖通過,但是這是不好的幾個原因。一個是它將服務層耦合到Web層。這不是一個嚴格的耦合,因爲它只是一個Map,但是服務應該是可重用和獨立的。另一個是地圖是一個「魔術」地圖,你需要知道密鑰才能使用它。通過使用命名和類型的方法參數,代碼更具可讀性和可理解性。

這會增加維護負擔,因爲您指出添加新字段需要更改簽名,但理想情況下,此方法將成爲完成此項工作的一個位置,因此您只需在一個位置進行更改即可。

隨意在您自己的代碼中使用params,但由於此項目是我們的演示項目之一,我希望它儘可能使用最佳實踐。

+0

因此,在服務中使用'params'映射壞了實踐? 與控制器中的「params」一起工作會讓人感覺不舒服嗎? – havenchyk 2014-04-30 09:35:28

1

您可以將整個params發送到服務,只是聲明爲Map

Class PetclinicService { 
    Pet createPet(Map params) { 
    def pet = new Pet(params) 
    pet.save() 
    pet 
    } 
} 
+2

當你像這樣綁定你的數據時,請記住'params'來自用戶輸入並可能包含你不期望的屬性。請參閱http://blog.springsource.org/2012/03/28/secure-data-binding-with-grails/ – ataylor 2013-02-25 19:10:05

+0

對,鏈接爲+1 :) – 2013-02-25 19:21:37

2

寵物診所應用程序使用的模式是一個不錯的最佳實踐。

泄漏params到服務層將使您的服務更緊密地耦合到控制器層。例如,重用API中的服務會更困難。此外,如果您的服務方法具有方法參數形式的顯式接口,則測試會被簡化。

相關問題