java - utilidad - ¿Para qué sirven las constantes de interfaz?
trabajar con interfaces java (9)
Estoy aprendiendo Java y acabo de descubrir que la interfaz puede tener campos, que son 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 y puedo ver algunos en la Biblioteca estándar de Java?
" El patrón de interfaz constante es un uso deficiente de las interfaces "
Quien inventó esta hipótesis, por muy gurú que sea, la preparó sobre la base de la necesidad de continuar 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 de refutación contra esa hipótesis aquí: ¿Cuál es la mejor manera de implementar constantes en Java? explicando lo infundado de esta hipótesis.
Durante 10 años esa pregunta permaneció abierta, hasta que se cerró dentro de las 2 horas después de que publicara mis razones para justificar esta hipótesis, exponiendo de ese modo la PENA por el debate de aquellos que se aferran a esta hipótesis errónea.
Estos son los puntos que expresé contra 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 de software.
Los defensores del sentimiento " El patrón de interfaz constante es un uso deficiente de las interfaces" no pueden proporcionar ninguna otra razón que no sean 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 aprovechar al máximo y explotar cada característica del lenguaje de la estructura del lenguaje Java para su propia conveniencia? No se requieren chaquetas. ¿Por qué inventar reglas que bloqueen su estilo de vida ineficaz para discriminar e incriminar estilos de vida más efectivos?
El problema fundamental
es la organización de la información. La información que media el proceso y el comportamiento de esa información deben entenderse primero, junto con las llamadas reglas comerciales, antes de diseñar o complementar las soluciones al proceso. Tal método de organización de la información se llamó normalización de datos hace algunas décadas.
Entonces, solo la ingeniería de una solución será posible porque alinear la granularidad y la modularidad de los componentes de una solución con la granularidad y la 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 una "normalización" del modelo de datos.
Las declaraciones de EF Codd sobre la normalización de datos son defectuosas, defectuosas y ambiguas.
La última moda enmascarada como ingeniería ágil es la noción equivocada de que uno no debe planificar y condicionar la organización de los módulos que se encuentran adelante porque puede refactorizar sobre la marcha. La refactorización y el cambio continuo sin ser obstaculizado por descubrimientos futuros se usan como excusa. Los descubrimientos esenciales del comportamiento de la información del proceso es, entonces, mediante el uso de trucos contables para retrasar las ganancias y la propiedad, por lo que el conocimiento esencial y su tratamiento se considera que no es necesario ahora.
Usar las constantes de interfaz es una buena práctica.
No invente reglas ni emita ninguna fatwa contra eso solo porque le encantan sus hábitos de programación ad-hoc "golpear y ejecutar".
No prohíba la posesión de armas con la razón de que hay personas que no saben cómo manejar las armas o que son propensas a abusar de ellas.
Si las reglas que elabora están destinadas a la programación de principiantes que no pueden codificar profesionalmente y que se cuentan entre ellos, dígalo así: no declare su fatwa como aplicable a los modelos de datos debidamente normalizados.
Un razonamiento tonto: las interfaces no fueron pensadas por los lenguajes del lenguaje Java para ser utilizados de esa manera?
No me importa lo que las intenciones originales de los padres fundadores tenían para la Constitución de los Estados Unidos. No me importan las intenciones no codificadas y no codificadas. Solo me importa lo que se codifica literariamente en la Constitución escrita y cómo puedo explotarlos para el funcionamiento efectivo de la sociedad.
Solo me importa lo que las especificaciones de plataforma / lenguaje Java me permitan y pretendo explotarlas al máximo para proporcionarme un medio para expresar mis soluciones de software de manera eficiente y efectiva. No se requieren chaquetas.
El uso de constantes de Enum es realmente 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 parámetros y valores sin que usted escriba que el código de mapeo demuestra las constantes de Enum es tan solo un uso involuntario del lenguaje de Java.
Especialmente dado que no le recomendamos que normalice y compense sus parámetros, habría una falsa impresión de que los parámetros mezclados en una bolsa Enum pertenecen a la misma dimensión.
Las constantes son un contrato API
No lo olvides Si diseñó y normalizó su modelo de datos e incluye constantes, esas constantes son contratos. Si no normalizaste tu modelo de datos, entonces deberías conformarte con las fatwas sobre cómo practicar la codificación restrictiva para lidiar con ese mal hábito.
Por lo tanto, las interfaces son una forma perfecta de implementar el contrato de Constants.
Una presunción extraña: ¿qué ocurre si la interfaz se implementa inadvertidamente?
Sip. Cualquiera puede implementar inadvertidamente cualquier interfaz inadvertidamente. Nada se interpondrá en el camino de tales programadores inadvertidos.
Diseñe y normalice su modelo de datos contra fugas
No coloque decretos restrictivos para proteger las presuntas malas prácticas que provocan la filtración de parámetros no contraídos / perdidos en la API. Resuelve el problema fundamental, en lugar de echarle la culpa a las Constantes de interfaz.
No usar un IDE es una mala práctica
Un programador de funcionamiento normal y EFICAZ no está allí para demostrar cuánto tiempo puede permanecer bajo el agua, qué tan lejos puede caminar en calor abrasador o tormentas eléctricas mojadas. Ella usará una herramienta eficiente como un automóvil o un autobús o, al menos, una bicicleta para llevarla 10 millas diarias al trabajo.
No impongas restricciones a otros programadores solo porque tienes una obsesión por el ascetismo esotérico con la programación sin IDE.
Un par de marcos están diseñados para ayudar a los programadores a seguir practicando los malos hábitos de manera eficiente.
OSGI es un marco así. Y también lo es el decreto contra Interface Constants.
Por lo tanto, la respuesta concluyente ...
Las constantes de interfaz son una forma efectiva y eficiente de colocar en Contrato componentes bien diseñados y normalizados de un modelo de datos.
Las constantes de interfaz en una interfaz privada apropiadamente nombrada anidadas en un archivo de clase también son una buena práctica para agrupar todas sus constantes privadas en lugar de dispersarlas por todo el archivo.
los campos deben declararse en una interfaz para que sean más fáciles de compartir y se puedan referenciar sin introducir un acoplamiento adicional.
Fuente: Herramientas de desarrollo de Java Estilo de codificación
Hay respuestas que son muy razonables.
Pero tengo algunas reflexiones sobre esta pregunta. (puede estar mal)
En mi opinión, los campos en una interfaz, no deben ser constantes para todo el proyecto, solo son medios para la interfaz y las interfaces lo amplían y las clases que implementan estas interfaces o tienen una estrecha relación con ellas. Deben usarse dentro de un cierto rango no global.
Joshua Bloch, "Java eficaz - Guía de lenguaje de programación":
El patrón de interfaz constante es un uso deficiente de las interfaces. 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 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, 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, todavía 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 en la interfaz.
La interfaz javax.swing.SwingConstants
es un ejemplo que obtuvo campos estáticos que se usan entre las clases de swing. Esto le permite usar fácilmente algo como
-
this.add(LINE_START, swingcomponent);
-
this.add(this.LINE_START, swingcomponent);
o -
this.add(SwingComponents.LINE_START, swingcomponent);
Sin embargo, esta interfaz no tiene métodos ...
Me encontré con esta pregunta y pensé que agregaría algo que no fue mencionado. En general, estoy de acuerdo con la respuesta de Pascal here . Sin embargo, no creo que las constantes en una interfaz sean "siempre" antipatrón.
Por ejemplo, si las constantes que está definiendo son parte de un contrato para esa interfaz, creo que la interfaz es un excelente lugar para las constantes. En algunos casos, no es apropiado validar sus parámetros de manera privada sin exponer el contrato a los usuarios de su implementación. Sin un contrato público, los usuarios solo pueden adivinar con qué validación, a excepción de descompilar la clase y leer su código.
Entonces, si implementa una interfaz y la interfaz tiene las constantes que usa para garantizar sus contratos (como rangos enteros, por ejemplo), un usuario de su clase puede estar seguro de que está utilizando la instancia de interfaz correctamente al verificar contra las constantes en la interfaz sí mismos. Esto sería imposible si las constantes fueran privadas para su implementación o si su implementación fuera un paquete privado o algo así.
Poner miembros estáticos en una interfaz (e implementar esa interfaz) es una mala práctica e incluso hay un nombre para ella, Constant Interface Antipattern , ver Effective Java , Item 17:
El patrón de interfaz constante es un uso deficiente de las interfaces . 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 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, 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, todavía 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 en la interfaz.
Hay varias interfaces constantes en las bibliotecas de la plataforma java, como
java.io.ObjectStreamConstants
. Estas interfaces deben considerarse como anomalías y no deben emularse.
Para evitar algunos inconvenientes de la interfaz constante (porque no se puede evitar que las personas la implementen), 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 ponerles un prefijo con el nombre de 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);
}
}
Son útiles si tiene constantes comunes que se usarán en las clases que implementan la interfaz.
Aquí hay un ejemplo: http://www.javapractices.com/topic/TopicAction.do?Id=32
Pero tenga en cuenta que la práctica recomendada es usar importaciones estáticas en lugar de constantes en las interfaces. Aquí hay una referencia: http://www.javapractices.com/topic/TopicAction.do?Id=195
Utilizo constantes de interfaz cuando trato con constantes compartidas entre clases.
public interface TestConstants
{
String RootLevelConstant1 = "RootLevelConstant1";
interface SubGroup1
{
String SubGroupConstant1 = "SubGroup1Constant1";
String SubGroupConstant2 = "SubGroup1Constant2";
}
interface SubGroup2
{
String SubGroupConstant1 = "SubGroup2Constant1";
String SubGroupConstant2 = "SubGroup2Constant2";
}
}
La agrupación es una gran ventaja, especialmente con un gran conjunto de constantes.
Para usar, simplemente los encadena:
System.out.println(TestConstants.SubGroup1.SubGroupConstant1);
System.out.println(TestConstants.SubGroup2.SubGroupConstant1);
System.out.println(TestConstants.RootLevelConstant1);