2013-02-25 6 views
5

Ich schaute auf die Probe Haustier Klinik Grails App auf github.Gut Wartbare Möglichkeit, eine save-Methode zu Grails Service hinzufügen

Es hat einen Service Haustiere für die Erstellung von PetclinicService genannt, das ein Verfahren für das Hinzufügen von Haustieren hat:

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 
} 

, die wie so von der Steuerung verwendet wird:

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

Ich bin gespannt, Wissen Sie, ob dies der beste Weg ist, etwas in Grails zu retten? Bei diesem Ansatz, wenn ich ein weiteres Feld zur Pet Domäne hinzufüge, sagen wir String color, dann muss ich drei Klassen (Pet, PetController, and PetclinicService) berühren, damit die Änderung abgeschlossen ist.

Gibt es eine Möglichkeit, ich kann das gesamte params Objekt in den Dienst senden und es automatisch auf die Domäne zuordnen?

Antwort

7

ich diese Änderung vorgenommen, weil der Standard in der params Karte passieren, aber das ist schlecht für ein paar Gründe. Eine besteht darin, dass die Serviceebene mit der Webebene gekoppelt wird. Dies ist keine strikte Kopplung, da es sich nur um eine Map handelt, die Services jedoch wiederverwendbar und unabhängig sein sollten. Die andere ist, dass die Karte eine "magische" Karte ist, wo Sie die Schlüssel kennen müssen, um sie zu benutzen. Durch die Verwendung von benannten und typisierten Methodenargumenten ist der Code lesbarer und verständlicher.

Dies fügt eine Wartungsbelastung hinzu, da Sie beim Hinzufügen eines neuen Feldes die Signatur ändern müssen. Idealerweise ist diese Methode jedoch der einzige Ort, an dem diese Arbeit erledigt wird. Sie müssen sie nur an einer Stelle ändern.

Fühlen Sie sich frei, params in Ihrem eigenen Code zu verwenden, aber da dieses Projekt eines unserer Demo-Projekte ist, wollte ich, dass Best Practices wo möglich genutzt werden.

+0

Also, ist mit 'params' Karte im Dienst eine schlechte trainieren? Ist es notwendig, mit 'params' im Controller zu arbeiten? – havenchyk

1

Sie können die gesamte params an den Dienst senden, erklären wie Map:

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

Wenn Sie Ihre Daten so binden, denken Sie daran, dass 'params' aus Benutzereingaben stammt und Eigenschaften enthält, die Sie nicht erwarten. Siehe http://blog.springsource.org/2012/03/28/secure-data-binding-with-grails/ – ataylor

+0

Richtig, +1 für den Link :) –

2

Das Muster, das die PET-Klinik-App verwendet, ist eine ziemlich gute Best Practice.

Wenn die Service-Schicht params undicht wird, werden Ihre Dienste viel enger mit der Controller-Schicht verbunden. Die Wiederverwendung des Dienstes in beispielsweise einer API wäre schwieriger. Außerdem wird das Testen vereinfacht, wenn Ihre Servicemethoden eine explizite Schnittstelle in Form von Methodenparametern haben.

Verwandte Themen