¿Es una mala práctica tener una interfaz para definir constantes?

40

Estoy escribiendo un conjunto de clases de prueba junit en Java. Hay varias constantes, por ejemplo, cadenas que necesitaré en diferentes clases de prueba. Estoy pensando en una interfaz que los defina y cada clase de prueba la implementaría.

Los beneficios que veo son:

  • Fácil acceso a las constantes: en MY_CONSTANTlugar deThatClass.MY_CONSTANT
  • cada constante definida solo una vez

¿Es este enfoque más bien una buena o mala práctica? Tengo ganas de abusar un poco del concepto de interfaces.

Puede responder generalmente sobre interfaces / constantes, pero también sobre pruebas unitarias si hay algo especial al respecto.

FabianB
fuente
La respuesta para "¿Es una mala práctica que una interfaz defina X?", Siendo X cualquier cosa que no sea "firmas de métodos", casi siempre es "Sí".
T. Sar - Restablece a Monica el

Respuestas:

79

Joshua Bloch desaconseja esto en su libro Effective Java :

Que una clase use algunas constantes internamente es un detalle de implementación. La implementación de una interfaz constante hace que este detalle de implementación se filtre en las clases API exportadas. No tiene ninguna consecuencia para los usuarios de una clase que la clase implemente una interfaz constante. De hecho, incluso puede confundirlos. Peor aún, representa un compromiso: si en una versión futura la clase se modifica para que ya no necesite usar las constantes, aún debe implementar la interfaz para garantizar la compatibilidad binaria.

Puede obtener el mismo efecto con una clase normal que define las constantes y luego usar import static com.example.Constants.*;

mate
fuente
13

En nuestro caso, estamos haciendo esto porque los valores de las constantes representan un contrato para estados finales que debe proporcionar una implementación de servicio. Poner estas constantes en la interfaz especifica los estados finales como parte del contrato, y si alguna implementación de la interfaz no los usa, no estaría haciendo su trabajo.

A VECES las constantes son detalles de implementación. A veces no lo son. Como de costumbre, un ingeniero necesita usar su cerebro para decidir qué hacer, y no confiar en un patrón o práctica radical.

usuario144901
fuente
7

No creo que sea bueno tener interfaces solo para constantes.

Pero si una interfaz que define el comportamiento (los métodos que implementan las clases deberían implementar), tiene constantes, está bien. Si "filtra algunos detalles del implementador" en la API, es porque así debe ser. También están filtrando que el implementador implementa métodos foo y bar.

Tomemos, por ejemplo, la interfaz java.awt.Transparency. Tiene constantes OPAQUE, BITMASK y TRANSLUCENT pero también tiene el método getTransparency ().

Si el diseñador puso esas constantes allí, es porque pensó que sería lo suficientemente estable como para ser parte de la interfaz, como lo es getTransparency ().

Tulains Córdova
fuente
2

Piense que es un punto de vista principalmente popular en lugares donde prevalece el diseño por contrato.
Las interfaces son contratos. Colocar constantes en las interfaces significa que cada clase que cumple con el contrato acepta el valor / concepto identificado por la constante.

CMR
fuente
1
Las interfaces son contratos públicos. Los valores constantes son preocupaciones privadas, la interfaz pública debe exponer a lo sumo sus nombres. Es mejor dejarlo en una clase abstracta.
Jwent
Casos en cuestión: javax.naming.Context, javax.ims.Session y cientos de tales interfaces ...
CMR
2
@jwenting Además, ¿podría una interfaz pública "at most expose their names", sin exponer los valores?
CMR
eso dependería del lenguaje de programación, supongo. En el caso de Java, no.
Jwenting 01 de
2

Una empresa en la que trabajé hizo un uso intensivo de las constantes 1 importadas por interfaz . No siento ningún daño por eso.

La pregunta que debe hacerse es: ¿qué importancia tiene para usted el espacio de nombres? En el caso de las constantes, eso es realmente todo lo que una clase actúa. Si tiene miles de constantes, es posible que no desee que todas esas constantes estén siempre disponibles.

Lo bueno de las interfaces es que le brinda el beneficio de trabajar de cualquier manera: traiga todos los espacios de nombres que necesita, o ninguno de ellos (y acceda a ellos explícitamente, con MyInterface.CONSTANT). Más o menos lo mismo import static MyInterface.*, pero un poco más obvio.


1: Si no está familiarizado con Java, no me refiero a la importpalabra clave, solo me refiero a que ingresó a través deimplements MyConstantsInterface

Nicole
fuente
1

Vengo de un entorno que está influenciado principalmente por la 'forma Ada' y la 'forma .Net'. Yo diría que no, que probablemente no sea mejor declarar constantes dentro de las interfaces. Técnicamente no está permitido en c #.

La razón por la que digo que no es que una interfaz es una forma de contrato que define el comportamiento, no el estado o la estructura. Una constante implica algún tipo de estado (primitivo), o un aspecto de estado (compuesto o agregado).

Puedo apreciar la necesidad de hacer que los valores predeterminados y predefinidos estén disponibles para todos los que implementan la interfaz, pero tal vez el estado predeterminado se describirá mejor en un objeto o plantilla abstracto o de valor, donde los valores predeterminados tendrían al menos un contexto mínimo.

Para obtener una guía más técnica: download.oracle.com/javase/1.5.0/docs/guide/language/static-import.html

JustinC
fuente
Agregar más enlaces que hacen referencia a la importación estática (1.5): 1. Wikipedia 2. Documentos de Oracle que hacen referencia a @Justinc
Abhijeet
1
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Referencia de Oracle Docs
Abhijeet
1

No, no es una mala práctica general.

El punto es que las constantes como cualquier otro artefacto deben introducirse bajo las reglas de visibilidad mínima y nivel de abstracción adecuado.

Usar la sintaxis solo porque puedes es el verdadero problema.

oopexpert
fuente