2011-02-02 18 views
14

Me preguntaba si es posible crear una interfaz de servicio en Grails y no puedo encontrar una forma adecuada de hacerlo. Esta explicación no es satisfactoria, ya que parece mezclar Java y Groovy:¿Cómo separar la interfaz de la implementación en los servicios de Grails?

http://www.grails.org/doc/latest/guide/8.%20The%20Service%20Layer.html

Me parece como un mal fallo de diseño del marco, dado que el mecanismo de interfaz es una de las mejores características de Java (y la mayoría de los lenguajes OO).

¿Alguna idea para aclarar este problema?

Gracias! Mulone

+3

¿Cuál es el problema al crear una interfaz en 'src' e implementarla en el servicio? ¿O desea poder reemplazar la implementación del servicio sobre la marcha? Los delegados (http://groovy.codehaus.org/Replace+Inheritance+with+Delegation) ayudarían. –

Respuesta

5
  • definir la interfaz de servicio en una clase com.mycompany.mypackage.MyInterface.groovy almacenado under src/groovy
  • definir la implementación del servicio se almacena en grails-app/services

    class MyService implements MyInterface { 
        // service implementation goes here 
    } 
    
+0

pero en este caso puedo especificar en el controlador "def myInterface"? ¿Cómo va a funcionar la inyección? – Mulone

+0

No, declararía 'def myService' –

+0

¿Cómo va a saber la inyección de dependencia qué implementación desea inyectar en su controlador? Como dice tim_yates, tienes que decirlo, nombrándolo. Durante el tiempo de ejecución podría tomar otra referencia de bean implementando su interfaz y asignarla a myService, y así tener los mismos métodos disponibles. – sbglasius

1

No es un defecto de diseño. Groovy es diferente de Java, ya que es un lenguaje dinámico que usa "pato-tipado". Lo que es interesante en groovy es que también hay interfaces. Entonces, si sigues la sugerencia de @ don, puedes asegurarte de que tu servicio cumpla con la interfaz, pero la forma en que haces DI con grails es simplemente especificar la implementación del servicio. es decir, si no obtiene el tiempo de compilación, marque donde usa la implementación del servicio, como lo hace en Java.

Tenga en cuenta que aquí no hay un acoplamiento apretado. El acoplamiento implica que algo está ligado a un tipo. Pero con el sistema de tipeo suelto de Groovy, los tipos son esencialmente criaturas dinámicas. Por lo tanto, en Java, si declara que un tipo es una implementación específica, es posible que el código no se compile si cambia el tipo más tarde. En groovy, el código siempre compilará si usa la 'def' ... (Creo que esto es correcto)

17

Puede tener una interfaz, pero en realidad no la necesita. Si lo entiendo correctamente, le gustaría tener dos implementaciones de un servicio y poder elegir cuál usar.

Basta con aplicar dos servicios nombrados por ejemplo MyService1 y MyService2, a continuación, en grails-app/conf/spring/resource.groovy puede especificar:

beans = { 
    ... 
    // syntax is beanId(implementingClassName) { properties } 
    myService(MyService1) 
    ... 
} 

o incluso:

beans = { 
    ... 
    if (someConfigurationOption) { 
     myService(MyService1) 
    } else { 
     myService(MyService2) 
    } 
} 

Así es como se dice de primavera, que el servicio de inyectar realidad para myService. Ahora usted será capaz de utilizar myService como:

public MyController { 
    def myService 
    ... 
} 

y el resorte de alambre automática una correcta aplicación. Esto le permite configurar qué implementación del servicio usar basándose, por ejemplo, en alguna configuración.

0

La mejor solución que encontré para esto es usar alias de alubias de resorte.Básicamente lo que necesita:

1) Crear una interfaz en src/maravilloso (MyService.groovy)

2) Inyectar su servicio siempre que lo necesite:

class MyController { 
    MyService myService 
} 

3) Crear sus servicios regulares aplicación de dicha interfaz (ImplOneService.groovy, ImplTwoService.groovy)

4) Añadir una entrada a resources.groovy donde se define la aplicación que debe utilizar (con el tiempo, las pruebas de medio ambiente, o cualquier otra cosa que necesita):

beans = { 
    if (...development, useFTP, etc...) { 
     springConfig.addAlias 'myService', 'ImplOneService' 
    } else { 
     springConfig.addAlias 'myService', 'ImplTwoService' 
    } 
} 

Complete sources here

Los comentarios que: El uso de las interfaces en el maravilloso realmente parece como una especie de "Quiero seguir con un poco de materia java estoy más cómodo con". En este caso, fuerte-tipando. Pero es exactamente la parte buena de Groovy que dice "No te preocupes, puedes mantener el camino de Java si quieres".

Cuestiones relacionadas