¿Para qué sirven las constantes de interfaz?
Estoy aprendiendo Java y acabo de descubrir que la interfaz puede tener campos públicos, estáticos y finales. No he visto ningún ejemplo de estos hasta ahora. ¿Cuáles son algunos de los casos de uso de estas constantes de interfaz? ¿Puedo ver algunos en la biblioteca estándar de Java?
Poner miembros estáticos en una interfaz (e implementar esa interfaz) es una mala práctica e incluso tiene un nombre, Antipatrón de interfaz constante ; consulte Java efectivo , elemento 17:
El patrón de interfaz constante es un mal uso de las interfaces . Que una clase utilice 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 la API exportada de la clase. No tiene ninguna consecuencia para los usuarios de una clase que la clase implemente una interfaz constante. De hecho, puede que incluso los confunda. 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. Si una clase no final implementa una interfaz constante, todas sus subclases tendrán sus espacios de nombres contaminados por las constantes de la interfaz.
Hay varias interfaces constantes en las bibliotecas de la plataforma Java, como
java.io.ObjectStreamConstants
. Estas interfaces deben considerarse anomalías y no deben emularse.
Para evitar algunos errores de la interfaz constante (porque no se puede evitar que la gente la implemente), se debe preferir una clase adecuada con un constructor privado (ejemplo tomado de Wikipedia ):
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
Y para acceder a las constantes sin tener que calificarlas completamente (es decir, sin tener que anteponerles el nombre de la clase), use una importación estática (desde Java 5):
import static Constants.PLANCK_CONSTANT;
import static Constants.PI;
public class Calculations {
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT / (2 * PI);
}
}
" El patrón de interfaz constante es un mal uso de las interfaces "
Quien haya inventado esta hipótesis, por muy gurú que sea, lo ha hecho sobre la base de la necesidad de seguir implementando malos hábitos y prácticas de manera eficiente. La hipótesis se basa en la promoción de la validez de los malos hábitos de diseño de software.
Escribí una respuesta refutando esa hipótesis aquí: ¿ Cuál es la mejor manera de implementar constantes en Java? explicando la falta de fundamento de esta hipótesis.
Durante 10 años esa pregunta permaneció abierta, hasta que se cerró dos horas después de que publiqué mis razones que desjustificaban esta hipótesis, exponiendo así la falta de voluntad para el debate por parte de aquellos que se aferran a esta hipótesis equivocada.
Estos son los puntos que expresé en contra de la hipótesis.
La base para sostener esta hipótesis es la necesidad de métodos y reglas RESTRICTIVAS para hacer frente a los efectos de los malos hábitos y metodologías del software.
Los defensores del sentimiento " El patrón de interfaz constante es un mal uso de las interfaces" no pueden proporcionar otras razones que las causadas por la necesidad de hacer frente a los efectos de esos malos hábitos y prácticas.
Resuelve el problema fundamental.
Y entonces, ¿por qué no hacer un uso completo y explotar todas las características del lenguaje de la estructura del lenguaje Java para su propia conveniencia? No se requieren chaquetas. ¿Por qué inventar reglas para bloquear su estilo de vida ineficaz y discriminar e incriminar estilos de vida más eficaces?
La cuestión fundamental
es la organización de la información. Primero se debe comprender la información que media en el proceso y el comportamiento de esa información, junto con las llamadas reglas comerciales, antes de diseñar o complementar soluciones al proceso. Este método de organización de la información se llamaba hace unas décadas normalización de datos.
Entonces sólo será posible la ingeniería de una solución porque alinear la granularidad y modularidad de los componentes de una solución con la granularidad y modularidad de los componentes de la información es la estrategia óptima.
Hay dos o tres obstáculos importantes para organizar la información.
La falta de percepción de la necesidad de "normalizar" el modelo de datos.
Las declaraciones de EF Codd sobre la normalización de datos son erróneas, defectuosas y ambiguas.
La última moda que se hace pasar por ingeniería ágil es la noción equivocada de que no se debe planificar ni condicionar la organización de los módulos con antelación porque se puede refactorizar sobre la marcha. Se utiliza como excusa la refactorización y el cambio continuo sin verse obstaculizado por descubrimientos futuros. Los descubrimientos esenciales del comportamiento de la información de proceso se realizan entonces mediante el uso de trucos contables para retrasar las ganancias y la asequibilidad, por lo que el conocimiento esencial y su tratamiento se consideran innecesarios ahora.
El uso de constantes de interfaz es una buena práctica.
No inventes reglas ni emitas fatwas en su contra sólo porque te encantan tus hábitos de programación ad hoc.
No prohibir la posesión de armas porque hay personas que no saben cómo manejarlas o son propensas a abusar de ellas.
Si las reglas que usted elabora están destinadas a principiantes en programación que no pueden codificar profesionalmente y usted se cuenta entre ellos, entonces dígalo: no declare su fatwa como aplicable a modelos de datos correctamente normalizados.
Un razonamiento tonto: ¿los fundadores del lenguaje Java no pretendían que las interfaces se utilizaran de esa manera?
No me importa cuáles fueran las intenciones originales de los padres fundadores para la Constitución de Estados Unidos. No me importan las intenciones no escritas y no codificadas. Sólo me importa lo que está codificado literariamente en la Constitución escrita y cómo puedo explotarlo para el funcionamiento eficaz de la sociedad.
Sólo me importa lo que me permiten las especificaciones del lenguaje/plataforma Java y tengo la intención de explotarlas al máximo para brindarme un medio para expresar mis soluciones de software de manera eficiente y efectiva. No se requieren chaquetas.
El uso de Enum Constants es en realidad una práctica horrible.
Requiere escribir código adicional para asignar el parámetro al valor. El hecho de que los fundadores de Java no proporcionaron el mapeo de valores de parámetros sin que usted escribiera ese código de mapeo demuestra que las constantes Enum son un uso igualmente involuntario del lenguaje Java.
Especialmente porque no se le recomienda normalizar y componer sus parámetros, habría una impresión falsa de que los parámetros mezclados en una bolsa Enum pertenecen a la misma dimensión.
Las constantes son contrato API
No lo olvides. Si diseñó y normalizó su modelo de datos e incluye constantes, entonces esas constantes son contratos. Si no normalizó su modelo de datos, entonces debe cumplir con las fatwas dadas sobre cómo practicar la codificación restrictiva para hacer frente a ese mal hábito.
Por lo tanto, las interfaces son una forma perfecta de implementar el contrato de Constantes.
Una suposición extraña: ¿qué pasa si la interfaz se implementa sin darse cuenta?
Sí. Cualquiera podría implementar sin querer cualquier interfaz. Nada se interpondrá en el camino de programadores tan inadvertidos.
Diseñe y normalice su modelo de datos contra fugas
No coloque decretos restrictivos para proteger presuntas malas prácticas que causan la filtración de parámetros no contratados o extraviados en la API. Resuelva el problema fundamental, en lugar de echarle la culpa a las constantes de interfaz.
No utilizar un IDE es una mala práctica
Un programador EFICAZ y que funcione normalmente no está allí para demostrar cuánto tiempo puede permanecer bajo el agua, qué distancia puede caminar en medio de un calor abrasador o tormentas húmedas. Debe utilizar una herramienta eficiente como un automóvil, un autobús o al menos una bicicleta para llevarla 10 millas al trabajo todos los días.
No imponga restricciones a sus compañeros programadores sólo porque tenga una obsesión esotérica y ascética con la programación sin IDE.
Un par de marcos están diseñados para ayudar a los programadores a continuar practicando malos hábitos de manera eficiente.
OSGI es uno de esos marcos. Y también lo es el decreto contra las constantes de interfaz.
Por lo tanto la respuesta concluyente...
Las constantes de interfaz son una forma eficaz y eficiente de colocar en el contrato componentes normalizados y bien diseñados de un modelo de datos.
Las constantes de interfaz en una interfaz privada con el nombre apropiado anidada en un archivo de clase también son una buena práctica para agrupar todas las constantes privadas en lugar de dispersarlas por todo el archivo.
Me encontré con esta vieja pregunta varias veces y la respuesta aceptada todavía me confunde. Después de pensarlo mucho, creo que esta pregunta se puede aclarar aún más.
¿Por qué utilizar la interfaz constante?
Simplemente compárelos:
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
vs
public interface Constants {
double PI = 3.14159;
double PLANCK_CONSTANT = 6.62606896e-34;
}
Mismo uso. Mucho menos código.
¿Mala práctica?
Creo que la respuesta de @Pascal Thivent tiene el énfasis equivocado, aquí está mi versión:
Poner miembros estáticos en una interfaz ( e implementar esa interfaz ) es una mala práctica.
La cita de Effective Java parte del supuesto de que otros implementan la interfaz constante, lo que creo que no debería suceder (y no sucederá).
Cuando crea una interfaz constante llamada algo así como Constants
, nadie debería implementarla. (aunque técnicamente posible, que es el único problema aquí)
No sucederá en la biblioteca estándar.
La biblioteca estándar no puede permitirse ningún posible mal uso del diseño, por lo que simplemente no verá ninguno allí.
Sin embargo , para los proyectos diarios de desarrolladores normales, usar la interfaz de constantes es mucho más fácil porque no necesita preocuparse por static
, etc., final
y empty constructor
NO causará ningún problema de diseño incorrecto. La única pega que se me ocurre es que todavía tiene el nombre de «interfaz», pero nada más que eso.
Debate interminable
Al final, creo que todo el mundo se limita a citar libros y dar opiniones y justificaciones a sus posturas. Para mí no hay excepción. Quizás la decisión aún dependa de los desarrolladores de cada proyecto. Continúe usándolo si se siente cómodo. Lo mejor que podemos hacer es hacerlo consistente durante todo el proyecto .