2010-04-17 21 views
18

he estado programando en Java durante unos cursos en la Universidad y tengo la siguiente pregunta:Metodología de interfaces Java: ¿Debería cada clase implementar una interfaz?

¿Es que metodológicamente se acepta que cada clase debe implementar una interfaz? ¿Se considera una mala práctica no hacerlo? ¿Puedes describir una situación en la que no es una buena idea usar interfaces?

Editar: Personalmente, me gusta la idea de usar interfaces para todo, como una metodología y el hábito, incluso si no es claramente beneficioso. Eclipse creó automáticamente un archivo de clase con todos los métodos, por lo que no pierde tiempo de todos modos.

+0

relacionadas: https://www.symphonious.net/2011/06/18/the-single-implementation-fallacy/ – jaco0646

+0

relacionadas: https://marekdec.wordpress.com/2011/12/06/explicit-interface-per-class-antipattern/ – jaco0646

+0

Relacionado: http://martinfowler.com/bliki/InterfaceImplementationPair.html – jaco0646

Respuesta

21

No necesita crear una interfaz si no va a utilizarla.

Normalmente se necesita una interfaz cuando:

  • Su programa proporcionará varias implementaciones para su componente. Por ejemplo, una implementación predeterminada que es parte de su código, y una implementación simulada que se utiliza en una prueba JUnit. Algunas herramientas automatizan la creación de una implementación simulada, como por ejemplo EasyMock.
  • Desea utilizar la inyección de dependencia para esta clase, con un marco como Spring o JBoss Micro-Container. En este caso, es una buena idea especificar las dependencias de una clase con otras clases utilizando una interfaz.
+4

+1 para pruebas unitarias y burlas. Utilizo interfaces en casi todas mis clases precisamente por este motivo. –

+4

@Philippe El marco burlón moderno puede simular clases. –

+0

disculpe la pregunta insensata, pero ¿qué es el marco burlón? –

17

Siguiendo el principio YAGNI, una clase debe implementar una interfaz si realmente la necesita. De lo contrario, ¿qué ganas con eso?

Editar: Las interfaces proporcionan un tipo de abstracción. Son particularmente útiles si desea intercambiar entre diferentes implementaciones (muchas clases que implementan la misma interfaz). Si es solo una clase, no hay ganancia.

2

Las interfaces son la forma de obtener un polimorfismo. Entonces, si solo tiene una implementación, una clase de tipo particular, no necesita una interfaz.

+1

Las interfaces proporcionan abstracción, no encapsulación. –

+0

Estaba pensando en el polimorfismo. No sé por qué dije encapsulación. Mi error. Error de ortografía. –

+0

Si bien soy un defensor de las interfaces, el polimorfismo se puede lograr en Java sin usar una interfaz, ya que puede ampliar cualquier clase no final y sobrecargar cualquier método no estático final – Kirby

5

No, no es necesario que cada clase implemente una interfaz. Use interfaces solo si hacen que su código sea más limpio y fácil de escribir.

Si su programa no necesita actualmente tener más de 1 implementación para una clase determinada, entonces no necesita una interfaz. Por ejemplo, en un simple programa de ajedrez que escribí, solo necesito 1 tipo de objeto de la Junta. Un tablero de ajedrez es un tablero de ajedrez es un tablero de ajedrez. Hacer una interfaz de la Junta e implementar eso habría requerido más código para escribir y mantener.

Es muy fácil cambiar a una interfaz si finalmente la necesita.

+1

si crea un programador solo es fácil pero no si su código ya es utilizado por múltiples proyectos: entonces será considerado un mal diseñador porque romperá el código del cliente. – user310291

+1

Bueno, sí, hay algunos casos en los que las interfaces tienen sentido, y las clases en bibliotecas distribuidas son uno de esos casos. Pero el OP no preguntó sobre ese caso específico, estaba preguntando sobre todas las clases. –

0

Cuando diseño un nuevo sistema desde cero uso un enfoque orientado a componentes, cada componente (10 o más clases) proporciona una interfaz, esto me permite (a veces) reutilizarlos.

  • Al diseñar una herramienta (o un sistema simple) Creo que esto no tiene que ser necesariamente un marco extensible introduzco las interfaces cuando necesito una segunda aplicación como una opción.

  • Vi algunos productos que expusieron casi todas las funcionalidades de una interfaz, tomó demasiado tiempo para comprender la complejidad innecesaria.

1

Una buena manera de aprender lo que se consideran buenas metodologías, especialmente cuando se trata de diseño de estructura de código, es mirar el código disponible gratuitamente. Con Java, el ejemplo obvio es echar un vistazo al JDK system libraries.

Encontrará muchos ejemplos de clases que no implementan ninguna interfaz, o que están destinadas a ser utilizadas directamente, como java.util.StringTokenizer.

+2

Agregaría la advertencia de que el lenguaje Java y las prácticas de programación pueden haber evolucionado desde que la clase se escribió originalmente y el código no ha cambiado para romper la compatibilidad con versiones anteriores.Por ejemplo, varias bibliotecas de sistema todavía usan 'static final' int o String constants para cosas que serían mejores usando enums, clases que toman o devuelven Objects que requieren un molde que sería mejor usando genéricos, y clases cuyos métodos solo toman Vectors o Hashtables porque la API de colecciones aún no se había escrito. – Nate

3

Descubrí que es beneficioso definir los métodos públicos de una clase en una interfaz correspondiente y cuando se definen referencias a otras clases, se usa estrictamente una referencia de interfaz. Esto permite una fácil inversión del control, y también facilita la prueba unitaria con burla y punteo. También le da la libertad de reemplazar la implementación con alguna otra clase que implemente esa interfaz, por lo que si está interesado en TDD puede hacer las cosas más fáciles (o más artificiales si es crítico con TDD)

1

Si usa el Servicio El patrón de interfaz del proveedor en las interfaces de la aplicación es más difícil de extender que las clases abstractas. Si agrega un método a la interfaz, todos los proveedores de servicio deben reescribirse. Pero si agrega un método no abstracto a la clase abstracta, ninguno de los proveedores de servicios debe reescribirse.

Las interfaces también dificultan la programación si solo una pequeña parte de los métodos de interfaz usualmente tienen una implementación significativa.

+0

Estos no son problemas con las interfaces en sí; simplemente son malos diseños de jerarquía. Tendría los mismos problemas si usa la misma jerarquía mal diseñada ampliando las clases. – Nate

4

No es necesario crear una interfaz para cada clase. Algunas de las razones comúnmente citadas incluyen burlas (innecesarias con marcos modernos de imitación como Mockito) y para la inyección de dependencias (por ejemplo, Spring, que también es innecesario en las implementaciones modernas).

Cree una interfaz si la necesita, especialmente para documentar formalmente las interfaces públicas. Hay un par de casos ingeniosos (por ejemplo, interfaces de marcadores).

Por si vale la pena, en un proyecto reciente utilizamos interfaces para todo (tanto DI como burlas se mencionaron como razones) y resultó ser un desperdicio completo y añadió mucha complejidad: era tan fácil agregue una interfaz cuando realmente se necesita para burlarse de algo en los raros casos en que fue necesario. Al final, estoy seguro de que alguien terminará entrando y eliminando todas las interfaces externas algún fin de semana.

Me doy cuenta de que los programadores C que se están mudando primero a Java tienden a gustar muchas interfaces ("son como encabezados"). La versión actual de Eclipse es compatible con esto, al permitir la navegación con control y clic para generar una ventana emergente que solicita una interfaz o implementación.

8

Cada clase implementa una interfaz (es decir, un contrato) en la medida en que proporciona una API no privada. Si debe elegir representar la interfaz por separado como una interfaz Java depende de si la implementación es "un concepto que varía".

Si está absolutamente seguro de que solo hay una implementación razonable, entonces no hay necesidad de una interfaz. De lo contrario, una interfaz le permitirá cambiar la implementación sin cambiar el código del cliente.

Algunas personas gritarán "YAGNI", asumiendo que usted tiene control total sobre el cambio del código en caso de que descubra un nuevo requisito más adelante. Otras personas sentirán justamente temor de que tengan que cambiar lo inmutable, una API publicada.

Si no implementa una interfaz (y utiliza algún tipo de fábrica para la creación de objetos), ciertos tipos de cambios le obligarán a romper el Principio de Open-Closed. En algunas situaciones esto es comercialmente aceptable, en otros no lo es.

¿Puede describir una situación en la que no es una buena idea usar interfaces?

En algunos idiomas (por ejemplo, C++, C#, pero no en Java) puede obtener un beneficio de rendimiento si su clase no contiene métodos virtuales.

En programas pequeños, o aplicaciones sin API publicados, entonces puede ver un pequeño costo para mantener interfaces separadas.

Si ve un aumento significativo en la complejidad debido a la separación de la interfaz y la implementación, entonces probablemente no esté utilizando las interfaces como contratos. Las interfaces reducen la complejidad. Desde la perspectiva del consumidor, los componentes se convierten en productos que cumplen con los términos de un contrato en lugar de entidades que tienen detalles de implementación sofisticados por derecho propio.

+1

"Cada clase implementa una interfaz (es decir, un contrato) en la medida en que proporciona una API no privada". ¡ESO es una sabia observación! –

+0

Relacionados: http://martinfowler.com/bliki/ImpllicitInterfaceImplementation.html – jaco0646

-5

Usar la interfaz está a punto de hacer que su marco de trabajo sea flexible. Dado que como mencioné aquí (Multiple Inheritance Debates II: according to Stroustrup) la herencia múltiple se canceló en java y C#, lo cual lamento, siempre se debe usar Interface porque nunca se sabe cuál será el futuro.

+7

Prepararse para el futuro antes de saber qué depara el futuro lleva a un código innecesariamente complicado. –

2

Para responder a la pregunta del OP de una manera muy contundente: no, no todas las clases necesitan implementar una interfaz. Al igual que para todas las preguntas de diseño, esto se reduce al mejor juicio. Aquí están algunos de los pulgares regla que normalmente siguen,

objetos
  • puramente funcional, probablemente no necesitan (por ejemplo del patrón, CharMatcher - aunque el último no aplicar predicado, que es secundario a su núcleo función)
  • titulares de los datos puros, probablemente no necesitan a (por ejemplo LogRecord, Locale)
  • Si puede imaginar una implementación diferente de una funcionalidad determinada (por ejemplo, en -memory caché frente a la memoria caché basada en disco), intente aislar la funcionalidad en una interfaz con . Pero no vayas demasiado lejos tratando de predecir el futuro tampoco.
  • Para propósitos de prueba, es muy conveniente cuando clases que hacer E/S o comienzan las discusiones son fácilmente mockable, por lo que los usuarios no pagar una multa cuando la gestión de sus pruebas.
  • No hay nada peor que una interfaz que pierde su implementación subyacente . Presta atención donde trazas la línea y asegúrate de que el Javadoc de tu interfaz sea neutral de esa manera. Si no es así, probablemente no necesites una interfaz.
  • general habla, es preferible que clases destinadas para el consumo público fuera de su paquete/proyecto para implementar interfaces para que sus usuarios se ven menos acoplados a su aplicación du jour.

Tenga en cuenta que probablemente pueda encontrar contraejemplos para cada una de las viñetas en esa lista. Las interfaces son muy potentes, por lo que deben usarse y crearse con cuidado, especialmente si proporciona API externas (vea this video para convencerse). Si eres demasiado rápido para poner una interfaz frente a todo, probablemente terminarás filtrando tu implementación única, y solo estás haciendo las cosas más complicadas para las personas que te siguen. Si no los usa lo suficiente, puede terminar con una base de código que es igualmente difícil de mantener porque todo está vinculado estáticamente y es muy difícil de cambiar. La lista no exhaustiva de arriba es donde trato de trazar la línea.

0

Una interfaz es como un contrato entre un proveedor de servicios (servidor) y el usuario de dicho servicio (cliente).

  • Si estamos desarrollando un servicio web y estamos exponiendo las rutas de descanso a través de clases de controlador, clases de controlador pueden implementar interfaces y las interfaces a actuar como el acuerdo entre el servicio web y los otros aplicaciones que utilizan este servicio web .
  • interfaces Java como Serializable, Clonnable y remoto utiliza para indicar algo que compilador o JVM.When JVM ve una clase que implementan estas interfaces, se realiza alguna operación en la que serialización de apoyo, la clonación o Invocación de método remoto. Si su clase necesita estas características, tendrá que implementar estas interfaces.

Cuestiones relacionadas