2013-02-25 6 views
5

Stavo guardando l'app campione di grails clinica per animali domestici su github.Buono Modo manutenibile per aggiungere un metodo di salvataggio al servizio Grails

Ha un servizio per la creazione di animali chiamati PetclinicService che ha un metodo per gli animali domestici, aggiungendo:

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 
} 

che viene utilizzato dal controller in questo modo:

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

Sono curioso di sapere se questo è il modo migliore per salvare qualcosa nei graal? Con questo approccio se aggiungo un altro campo al dominio Pet, ad esempio String color, quindi dovrò toccare tre classi (Pet, PetController, and PetclinicService) affinché la modifica sia completa.

C'è un modo per inviare l'intero oggetto params al servizio e farlo associare automaticamente al dominio?

risposta

7

ho fatto che il cambiamento perché lo standard è quello di passare nella mappa params, ma questo è un male per un paio di motivi. Uno è che collega il livello di servizio al livello web. Questo non è un accoppiamento rigoroso poiché è solo una mappa, ma i servizi dovrebbero essere riutilizzabili e indipendenti. L'altro è che la mappa è una mappa "magica" in cui è necessario conoscere i tasti per utilizzarla. Utilizzando gli argomenti del metodo named e typed, il codice è più leggibile e comprensibile.

Questo aggiunge un onere di manutenzione poiché, come si fa notare, aggiungere un nuovo campo richiede la modifica della firma, ma idealmente questo metodo sarà l'unico punto in cui viene eseguito questo lavoro, quindi è sufficiente modificarlo in un unico punto.

Sentitevi liberi di usare params nel vostro codice, ma poiché questo progetto è uno dei nostri progetti dimostrativi, volevo che usasse le migliori pratiche ove possibile.

+0

Quindi, sta usando la mappa 'params' all'interno di un servizio cattivo pratica? È possibile lavorare con 'params' nel controller? – havenchyk

1

è possibile inviare l'intero params al servizio, basta dichiarare come Map:

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

Quando si legano i dati in questo modo, ricorda che 'params' proviene da input dell'utente e potrebbe includere proprietà che non ti aspetti. Vedi http://blog.springsource.org/2012/03/28/secure-data-binding-with-grails/ – ataylor

+0

Destra, +1 per il collegamento :) –

2

Il modello utilizzato dall'applicazione clinica per animali domestici è una buona pratica migliore.

La perdita del livello di servizio params renderà i servizi molto più strettamente collegati al livello controller. Riutilizzare il servizio, ad esempio, in un'API sarebbe più difficile. Inoltre, il test è semplificato se i metodi di servizio hanno un'interfaccia esplicita sotto forma di parametri del metodo.