Estoy trabajando en una aplicación con muchas constantes. En la última revisión de código, se descubrió que las constantes están demasiado dispersas y que todas deberían organizarse en un único archivo de constantes "maestro". El desacuerdo se trata de cómo organizarlos. La mayoría siente que usar el nombre constante debería ser lo suficientemente bueno, pero esto conducirá a un código similar al siguiente:
public static final String CREDITCARD_ACTION_SUBMITDATA = "6767";
public static final String CREDITCARD_UIFIELDID_CARDHOLDER_NAME = "3959854";
public static final String CREDITCARD_UIFIELDID_EXPIRY_MONTH = "3524";
public static final String CREDITCARD_UIFIELDID_ACCOUNT_ID = "3524";
...
public static final String BANKPAYMENT_UIFIELDID_ACCOUNT_ID = "9987";
Encuentro que este tipo de convención de nombres es engorroso. Pensé que podría ser más fácil usar una clase anidada pública y tener algo como esto:
public class IntegrationSystemConstants
{
public class CreditCard
{
public static final String UI_EXPIRY_MONTH = "3524";
public static final String UI_ACCOUNT_ID = "3524";
...
}
public class BankAccount
{
public static final String UI_ACCOUNT_ID = "9987";
...
}
}
Esta idea no fue bien recibida porque era "demasiado complicada" (no obtuve muchos detalles de por qué esto podría ser demasiado complicado). Creo que esto crea una mejor división entre grupos de constantes relacionadas y el autocompletado también hace que sea más fácil encontrarlos. Sin embargo, nunca he visto esto, así que me pregunto si esta es una práctica aceptada o si hay mejores razones por las que no debería hacerse.
fuente
Respuestas:
No estoy de acuerdo con ninguna de las dos propuestas.
Las constantes deben estar en sus clases pertinentes , no en una clase completamente constante en ninguna de las dos formas propuestas.
No debería haber clases / interfaces solo constantes.
CreditCard
Debe existir una clase (no una clase interna). Esta clase / interfaz tiene métodos relativos a las tarjetas de crédito, así como a las constantesUI_EXPIRY_MONTH
yUI_ACCOUNT_ID
.Debe existir una clase / interfaz
BankAccount
(no una clase interna). Esta clase / interfaz tiene métodos relativos a las cuentas bancarias, así como constantesUI_ACCOUNT_ID
.Por ejemplo, en la API de Java, cada clase / interfaz tiene sus constantes. No están en una clase / interfaz Constantes con cientos de constantes, ya sea agrupadas en clases internas o no.
Por ejemplo, estas constantes pertinentes a los conjuntos de resultados están en la interfaz
ResultSet
:Esta interfaz tiene firmas de método relativas a los conjuntos de resultados, y la implementación de clases implementa ese comportamiento. No son simples titulares constantes.
Estas constantes pertinentes a las acciones de la interfaz de usuario están en la interfaz
javax.swing.Action
:Las clases de implementación tienen un comportamiento relativo a las acciones de la interfaz de usuario, no son simples titulares constantes.
Conozco al menos una interfaz de "constantes" (
SwingConstants
) sin métodos, pero no tiene cientos de constantes, solo unas pocas, y todas están relacionadas con direcciones y posiciones de elementos de la interfaz de usuario:Creo que las clases de constantes solo no son un buen diseño OO.
fuente
Esta es la solución 100% incorrecta al problema de las constantes que son "difíciles de encontrar". Es un error fundamental (desafortunadamente cometido con demasiada frecuencia por los programadores) agrupar cosas por criterios técnicos como ser constantes, enumeraciones o interfaces.
Excepto por las arquitecturas de capa, las cosas deben agruparse por su dominio y sus constantes, ya que son elementos de muy bajo nivel. Las constantes deben ser parte de las clases o interfaces que las usan como parte de su API. Si no puede encontrar un lugar natural para que vivan, debe limpiar su diseño de API.
Además, un solo archivo de constantes enormes mata la velocidad de desarrollo en Java porque las constantes están integradas en las clases que las usan en tiempo de compilación, por lo que cualquier cambio obliga a una recopilación de todos esos archivos y todo lo que depende de ellos. Si tiene un archivo con constantes que se usan en todas partes, pierde en gran medida el beneficio de la compilación incremental: observe el bloqueo de Eclipse durante 15 minutos, ya que recompila todo su proyecto para cada cambio en ese archivo. Y dado que ese archivo contiene todas las constantes utilizadas en cualquier lugar, lo cambiará con bastante frecuencia. Sí, estoy hablando por experiencia personal.
fuente
Tienes razón. Su sugerencia permite que un programador
import static Constants.BankAccount.*
elimine innumerables repeticiones de 'BANKACCOUNT_'. La concatenación es un pobre sustituto del alcance real. Dicho esto, no tengo muchas esperanzas de que cambies la cultura del equipo. Tienen una noción de prácticas adecuadas, y no es probable que cambien incluso si les muestra 100 expertos que dicen que están equivocados.También me pregunto por qué tiene un solo archivo 'Constantes'. Esta es una práctica muy mala, a menos que estas constantes estén relacionadas de alguna manera y sean muy estables. Más típicamente se convierte en una especie de clase de fregadero que cambia constantemente y depende de todo.
fuente
Ambos enfoques funcionan, y eso es lo importante al final del día.
Dicho esto, su enfoque es lo suficientemente común como para ser considerado un patrón, o más exactamente, una mejora lo suficientemente buena sobre el constante anti-patrón de interfaz . No veo lo que es complicado, pero esa es una discusión que debería tener con su equipo.
fuente
Uno de los desafíos con la larga lista de constantes es encontrar la constante "correcta" para usar. Invariablemente, alguien agrega una constante al final de la línea en lugar de agregarla al grupo al que pertenecía.
Lo que trae a colación otro punto para discutir con su equipo: ya existe una categorización de facto de las constantes a través de sus nombres. Por lo tanto, realmente no debería ser un gran cambio para ellos del estado actual a lo que está proponiendo. El uso de autocompletar facilita aún más las búsquedas constantes.
En todo caso, su sugerencia ayuda a desalentar el uso de la constante "incorrecta" a pesar de que podría encajar en una situación particular. Al envolver las constantes dentro de una clase representativa, alentará a los desarrolladores a pensar si deberían usarla. Por ejemplo, si hago
CreditCard.SomeConstant
uso general, me pregunto por qué no hay unaGeneral.SomeConstant
para esa situación.He estado en proyectos con cantidades monstruosas de constantes, y hubiera preferido tener el método que sugieres. Es más limpio, más directo y ayuda a evitar el uso accidental.
fuente
Hago esto ocasionalmente (en C #), particularmente si necesito programar contra / analizar una estructura XML bien conocida y fija o algo anidado de manera similar y una cadena pesada ... por ejemplo, un analizador de bloques de configuración personalizado.
Construyo una estructura de clase anidada que coincide con la estructura jerárquica del XML con los nombres de clase correspondientes a los elementos que contienen una propiedad const string "ElementName" y una propiedad similar correspondiente a cada atributo (si corresponde).
Hace que sea muy fácil programar contra el Xml correspondiente.
fuente