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_CONSTANT
lugar 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.
java
design
programming-practices
constants
FabianB
fuente
fuente
Respuestas:
Joshua Bloch desaconseja esto en su libro Effective Java :
Puede obtener el mismo efecto con una clase normal que define las constantes y luego usar
import static com.example.Constants.*;
fuente
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.
fuente
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 ().
fuente
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.
fuente
"at most expose their names"
, sin exponer los valores?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 mismoimport static MyInterface.*
, pero un poco más obvio.1: Si no está familiarizado con Java, no me refiero a la
import
palabra clave, solo me refiero a que ingresó a través deimplements MyConstantsInterface
fuente
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
fuente
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 DocsNo, 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.
fuente