it-swarm-es.tech

¿Cuál es la mejor manera de implementar constantes en Java?

He visto ejemplos como este:

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

y supuse que podría tener una clase de Constantes para envolver constantes, declarándolas como final estática. No sé prácticamente nada de Java y me pregunto si esta es la mejor manera de crear constantes.

373
mk.

Eso es perfectamente aceptable, probablemente incluso el estándar.

(public/private) static final TYPE NAME = VALUE;

donde TYPE es el tipo, NAME es el nombre en mayúsculas con guiones bajos para espacios, y VALUE es el valor constante;

Recomiendo encarecidamente NO poner sus constantes en sus propias clases o interfaces.

Como nota al margen: las variables que se declaran definitivas y mutables aún se pueden cambiar; sin embargo, la variable nunca puede apuntar a un objeto diferente.

Por ejemplo:

public static final Point Origin = new Point(0,0);

public static void main(String[] args){

    Origin.x = 3;

}

Eso es legal y Origin sería un punto en (3, 0).

403
jjnguy

Yo recomendaría altamente no tener una sola clase de constantes. Puede parecer una buena idea en ese momento, pero cuando los desarrolladores se niegan a documentar constantes y la clase crece hasta abarcar más de 500 constantes que no están relacionadas entre sí (relacionadas con aspectos completamente diferentes de la aplicación), esto Generalmente se convierte en el archivo de constantes siendo completamente ilegible. En lugar:

  • Si tiene acceso a Java 5+, use enumeraciones para definir sus constantes específicas para un área de aplicación. Todas las partes del área de aplicación deben referirse a enumeraciones, no a valores constantes, para estas constantes. Puede declarar una enumeración similar a la forma en que declara una clase. Las enumeraciones son quizás la característica más útil (y, posiblemente, la única) de Java 5+.
  • Si tiene constantes que solo son válidas para una clase en particular o una de sus subclases, declare como protegidas o públicas y colóquelas en la clase superior en la jerarquía. De esta manera, las subclases pueden acceder a estos valores constantes (y si otras clases acceden a ellos a través del público, las constantes no solo son válidas para una clase en particular ... lo que significa que las clases externas que usan esta constante pueden estar demasiado unidas a la clase que contiene la constante)
  • Si tiene una interfaz con un comportamiento definido, pero los valores devueltos o los valores de los argumentos deberían ser particulares, es perfectamente aceptable definir constantes en esa interfaz para que otros implementadores tengan acceso a ellas. Sin embargo, evite crear una interfaz solo para contener constantes: puede volverse tan mala como una clase creada solo para mantener constantes.
235
MetroidFan2002

Es una MALA PRÁCTICA para usar interfaces solo para mantener constantes (llamado patrón de interfaz constante por Josh Bloch). Esto es lo que Josh aconseja:

Si las constantes están fuertemente vinculadas a una clase o interfaz existente, debe agregarlas a la clase o interfaz. Por ejemplo, todas las clases primitivas numéricas en caja, como las constantes Integer y Double, exportan MIN_VALUE y MAX_VALUE. Si las constantes se ven mejor como miembros de un tipo enumerado, debe exportarlos con un enum type. De lo contrario, debería exportar las constantes con una clase de utilidad no institucional.

Ejemplo:

// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
    private PhysicalConstants() { }  // Prevents instantiation

    public static final double AVOGADROS_NUMBER   = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS      = 9.10938188e-31;
}

Acerca de la convención de nombramiento:

Por convención, estos campos tienen nombres que consisten en letras mayúsculas, con palabras separadas por guiones bajos. Es crítico que estos campos contengan valores primitivos o referencias a objetos inmutables.

120
Marcio Aguiar

En Effective Java (2ª edición), se recomienda que utilice enumeraciones en lugar de entradas estáticas para las constantes.

Aquí hay una buena reseña de enums en Java: http://Java.Sun.com/j2se/1.5.0/docs/guide/language/enums.html

Tenga en cuenta que al final de ese artículo la pregunta planteada es:

Entonces, ¿cuándo deberías usar enumeraciones?

Con una respuesta de:

Cada vez que necesites un conjunto fijo de constantes

36
shelfoo

Solo evita usar una interfaz:

public interface MyConstants {
    String CONSTANT_ONE = "foo";
}

public class NeddsConstant implements MyConstants {

}

Es tentador, pero viola la encapsulación y difumina la distinción de las definiciones de clase.

21
stimpy

Yo uso el siguiente enfoque:

public final class Constants {
  public final class File {
    public static final int MIN_ROWS = 1;
    public static final int MAX_ROWS = 1000;

    private File() {}
  }

  public final class DB {
    public static final String name = "oups";

    public final class Connection {
      public static final String URL = "jdbc:tra-ta-ta";
      public static final String USER = "testUser";
      public static final String PASSWORD = "testPassword";

      private Connection() {}
    }

    private DB() {}
  }

  private Constants() {}
}

Que, por ejemplo, uso Constants.DB.Connection.URL para obtener constante. Se ve más "objeto orientado" en cuanto a mí.

19
albus.ua

Crear constantes finales estáticas en una clase separada puede meterte en problemas. El compilador de Java realmente optimizará esto y colocará el valor real de la constante en cualquier clase que lo haga referencia.

Si luego cambia la clase de 'Constantes' y no hace una compilación de otras clases que hacen referencia a esa clase, terminará con una combinación de valores antiguos y nuevos que se están utilizando.

En lugar de pensar en estas como constantes, piense en ellos como parámetros de configuración y cree una clase para administrarlos. Haga que los valores no sean finales, e incluso considere usar captadores. En el futuro, cuando determine que algunos de estos parámetros realmente deberían ser configurables por el usuario o administrador, será mucho más fácil hacerlo.

17
Kevin Day

El error número uno que puede cometer es crear una clase accesible a nivel mundial llamada con un nombre genérico, como Constantes. Esto simplemente se llena de basura y pierdes toda la capacidad de descubrir qué parte de tu sistema usa estas constantes.

En cambio, las constantes deben ir a la clase que las "posee". ¿Tienes una constante llamada TIMEOUT? Probablemente debería ir en su clase de Comunicaciones () o Conexión (). MAX_BAD_LOGINS_PER_HOUR? Entra en Usuario (). Y así sucesivamente y así sucesivamente.

El otro uso posible son los archivos .properties de Java cuando las "constantes" pueden definirse en tiempo de ejecución, pero no son fáciles de cambiar por el usuario. Puede empaquetarlos en su .jars y hacer referencia a ellos con el Class resourceLoader.

13
Yann Ramin

Esa es la manera correcta de ir.

Generalmente las constantes son no se mantienen en clases separadas de "Constantes" porque no son detectables Si la constante es relevante para la clase actual, mantenerla allí ayuda al siguiente desarrollador.

6
Jason Cohen

Estoy de acuerdo en que usar una interfaz no es el camino a seguir. Evitar este patrón incluso tiene su propio elemento (# 18) en Bloch's Effective Java .

Un argumento que Bloch hace contra el patrón de interfaz constante es que el uso de constantes es un detalle de implementación, pero la implementación de una interfaz para usarlas expone ese detalle de implementación en su API exportada.

El patrón public|private static final TYPE NAME = VALUE; es una buena manera de declarar una constante. Personalmente, creo que es mejor evitar hacer una clase separada para albergar todas sus constantes, pero nunca he visto una razón para no hacer esto, aparte de las preferencias personales y el estilo.

Si sus constantes se pueden modelar bien como una enumeración, considere la estructura enum disponible en 1.5 o posterior.

Si está utilizando una versión anterior a la 1.5, aún puede sacar enumeraciones seguras para tipos utilizando las clases normales de Java. (Ver este sitio para más sobre eso).

5
Rob Dickerson

¿Qué pasa con una enumeración?

5
Sébastien D.

Prefiero usar captadores en lugar de constantes. Esos captadores pueden devolver valores constantes, por ejemplo, public int getMaxConnections() {return 10;}, pero cualquier cosa que necesite la constante pasará por un getter.

Una de las ventajas es que si su programa supera la constante (encontrará que debe ser configurable), simplemente puede cambiar la forma en que el obtentor devuelve la constante.

El otro beneficio es que para modificar la constante no tienes que recompilar todo lo que la usa. Cuando hace referencia a un campo final estático, el valor de esa constante se compila en cualquier código de bytes que lo haga referencia.

5
big_peanut_horse

Basado en los comentarios anteriores, creo que este es un buen enfoque para cambiar la clase constante global antigua (que tiene variables finales públicas estáticas) a su equivalente en forma de enumeración de una manera como esta:

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_Host("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

Entonces puedo referirlos a me gusta:

Constants.StringConstant.DB_Host
4
Lorand Bendig

Un buen diseño orientado a objetos no debería necesitar muchas constantes disponibles públicamente. La mayoría de las constantes se deben encapsular en la clase que las necesita para hacer su trabajo.

3
Bradley Harris

Hay una cierta cantidad de opinión para responder a esto. Para empezar, las constantes en Java generalmente se declaran públicas, estáticas y finales. A continuación se presentan las razones:

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

Nunca usaría una interfaz para un objeto/descriptor de acceso CONSTANTES simplemente porque se espera que las interfaces se implementen. ¿No sería esto gracioso?

String myConstant = IMyInterface.CONSTANTX;

En su lugar, elegiría entre algunas formas diferentes, en función de algunas pequeñas compensaciones, y así depende de lo que necesite:

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe
2
djangofan

¿Cuál es la mejor manera de implementar constantes en Java?

Un enfoque que realmente deberíamos evitar: usar interfaces para definir constantes.

Crear una interfaz específicamente para declarar constantes es realmente lo peor: anula la razón por la que se diseñaron las interfaces: la definición de los métodos de contrato.

Incluso si ya existe una interfaz para satisfacer una necesidad específica, declarar las constantes en ellas realmente no tiene sentido, ya que las constantes no deberían formar parte de la API y del contrato proporcionado a las clases de los clientes.


Para simplificar, tenemos en general 4 enfoques válidos.

Con el campo static final String/Integer:

  • 1) usando una clase que declara constantes dentro pero no solo.
  • 1 variante) creando una clase dedicada solo a declarar constantes.

Con Java 5 enum:

  • 2) declarar la enumeración en una clase de propósito relacionado (así como una clase anidada).
  • 2 variante) creando la enumeración como una clase independiente (así definida en su propio archivo de clase).

TLDR: ¿Cuál es la mejor manera y dónde ubicar las constantes?

En la mayoría de los casos, la forma de enumeración es probablemente más fina que la de static final String/Integer y personalmente creo que la forma de static final String/Integer debería usarse solo si tenemos buenas razones para no usar las enumeraciones.
Y sobre dónde debemos declarar los valores constantes, la idea es buscar si hay una sola clase existente que posee una cohesión funcional específica y fuerte con valores constantes. Si encontramos una clase así, debe usarlo como el titular de las constantes. De lo contrario, la constante no debería estar asociada a ninguna clase en particular.


static final String/static final Integer VERSUS enum

Enumeración de uso es realmente una forma de considerar fuertemente.
Las enumeraciones tienen una gran ventaja sobre String o Integer campo constante.
Establecen una restricción de compilación más fuerte. Si define un método que toma la enumeración como parámetro, solo puede pasar un valor de enumeración definido en la clase de enumeración (o nula).
Con String y Integer, puede sustituirlos por cualquier valor de tipo compatible y la compilación estará bien incluso si el valor no es una constante definida en los campos static final String/static final Integer.

Por ejemplo, debajo de dos constantes definidas en una clase como static final String campos:

public class MyClass{

   public static final String ONE_CONSTANT = "value";
   public static final String ANOTHER_CONSTANT = "other value";
   . . .
}

Aquí un método que espera tener una de estas constantes como parámetro:

public void process(String constantExpected){
    ...    
}

Puedes invocarlo de esta manera:

process(MyClass.ONE_CONSTANT);

o

process(MyClass.ANOTHER_CONSTANT);

Pero ninguna restricción de compilación le impide invocarlo de esta manera:

process("a not defined constant value");

Usted tendría el error solo en tiempo de ejecución y solo si hace una verificación del valor transmitido.

Con enum, no se requieren comprobaciones ya que el cliente solo podría pasar un valor de enumeración en un parámetro de enumeración.

Por ejemplo, aquí hay dos valores definidos en una clase de enumeración (tan constante fuera de la caja):

public enum MyEnum {

    ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");

    private String value;

    MyEnum(String value) {
       this.value = value;
    }
         ...
}

Aquí un método que espera tener uno de estos valores de enumeración como parámetro:

public void process(MyEnum myEnum){
    ...    
}

Puedes invocarlo de esta manera:

process(MyEnum.ONE_CONSTANT);

o

process(MyEnum.ANOTHER_CONSTANT);

Pero la compilación nunca te permitirá invocarla de esta manera:

process("a not defined constant value");

¿Dónde debemos declarar las constantes?

Si su aplicación contiene una única clase existente que posee una cohesión funcional fuerte y específica con los valores constantes, el 1) y el 2) parecen más intuitivos.
En general, facilita el uso de las constantes si están declaradas en la clase principal que las manipula o que tiene un nombre muy natural para adivinar que lo encontraremos dentro.

Por ejemplo, en la biblioteca JDK, los valores constantes exponenciales y pi se declaran en una clase que declara no solo declaraciones constantes (Java.lang.Math).

   public final class Math {
          ...
       public static final double E = 2.7182818284590452354;
       public static final double PI = 3.14159265358979323846;
         ...
   }

Los clientes que usan funciones matemáticas a menudo dependen de la clase Math. Por lo tanto, pueden encontrar constantes fácilmente y también pueden recordar dónde se definen E y PI de una manera muy natural.

Si su aplicación no contiene una clase existente que tenga una cohesión funcional muy específica y fuerte con los valores constantes, la variante 1 y la variante 2, las formas parecen más intuitivas.
En general, no facilita el uso de las constantes si están declaradas en una clase que las manipula, mientras que también tenemos 3 o 4 clases que las manipulan tanto como ninguna de estas clases parece ser Más natural que otros para albergar valores constantes.
Aquí, tiene sentido definir una clase personalizada para mantener solo valores constantes.
Por ejemplo, en la biblioteca JDK, la enumeración Java.util.concurrent.TimeUnit no se declara en una clase específica, ya que realmente no hay una y solo una clase específica de JDK que aparece como la más intuitiva para mantenerla:

public enum TimeUnit {
    NANOSECONDS {
      .....
    },
    MICROSECONDS {
      .....
    },
    MILLISECONDS {
      .....
    },
    SECONDS {
      .....
    },
      .....
}      

Muchas clases declaradas en Java.util.concurrent las usan: BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService, ... y realmente ninguna de ellas parece más apropiada para mantener la enumeración.

2
davidxxx

FWIW, un valor de tiempo de espera en segundos probablemente debería ser un ajuste de configuración (leído desde un archivo de propiedades o mediante inyección como en Spring) y no una constante.

1
Tim Howland

Cuál es la diferencia

1.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

2.

public class MyGlobalConstants {
    private MyGlobalConstants () {} // Prevents instantiation
    public static final int TIMEOUT_IN_SECS = 25;
}

y usando MyGlobalConstants.TIMEOUT_IN_SECS donde sea que necesitamos esta constante. Creo que ambos son iguales.

1
chandrayya

Una sola clase de constantes genéricas es una mala idea. Las constantes deben agruparse junto con la clase con la que están más relacionadas lógicamente.

En lugar de usar variables de cualquier tipo (especialmente enumeraciones), sugeriría que use métodos. Cree un método con el mismo nombre que la variable y haga que devuelva el valor que asignó a la variable. Ahora elimine la variable y reemplace todas las referencias a ella con llamadas al método que acaba de crear. Si cree que la constante es lo suficientemente genérica como para no tener que crear una instancia de la clase para usarla, convierta el método de constante en un método de clase.

1
ab

Se puede declarar una constante, de cualquier tipo, creando una propiedad inmutable que dentro de una clase (es decir, una variable miembro con el modificador final). Normalmente, también se proporcionan los modificadores static y public.

public class OfficePrinter {
    public static final String STATE = "Ready";  
}

Existen numerosas aplicaciones en las que el valor de una constante indica una selección de un n-Tuple (por ejemplo, enumeración ) de opciones. En nuestro ejemplo, podemos elegir definir un tipo enumerado que restrinja los posibles valores asignados (es decir, mejorado type-safety ):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}
1
Ryan Delucchi

No llamaría a la clase la misma (aparte de la carcasa) como la constante ... Tendría como mínimo una clase de "Configuración", o "Valores", o "Constantes", donde vivirían todas las constantes. Si tengo un gran número de ellos, los agruparía en clases de constantes lógicas (UserSettings, AppSettings, etc.)

0
Joel Martinez

static final es mi preferencia, solo usaría enum si el artículo fuera enumerable.

0
wulfgarpro

Es MALO hábito y terriblemente ANUNCIANDO la práctica citar a Joshua Bloch sin entender el fundamentalismo básico de cero.

No he leído nada de Joshua Bloch, por lo que tampoco

  • el es un programador terrible
  • o la gente hasta ahora que lo encuentro citando (Joshua es el nombre de un niño que supongo) simplemente están utilizando su material como guiones religiosos para justificar sus indulgencias religiosas de software.

Como en el fundamentalismo bíblico, todas las leyes bíblicas pueden resumirse en

  • Ama la Identidad Fundamental con todo tu corazón y con toda tu mente.
  • Ama a tu prójimo como a ti mismo

y así, el fundamentalismo de la ingeniería de software puede resumirse por

  • dedícate a los fundamentos de cero con toda tu fuerza de programación y mente
  • y dedíquese a la excelencia de sus compañeros programadores como lo haría por usted mismo.

Además, entre los círculos fundamentalistas bíblicos se dibuja un corolario fuerte y razonable.

  • Primero Amate a ti mismo. Porque si no te amas mucho a ti mismo, entonces el concepto "ama a tu prójimo como a ti mismo" no tiene mucho peso, ya que "cuánto te amas a ti mismo" es la línea de referencia por encima de la cual amarías a los demás.

De manera similar, si no se respeta a sí mismo como programador y simplemente acepta los pronunciamientos y profecías de algún guru-nath de programación SIN cuestionar los fundamentos, sus citas y confianza en Joshua Bloch (y cosas por el estilo) no tienen sentido. Y, por lo tanto, no tendrías ningún respeto por tus compañeros programadores.

Las leyes fundamentales de la programación de software.

  • la pereza es la virtud de un buen programador.
  • usted debe hacer que su vida de programación sea tan fácil, perezosa y, por lo tanto, lo más efectiva posible.
  • debe hacer que las consecuencias y las entrañas de su programación sean tan fáciles, perezosas y, por lo tanto, lo más eficaces posible para sus programadores vecinos que trabajan con usted y recogen sus entrañas de programación.

¿Las constantes de patrón de interfaz son un mal hábito?

¿Bajo qué leyes de programación fundamentalmente efectiva y responsable se encuentra este decreto religioso?

Simplemente lea el artículo de wikipedia sobre constantes de patrón de interfaz ( https://en.wikipedia.org/wiki/Constant_interface ), y las excusas tontas que dice contra las constantes de patrón de interfaz.

  • Whatif-No IDE? ¿Quién en la tierra como programador de software no usaría un IDE? La mayoría de nosotros somos programadores que preferimos no tener que probar tener el supervivencia aistético y el uso de un IDE.

    • Además, espere a un segundo defensor de la programación micro-funcional como un medio para no necesitar un IDE. Espere a que lea mi explicación sobre la normalización del modelo de datos.
  • ¿Contamina el espacio de nombres con variables no utilizadas dentro del alcance actual? Podría ser partidario de esta opinión.

    • no son conscientes de, y la necesidad de, la normalización del modelo de datos
  • Usar interfaces para hacer cumplir constantes es un abuso de interfaces. Los defensores de los mismos tienen un mal hábito de

    • no ver que las "constantes" deben ser tratadas como un contrato. Y las interfaces se utilizan para hacer cumplir o proyectar el cumplimiento de un contrato.
  • Es difícil, si no imposible, convertir las interfaces en clases implementadas en el futuro. Hah .... hmmm ... ???

    • ¿Por qué querría participar en un patrón de programación como su modo de vida persistente? IOW, ¿por qué dedicarse a tal AMBIVALENTE y mala costumbre de programación?

Cualquiera que sean las excusas, no hay ninguna excusa válida cuando se trata de una ingeniería de software FUNDAMENTALMENTE EFECTIVA para deslegitimar o, en general, desalentar el uso de constantes de interfaz.

No importa cuáles fueron los intentos originales y los estados mentales de los padres fundadores que elaboraron la Constitución de los Estados Unidos. Podríamos debatir las intenciones originales de los padres fundadores, pero todo lo que me importa son las declaraciones escritas de la Constitución de los Estados Unidos. Y es responsabilidad de cada ciudadano de los Estados Unidos explotar el fundamentalismo literario escrito, no los intentos de fundación no escritos, de la Constitución de los Estados Unidos.

Del mismo modo, no me importa lo que los intenciones "originales" de los fundadores de la plataforma Java y el lenguaje de programación tenían para la interfaz. Lo que me importa son las características efectivas que proporciona la especificación de Java, y tengo la intención de aprovechar esas características al máximo para ayudarme a cumplir las leyes fundamentales de la programación responsable de software. No me importa si se percibe que "violan la intención de las interfaces". No me importa lo que Gosling o alguien a quien Bloch diga sobre la "forma correcta de usar Java", a menos que lo que digan no viole mi necesidad de EFECTIVO cumplir los fundamentos.

Lo fundamental es la normalización del modelo de datos.

No importa cómo se aloje o transmita su modelo de datos. Ya sea que use interfaces o enums o whatevernots, relacionales o no-SQL, si no entiende la necesidad y el proceso de la normalización del modelo de datos.

Primero debemos definir y normalizar el modelo de datos de un conjunto de procesos. Y cuando tenemos un modelo de datos coherente, SOLAMENTE podemos usar el flujo de proceso de sus componentes para definir el comportamiento funcional y el proceso bloquea un campo o ámbito de aplicaciones. Y solo así podremos definir la API de cada proceso funcional.

Incluso las facetas de la normalización de datos según lo propuesto por EF Codd ahora se enfrentan a un desafío severo y a un desafío severo. p.ej. Su declaración sobre 1NF ha sido criticada por ambigua, desalineada y sobre simplificada, al igual que el resto de sus declaraciones, especialmente en el advenimiento de los servicios de datos modernos, la tecnología de repo y la transmisión. En mi opinión, las declaraciones de EF Codd se deben abandonar por completo y se debe diseñar un nuevo conjunto de declaraciones más matemáticamente plausibles.

Un defecto evidente de EF Codd's y la causa de su desalineación con respecto a la comprensión humana efectiva es su creencia de que los datos multidimensionales y de dimensiones mutables perceptibles por los seres humanos pueden percibirse de manera eficiente a través de un conjunto de mapeos bidimensionales poco sistemáticos.

Los fundamentos de la normalización de datos

Lo que EF Codd no pudo expresar.

Dentro de cada modelo de datos coherente, estos son el orden graduado secuencial de la coherencia del modelo de datos a alcanzar.

  1. La Unidad e Identidad de las instancias de datos.
    • diseñar la granularidad de cada componente de datos, por lo que su granularidad se encuentra en un nivel en el que cada instancia de un componente se puede identificar y recuperar de forma única.
    • ausencia de alias de instancia. es decir, no existe ningún medio por el cual una identificación produzca más de una instancia de un componente.
  2. Ausencia de interferencia de instancia. No existe la necesidad de utilizar una o más instancias de un componente para contribuir a identificar una instancia de un componente.
  3. La unidad e identidad de los componentes de datos/dimensiones.
    • Presencia de desalineación de componentes. Debe existir una definición por la cual un componente/dimensión puede ser identificado de manera única. Cuál es la definición primaria de un componente;
    • donde la definición principal no dará lugar a la exposición de subdimensiones o componentes de miembros que no forman parte de un componente previsto;
  4. Medios únicos de distribución de componentes. Debe existir una, y solo una, la definición de desaleamiento de un componente para un componente.
  5. Existe una, y solo una, interfaz de definición o contrato para identificar un componente principal en una relación jerárquica de componentes.
  6. Ausencia de interferencia de componentes. No existe la necesidad de utilizar un miembro de otro componente para contribuir a la identificación definitiva de un componente.
    • En tal relación padre-hijo, la definición de identificación de un padre no debe depender de parte del conjunto de componentes miembros de un hijo. Un componente miembro de la identidad de un padre debe ser la identidad infantil completa sin tener que recurrir a hacer referencia a alguno o todos los hijos de un niño.
  7. Apariciones bimodales o multimodales de un modelo de datos.
    • Cuando existen dos definiciones candidatas de un componente, es una señal obvia de que existen dos modelos de datos diferentes que se mezclan como uno solo. Eso significa que hay incoherencia en el nivel del modelo de datos, o el nivel de campo.
    • Un campo de aplicaciones debe usar uno y solo un modelo de datos, de manera coherente.
  8. Detectar e identificar mutaciones de componentes. A menos que haya realizado un análisis estadístico de componentes de datos enormes, probablemente no vea, o vea la necesidad de tratar, la mutación de componentes.
    • Un modelo de datos puede tener algunos de sus componentes mutados cíclicamente o gradualmente.
    • El modo puede ser rotación de miembros o transposición-rotación.
    • La mutación de rotación de miembros podría ser un intercambio distinto de componentes secundarios entre componentes. O donde tendrían que definirse componentes completamente nuevos.
    • La mutación transposicional se manifestaría como un miembro dimensional que muta en un atributo, y viceversa.
    • Cada ciclo de mutación debe identificarse como un modo de datos distinto.
  9. Versionizar cada mutación. De modo que puede extraer una versión anterior del modelo de datos, cuando quizás surja la necesidad de tratar una mutación de 8 años del modelo de datos.

En un campo o cuadrícula de aplicaciones de componentes de interconexión, debe haber uno y solo un modelo de datos coherente o debe existir un medio para que un modelo/versión de datos se identifique.

¿Seguimos preguntando si podríamos usar Constantes de Interfaz? De Verdad ?

Hay problemas de normalización de datos en juego más consecuentes que esta pregunta mundana. Si no resuelve esos problemas, la confusión que cree que causan las constantes de interfaz es comparativamente nada. Zilch.

A partir de la normalización del modelo de datos, se determinan los componentes como variables, como propiedades, como constantes de interfaz de contrato.

Luego, usted determina cuál va en la inyección de valor, la posición de la configuración de propiedades, las interfaces, las cadenas finales, etc.

Si tiene que usar la excusa de tener que localizar un componente más fácil de dictar contra las constantes de interfaz, significa que tiene la mala costumbre de no practicar la normalización del modelo de datos.

Quizás desee compilar el modelo de datos en una versión vcs. Que puede extraer una versión claramente identificable de un modelo de datos.

Se garantiza completamente que los valores definidos en las interfaces no son mutables. Y compartibles. ¿Por qué cargar un conjunto de cadenas finales en su clase de otra clase cuando todo lo que necesita es ese conjunto de constantes?

Entonces, ¿por qué no esto para publicar un contrato de modelo de datos? Quiero decir que si puedes manejarlo y normalizarlo coherentemente, ¿por qué no? ...

public interface CustomerService {
  public interface Label{
    char AssignmentCharacter = ':';
    public interface Address{
      String Street = "Street";
      String Unit= "Unit/Suite";
      String Municipal = "City";
      String County = "County";
      String Provincial = "State";
      String PostalCode = "Zip"
    }

    public interface Person {
      public interface NameParts{
        String Given = "First/Given name"
        String Auxiliary = "Middle initial"
        String Family = "Last name"
      }
    }
  }
}

Ahora puedo hacer referencia a las etiquetas contratadas de mis aplicaciones de una manera tal como

CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family

¿Esto confunde los contenidos del archivo jar? Como programador de Java no me importa la estructura del tarro.

¿Esto presenta complejidad al intercambio en tiempo de ejecución motivado por osgi? Osgi es un medio extremadamente eficiente para permitir que los programadores continúen con sus malos hábitos. Hay mejores alternativas que osgi.

¿O por qué no esto? No hay fugas de las constantes privadas en el contrato publicado. Todas las constantes privadas deben agruparse en una interfaz privada llamada "Constantes", porque no quiero tener que buscar constantes y soy demasiado vago para escribir repetidamente "Cadena final privada".

public class PurchaseRequest {
  private interface Constants{
    String INTERESTINGName = "Interesting Name";
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Quizás incluso esto:

public interface PurchaseOrderConstants {
  public interface Properties{
    default String InterestingName(){
       return something();
    }
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

El único problema con las constantes de interfaz que vale la pena considerar es cuando se implementa la interfaz.

Esta no es la "intención original" de las interfaces? Como si me importara la "intención original" de los padres fundadores en la elaboración de la Constitución de los Estados Unidos, en lugar de cómo interpretaría el Tribunal Supremo las cartas escritas de la Constitución de los Estados Unidos.

Después de todo, vivo en la tierra de los libres, los salvajes y el hogar de los valientes. Sea valiente, sea libre, sea salvaje, use la interfaz. Si mis compañeros programadores se niegan a usar medios de programación eficientes y perezosos, ¿estoy obligado por la regla de oro a disminuir mi eficiencia de programación para alinearse con la suya? Tal vez debería, pero esa no es una situación ideal.

0
Blessed Geek

Para ir un paso más allá, puede colocar constantes utilizadas globalmente en una interfaz para que puedan usarse en todo el sistema. P.ej.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

Pero no lo pongas en práctica. Simplemente refiérase a ellos directamente en el código a través del nombre de clase completo.

0
Andrew Harmel-Law

Uso static final para declarar constantes e ir con la notación de denominación ALL_CAPS. He visto bastantes casos de la vida real donde todas las constantes se agrupan en una interfaz. Algunas publicaciones han llamado, con razón, una mala práctica, principalmente porque no es para eso que es una interfaz. Una interfaz debe hacer cumplir un contrato y no debe ser un lugar para colocar constantes no relacionadas. Reunirlo en una clase que no puede ser instanciada (a través de un constructor privado) también está bien si la semántica constante no pertenece a una clase específica ( es). Siempre pongo una constante en la clase con la que está más relacionado, porque eso tiene sentido y también es fácil de mantener.

Las enumeraciones son una buena opción para representar un rango de valores, pero si está almacenando constantes independientes con un énfasis en el valor absoluto (por ejemplo, TIMEOUT = 100 ms), puede optar por el enfoque static final.

0
bincob

Para Constantes, Enum es una mejor opción en mi humilde opinión. Aquí hay un ejemplo

clase pública myClass {

public enum myEnum {
    Option1("String1", 2), 
    Option2("String2", 2) 
    ;
    String str;
            int i;

            myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }


}
0
mmansoor

Estoy de acuerdo con lo que la mayoría dice, es mejor usar enumeraciones cuando se trata de una colección de constantes. Sin embargo, si está programando en Android, hay una solución mejor: IntDef Annotation .

@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();

La anotación IntDef es superior a las enumeraciones de una manera simple, ocupa mucho menos espacio, ya que es simplemente un marcador de tiempo de compilación. No es una clase, ni tiene la propiedad de conversión automática de cadenas.

0
Quinn Turner

Una de las formas en que lo hago es creando una clase 'Global' con valores constantes y realizando una importación estática en las clases que necesitan acceso a la constante.

0
Javamann