Interfaces en JEE
Al punto. En los proyectos que implementan Spring en los que he estado suelen hacer una implementación con interfaces para los servicios.
interface Servicio1
class Servicio1Impl implements Serivicio1
algo así, para cada servicio, y mi pregunta es, aparte del enorme tedio, la complicación en potencia de código y la dificultad de mantenimiento de la aplicación que otras VENTAJAS provee este tipo de implementación? o por que siempre me dirán que así se usa o.O?
alguna idea? obviamente se para lo que sirve una interfaz y a grandes razgos se la ventaja pero me parecen mas las desventajas que trae consigo este tipo de implementación no creen?
gracias
- Inicie sesión o regístrese para enviar comentarios
La ventaja principal, aunque
La ventaja principal, aunque no necesariamente materializada es que puedes proveer una implementación diferente.
No estoy muy seguro de como exactamente funcione Spring pero en otros modulos por ejemplo, se puede hacer un programa complejo y utilizar puras interfaces y hacer que todo interactue y solo esperar a que llegue la implementación concreta y no haya necesidad de cambiar todo.
Un ejemplo de esto es la biblioteca para conexión a base de datos JDBC, hay componentes muy importantes que son puras interfaces ( si no es que todo el paquete son puras interfaces: Connection, ResultSet, Statement etc. luego viene el proveedor e implementa las interfaces y puedes tener varios drivers, por ejemplo de Oracle, DB2, MS - SQL Server
Quizá en tus proyectos no ves materializada esta ventaja y si resulta tedioso, pero ese el mecanismo que Java provee para permitir esta flexibilidad.
Otros lenguajes de programación lo hacen de forma diferente, podría haber alguno en el que simplemente llamas al método de la interfaz pero no dices que la implementas ni nada, es básicamente lo mismo:
Las cosas podrían ser así, simplemente pasarle a un objeto que aunque no implemente la interfaz explicitamente la implementa ( valga la redundancia ) implicitamente pues tiene los métodos requeridos.
Esto lo pueden hacer lenguajes de programación con tipeo estático, ni siquiera me refiero acá a los de tipeo dinámico, el inconveniente que algunas personas le ven es que se dificulta un poco más al humano saber si la clase en cuestión va a poder o no satisfacer la interfaz, porque lo único que ve es el tipo de dato (
) y tendría que de alguna forma ver sus métodos. Si implementa la interfaz hace de una forma más clara sus intenciones de ser como la interfaz.
A mi en lo personal me gustaría más que fuera implicito. Esta disciplina de tipeo se llama tipeo estructurado, donde si una clase tiene los mismos métodos que otra, se puede usar donde el tipo de dato de la otra es esperado.
Arquitectura
Con las interfaces yo también pensaba que eran cosas innecesarias pero, al final de cuentas sirven para mantener una jerarquía y una clasificación sobre los objetos que usas.
Un ejemplo común son los DAO, en donde tienes una interfaz simple:
De ahí, todos los objetos a usar la interfaz DAO DEBEN implementar esos métodos con el fin de controlar el comportamiento de cada objeto/clase. Claro que llega un punto en que la gente crea interfaces sin ton ni son y para cada cosa crean una interfaz, aunque sea idéntica a otra(s) interfa(z|ces).
El punto es que como todo si abusamos de ellas, podemos llegar a usarlas por usarlas sin ningún fundamento, en otras palabras caer en el: "Pues así se usa y siempre lo hemos hecho así".
Crear una interfaz desde mi punto de vista necesita de pensar un rato para que la vas a usar, no es para verte muy "I'm a pro 'cause I use interfaces"; sino por razones de modelo y arquitectura de tu proyecto.
Creo que hay lenguajes de programación que te piden una interfaz por cada clase que tengas y muchas personas se quedaron con esa idea al momento de pasarse a Java y por ello pasa lo que comentas.
Re: La ventaja principal, aunque
Creo que vi un error en tu explicación con código y eso es que según yo la clase "UnaClase" debería implementar la interfaz "UnaInterfaz", ¿no?...Quedando:
¿O el errado soy yo?
No, es a propósito, es un
No, es a propósito, es un ejemplo de algo que podría ser para no tener que agregar ese implements, la idea es similar al tipeo dinámico donde si el objeto responde al mensaje se invoca el método, pero este se llama tipeo estructurado donde si el compilador detecta que el método está presente te deja usarlo.
Existe un lenguaje de programación que se llama WhieOak que provee esta adición a Java introduciendo una nueva palabra reservada:
Ahi dejo el link.
La pregunta era: ¿que ventaja hay? la respuesta es claridad en cuanto a los métodos que tiene una clase y como contraste yo mencioné este paradigma que no lo necesita. Otro lenguaje de programación que no lo necesita es Go.
Programming to an interface not to an implementation
El concepto de servicio y de implementaciones de un servicio es un principio de diseño en cualquier paradigma de cómputo. Es algo "totalmente" establecido como una técnica que conduce a ventajas indiscutibles y a muy pocas desventajas. Es en estos momentos un postulado o axioma de la programación orientada a objetos que no necesita ser demostrado.
Lo mejor entonces es tratar de entenderlo considerándolo como algo ventajoso.
Programar basado en interfaces hace posible entonces trabajar con fábricas de objetos que encapsulan las dependencias con implementaciones (clases) diversas que una interfaz puede tener, ofreciendo aun más ventajas para el encapsulamiento de dependencias.
Los patrones de diseño basan su utilidad en muchas cosas, y entre esas cosas, el "encapsular lo que varía" ocupa uno de los primeros lugares. Programar contra interfaces contribuye a ese encapsulamiento de dependencias.
Continuando con las
Continuando con las ideas...
Piensa en la interfaz como un contrato, un modelo abstracto de qué hará tu servicio, todavía no del cómo lo va a resolver. Definiendo el qué (interfaz) es posible tener varias maneras de resolverlo, es decir, varias implementaciones (el cómo).
Por ejemplo, imagínate que tu servicio tiene que obtener el precio de un artículo de la base de datos, entonces supongamos que en este caso decides no hacerlo con una interfaz, e implementas directo la lógica que requieras para ello... ¿funciona no? Perfecto. Entonces, ahora imagina que por requerimiento los precios de algunos artículos los debes obtener ahora de un web service, en lugar de la conexión a la base de datos que ya tenías, pero sin hacer que la primera opción deje de funcionar. Lo que tendrías que hacer es crear otra clase para esto, e implementar la obtención del precio ahora por web service. La complicación viene en el momento en el que tienes que cambiar los llamados que ya hacías a tu otra clase, en todas las partes en las que se obtenía el precio yendo a la BBDD y que ahora quieres se haga con la clase que los obtiene por web service.
En este tipo de casos la ventaja de utilizar interfaces es muy alta, ya que si desde un inicio crearas una interfaz con la firma de el/los métodos para obtener el precio de un artículo, todas las partes de tu sistema que requieran el precio de un artículo únicamente necesitarán tener el servicio declarado como el tipo de la interfaz, y no de la clase concreta. Así, cuando necesites crear una implementación diferente, todas esas partes del sistema donde se hace uso del método para obtener el precio ni siquiera se enterarán cuando la implementación cambie, porque ellos conocen la interfaz, entonces así ya puedes poner en ellos el objeto que obtiene el precio mediante la base de datos o cambiarlo al que ocupa el web service, y no tendrás que modificar absolutamente nada en los demás.
Re: Continuando con las
Esta explicación fue la que me dieron cuando estaba aprendiendo y mi respuesta fue: ¿Pues qué no eso también lo puedo hacer con clases abstractas?... Y pues si, si se puede, el problema es cuando tienes que tener el comportamiento de más de una clase, digamos que tenemos gadgets que reproducen video y audio, podríamos hacer una clase abstracta:
Luego en nuestro reproductor de vídeo:
Y nuestro reproductor de música
Y ok, jala y tiene esa "implementación" en cada parte. Pero que pasa
.
si aparece otro gadget que es capaz de reproducir música, vídeo y
además trae la posibilidad de usar una calculadora. Recordemos que
en Java no existe la herencia múltiple, por tanto no podríamos hacer
algo como
Aquí es donde ayudan las interfaces, porqué mientras no puedes tener
.
herencia múltiple, en una clase puedes implementar varias interfaces, es decir,
si es correcto algo como
De esa manera "estandarizas" a tus objetos en caso de necesitar un
comportamiento y la implementación es como hacer dicho comportamiento.
Encontré una buena explicación de ello en SlideShare, pueden revisarla aquí,
en ésta me basé para explicarle a un amigo que quería aprender OOP.
Sry pro la tardanza
Mil gracias por la información, siempre con información objetiva y muy variada.
Sobre lo que comentas benek, que no se resolvería con un refractor? obviamente no es lo mas conveniente pero viendo las contras que trae implementar interfaces por doquier no me parece suficiente razón.
.
Me encuentro en la posición que menciona wishmaster77, me parece que muchos solo implementan interfaces solo por que así se usa "I'm a pro 'cause I use interfaces", no tengo nada en contra de las interfaces de echo entiendo que se hace modular y fácilmente migrable en cuanto a implementaciones pero lo que comenta bferro son palabras mayores, quizás debería entonces tratar de entender al 100% esto
(y poner interfaces a lo estúpido por todas partes mientras lo entiendo.... o.O)y supongo que mientras lo entiendo o encuentre a alguien que lo entienda puedo prescindir de las mismas y averiguar por mi mismo por que serían mejores pues me parece un tema muy profundo a como lo comenta bferro..
una pregunta yo me he topado con que para cada servicio se crea una interfaz así que se ve medio ilógico 10 servicios y 10 interfaces que "encapsulan" (que en realidad te estas encapsulando a ti mismo o.O)la información o contenido de la clase, me parece muy acertado el ejemplo que da wishmaster77 y en realidad esa es la razón por la que se usa UNA INTERFAZ en general no solo como patrón. El comentario va por lo siguiente, quizás yo me este confundiendo por que he estado observando implementaciones incorrectas de las interfaces, y no se implementan por doquier, y si es recomendable tenerlas pero de tal forma que sean útiles como en el ejemplo del Gadget, en la que varias clases implementan la interfaz, y no una sola, o en el caso de que se analice el alcance y se vea posible que en un futuro las implementaciones cambien o se creen flujos alternos.. etc.
Me refiero a que para eso se requeriría un análisis completo y no implementarlas por que así es lo mejor como le entendí a bferro, quizás se refería a esto mismo: "En estos casos siempre es mejor implementar interfaces..."
Aplicaciones Distribuidas
Ademas de los contratos que se pueden seguir, otra ventaja de hacer estas implementaciones es que puedes distribuir los servicios, puedes empaquetar las interfaces y del lado del cliente solo invocas por RMI, o EJB los servicios implementados, así si la lógica de negocio cambia o se optimizan los métodos no necesitas re distribuir las clases implementadas solo las despliegas en el servidor y eso es todo.
Interfaces y Spring
Estoy de acuerdo contigo White_King, a veces parece que se le quiere poner "mucha crema a los tacos",.. nos dicen cuál es la mejor manera de hacer algo, nos dicen que hay que hacerlo con interfaces, pero pocas veces nos justifican..
En fin, para mí el ejemplo más claro en dónde queda ejemplificado y justificado el uso de la interfaces es en JDBC.
Uno como programador usa JDBC casi todo a nivel de interfaces, muy pocas clases. Entonces creamos aplicaciones que son "independientes" del manejador de base de datos, y después simplemente decidimos qué driver utilizar, el de MySQL, el de Postgres, el de Oracle, etc.
Cada uno de estos drivers hace su propia implementación de la interfaz JDBC, para nosotros eso es transparente.
En concreto, la ventaja que he visto de implementar los servicios a través de interfaces en Spring es que dicha implementación no necesariamente tiene que ser con Java. Por ejemplo, la implementación se puede hacerse con algún lenguaje de script, Groovy por ejemplo.
Sale y vale
Byte
Ventaja al realizar cambios
Imagina la siguiente escenario tienes 2 módulos similares en un sistema hospitalario Urgencias y Terapia Intensiva 70% es igual pero como tienes 2 usuarios se derivan reglas diferentes para el sistema. Después de un tiempo liberaste el sistema y lo tienes que modificar.
¿Cómo te aseguras que un cambio en Urgencias no afecta a Terapia intensiva?
Otro escenario y esta vez dentro de un sistema. ¿Cómo te aseguras que un cambio en la base de datos no afecta la lógica o la pantalla?
Las interfaces son una herramienta que te ayuda a mantener el sistema tolerante a cambios.