Poner miembros estáticos en una interfaz (e implementar esa interfaz) es una mala práctica e incluso hay un nombre para ello, el Antipattern de Interfaz Constante , vea Java efectivo , artículo 17:
El patrón de interfaz constante es un mal uso 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 importancia 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 se modifica la clase para que ya no necesite usar las constantes, aún debe implementar la interfaz para asegurar 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 anomalías y no deben emularse.
Para evitar algunos errores de la interfaz constante (porque no 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 prefijarlas con 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);
}
}
Quien elaboró esta hipótesis, por muy gurú que sea, la inventó sobre la base de la necesidad de seguir implementando los malos hábitos y prácticas de manera eficiente. La hipótesis se basa en la promoción de la validez de malos hábitos de diseño de software.
Escribí una respuesta para refutar 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 había permanecido abierta, hasta que se cerró dentro de 2 horas después de que publiqué mis razones desjustificando esta hipótesis, exponiendo así la DESQUERIDA para el debate de aquellos que se aferran a esta hipótesis equivocada.
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 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 luego, ¿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 para discriminar e incriminar estilos de vida más efectivos?
El tema 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 de negocio, antes de diseñar o complementar soluciones al proceso. Este método de organización de la información se denominó normalización de datos hace algunas décadas.
Entonces, solo la ingeniería de una solución será posible 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 "normalización" del 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 disfraza de ingeniería ágil es la noción equivocada de que no se debe planificar y condicionar la organización de los módulos con anticipación porque se puede refactorizar sobre la marcha. La refactorización y el cambio continuo sin verse obstaculizados por futuros descubrimientos se utilizan 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 puesta en activo, por lo que el conocimiento esencial y su tratamiento no se considera necesario ahora.
El uso de constantes de interfaz es una buena práctica.
No invente reglas ni emita ninguna fatwa en su contra solo porque ama sus hábitos de programación ad-hoc.
No prohíba la posesión de armas por el motivo de que hay personas que no saben cómo manejarlas o que son propensas a abusar de ellas.
Si las reglas que inventa están destinadas a principiantes de programación que no pueden codificar profesionalmente y que usted se cuenta entre ellos, dígalo, no declare su fatwa como aplicable a modelos de datos normalizados correctamente.
Un razonamiento tonto - ¿Los problemas del lenguaje Java no pretendían que las interfaces se usaran de esa manera?
No me importa cuáles fueron las intenciones originales de los padres fundadores para la Constitución de Estados Unidos. No me importan las intenciones no codificadas no escritas. Solo me importa lo que está codificado literariamente en la Constitución escrita y cómo puedo explotarlos para el funcionamiento efectivo de la sociedad.
Solo me importa lo que me permitan las especificaciones del lenguaje / plataforma Java y tengo la intención de 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 las constantes 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 proporcionaran la asignación de valores de parámetros sin que usted escribiera ese código de asignación demuestra que las constantes de Enum son un uso no intencionado del lenguaje Java.
Sobre todo porque no se le anima a normalizar y componenteizar 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 contrato API
No olvides eso. Si diseñó y normalizó su modelo de datos, y estos incluyen constantes, esas constantes son contratos. Si no normalizó su modelo de datos, entonces debe ajustarse a 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 Constants.
Una presunción extraña: ¿qué pasa si la interfaz se implementa inadvertidamente?
Sip. Cualquiera podría implementar inadvertidamente cualquier interfaz sin darse cuenta. Nada se interpondrá en el camino de estos programadores inadvertidos.
Diseñe y normalice su modelo de datos contra fugas
No coloque decretos restrictivos para proteger las presuntas malas prácticas que causan la filtración de parámetros no contratados / perdidos en la API. Resuelva el problema fundamental, en lugar de culpar a las constantes de interfaz.
No usar un IDE es una mala práctica
Un programador EFECTIVO y de funcionamiento normal no está allí para demostrar cuánto tiempo puede permanecer bajo el agua, qué tan lejos podría caminar en un calor abrasador o tormentas eléctricas húmedas. Ella debe usar una herramienta eficiente como un automóvil o autobús o al menos una bicicleta para llevar sus 10 millas al trabajo todos los días.
No imponga restricciones a los compañeros programadores solo porque tiene una obsesión de 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 malos hábitos de manera eficiente.
OSGI es un marco de este tipo. Y también lo es el decreto contra las Constantes de Interfaz.
Por tanto, la respuesta concluyente ...
Las constantes de interfaz son una forma eficaz y eficiente de colocar en el contrato componentes bien diseñados y normalizados 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 sus constantes privadas en lugar de dispersarlas por todo el archivo.
fuente
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 más.
¿Por qué utilizar Interface Constant?
Simplemente compárelos:
vs
Mismo uso. Mucho menos código.
¿Mala práctica?
Creo que la respuesta de @Pascal Thivent tiene un énfasis incorrecto, aquí está mi versión:
La cita de Effective Java asume que la interfaz constante está siendo implementada por otros, lo que creo que no debería (y no sucederá) suceder.
Cuando crea una interfaz constante llamada algo así
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 no verá ninguno allí.
Sin embargo , para los proyectos diarias de los desarrolladores normales, utilizando la interfaz de constantes es mucho más fácil porque usted no necesita preocuparse de
static
,final
,empty constructor
, etc, y que no causa ningún problema de diseño malo. El único inconveniente que se me ocurre es que todavía tiene el nombre de "interfaz", pero nada más que eso.Debate sin fin
Al final, creo que todos están citando libros y dando opiniones y justificaciones a sus posiciones. No es una excepción para mí. Quizás la decisión aún dependa de los desarrolladores de cada proyecto. Siga adelante para usarlo si se siente cómodo. Lo mejor que podemos hacer es que sea coherente durante todo el proyecto .
fuente
public
también se puede omitir ya que es una interfaz, por lo que simplemente ¡Eldouble PI = 3.14159;
uso deConstants.PI
no necesita que la clase lo use para implementar laConstants
interfaz! Creo que el enfoque de la interfaz es mucho más limpio en términos de uso, en mi humilde opiniónJoshua Bloch, "Eficaz Java - Guía del lenguaje de programación":
fuente
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 utilizar importaciones estáticas en lugar de constantes en las interfaces. Aquí hay una referencia: http://www.javapractices.com/topic/TopicAction.do?Id=195
fuente
Hay respuestas que son muy razonables.
Pero tengo algunas ideas sobre esta pregunta. (puede estar mal)
En mi opinión, los campos en una interfaz, no deben ser constantes para todo el proyecto, son solo medios para la interfaz y las interfaces la extienden y las clases que implementan estas interfaces o tienen una relación cercana con ellas. Deben usarse dentro de un rango determinado, no global.
fuente
Dos puntos sobre la interfaz:
Una interfaz describe un subconjunto de lo que puede hacer un objeto que lo implementa. (Esta es la intuición)
Una interfaz describe constantes comunes seguidas de objetos que la implementan.
Entonces creo que si interfaz de constantes no se usa para constantes globales , entonces es aceptable:
implements
eso (y, por supuesto, use estas constantes comunes en la implementación).Ejemplo:
En este ejemplo:
Circle implements Drawable
, inmediatamente se sabe queCircle
probablemente se ajusta a las constantes definidas enDrawable
, de lo contrario tienen que elegir un nombre peor que los buenosPI
yGOLDEN_RATIO
ya se ha tomado!Drawable
objetos se ajustan a lo específicoPI
yGOLDEN_RATIO
definido enDrawable
, puede haber objetos que noDrawable
tengan diferente precisión de pi y proporción áurea.fuente
La
javax.swing.SwingConstants
interfaz es un ejemplo que tiene campos estáticos que se utilizan entre las clases de swing. Esto le permite usar fácilmente algo comothis.add(LINE_START, swingcomponent);
this.add(this.LINE_START, swingcomponent);
othis.add(SwingComponents.LINE_START, swingcomponent);
Sin embargo, esta interfaz no tiene métodos ...
fuente
Me encontré con esta pregunta y pensé en agregar algo que no se mencionó. En general, estoy de acuerdo con la respuesta de Pascal aquí . Sin embargo, no creo que las constantes en una interfaz sean "siempre" un antipatrón.
Por ejemplo, si las constantes que está definiendo son parte de un contrato para esa interfaz, creo que la interfaz es un gran lugar para las constantes. En algunos casos, simplemente no es apropiado validar de forma privada sus parámetros sin exponer el contrato a los usuarios de su implementación. Sin un contrato de cara al público, los usuarios solo pueden adivinar con qué está validando, salvo 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), entonces un usuario de su clase puede estar seguro de que está usando la instancia de la interfaz correctamente al verificar 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í.
fuente
Utilizo constantes de interfaz cuando trato con constantes compartidas entre clases.
La agrupación es un gran activo, especialmente con un gran conjunto de constantes.
Para usarlos, simplemente encadénelos:
fuente
Fuente: Estilo de codificación de las herramientas de desarrollo de Java
fuente