2010-01-14 37 views
6

Hoy me miraba la clase ZipEntry y encontró lo siguiente:¿Debería una clase implementar una interfaz de solo constantes?

public class ZipEntry implements ZipConstants, Cloneable 

ZipConstants no define ningún método - únicas constantes (static final int LOCHDR = 30)

Se me ocurrió entonces que la implementación de la interfaz con constantes le permite acceda a esas constantes directamente, como si estuvieran definidas en la clase misma. Por ejemplo:

public interface Constants { 
    static final int CONST = 2; 
} 

public class implements Constants { 
    int doSomething(int input) { 
     return CONST * input; 
    } 
} 

¿Existe otra razón para no usar esto, aparte de:

  • está en un primer momento confuso donde la constante proviene de
  • se considera incorrecto utilizar las interfaces de constantes definición

Tengo curiosidad porque definitivamente no es una práctica muy común.

Respuesta

16

Otras razones para no utilizar esto:

Desde Java 5, hay una característica "limpia" lenguaje que logra el mismo objetivo: static imports.

La implementación de interfaces para usar constantes es básicamente un truco anterior a Java-5 para simular importaciones estáticas.

+0

(+1), no lo está simulando por completo, porque no funciona para las importaciones estáticas de los métodos – Bozho

+0

En realidad, también hay una lógica circular en este argumento. No heredamos clases constantes solamente porque puede usar importaciones estáticas. ¿Pero por qué deberíamos usar importaciones estáticas dado que podemos heredar la interfaz? Incluso llamarlo un "truco" sin decir por qué se considera un "truco" es como repetir el mantra del "estilo malo". –

+0

La diferencia es que las importaciones estáticas son una característica del lenguaje introducida específicamente para permitir esto, mientras que el propósito de las interfaces es bastante diferente; por lo tanto, usar una interfaz como esta es un truco; Pensé que era evidente. –

2

... porque se considera incorrecto utilizar las interfaces para las constantes definición

Esta es una mala razón para no hacer algo. De hecho, no es una razón en absoluto.

EDITAR

considerar esto.

  • La razón por la que XXX es malo es YYY.
  • La razón por la que debes hacer XXX es que es un mal estilo.

¿Cuántas razones sustanciales existen para no hacer XXX? ¿Uno o dos?

Si la respuesta es dos, puedo hacer que sea tres, cuatro, cinco y así sucesivamente agregando cadenas de razones extra tenues. Por ejemplo, "La razón por la que no debes hacer XXX es porque es una mala idea". "Las razones por las que es una mala idea es que es un mal estilo". Y así. Eso es claramente tonto.

No real razón por la que no se hace XXX es YYY, y el motivo de "mal estilo" no es un motivo de peso. Más bien, es un atajo para decir que no hagas XXX debido a YYY y ZZZ, y cualquier otra razón de fondo.

De hecho, incluso el motivo "es confuso" del OP está incompletamente indicado. ¿POR QUÉ es confuso?

Porque una interfaz es normalmente un tipo con clases que implementan la interfaz son subtipo. Pero una interfaz única constante no es un tipo en ningún sentido útil, y las clases que implementan la interfaz no son subtipos en ningún sentido útil. En definitiva, esta es la verdadera razón por la que la implementación de interfaces de solo-constancia se denomina estilo incorrecto y "antipatrón", y es la razón principal por la que las importaciones estáticas se agregaron en Java 5.

+0

, ya que es una cuestión de estilo de código de todos modos, tener una razón de estilo de código para otro asunto de estilo de código no es tan extraño. – Bozho

3

No es tan raro como se podría pensar, por ejemplo en el análisis estático de Parasofts JTest, tanto la regla de que las constantes deben declararse en un class como la regla de que las constantes deben declararse en interface s están presentes, y le corresponde al proyecto elegir entre ellas.

Dicho esto, en todos mis proyectos no se permite la práctica de definir constantes en las interfaces. Crear una clase significativa y ser explícito sobre el contexto de una constante hace que el código sea mucho más legible y mantenible que en el caso donde un desarrollador tiene que verificar que las constantes usadas en una clase sean en realidad las mismas en otra clase (o no).)

0

No, esto también se conoce como el "Antipatín de interfaz constante". Una alternativa es escribir una clase concreta que defina las constantes y luego use la importación estática.

Clase Constantes

package util; 

public class Constants { 
    public static final String CONSTANT_STRING = "abc"; 

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

clase Test

import static util.Constants.CONSTANT_STRING; 

public class Test { 
    System.out.println(CONSTANT_STRING); 
} 

Ver

Wikipedia

para más detalles.

+0

Soy consciente de cuáles son las importaciones estáticas;) – Bozho

0

Una de las razones para no poner sus constantes en su interfaz es que si expone su interfaz a un tercero tienen acceso a sus constantes. Puede que no parezca una mala idea comenzar, pero imagina si quieres cambiar el valor de una constante, pero las personas siguen usando una interfaz anterior.

Cuando agrega algo a una interfaz, tiene el potencial de ser grabado en piedra por lo que solo agregue lo que desea que otros vean y usen.

2

creo que el uso de una interfaz para las constantes compartidos es un ejemplo de confundir dos conceptos diferentes:

  1. la reutilización de código
  2. Subtipificación

En mi experiencia en el uso de subclases, o interfaz de la aplicación, simplemente para evitar la duplicación de código conduce a problemas. Tu código se vuelve más frágil. Por ejemplo, alguien podría redefinir accidentalmente la constante, especialmente si su jerarquía de clases tiene varias clases de profundidad.

A menudo es mejor usar la composición para mantener su código SECO.

Otro problema con el uso de herencia de esta manera es que generalmente este tipo de herencia forma parte de la API de su clase. La jerarquía de la clase es visible fuera de la clase. Esto rompe la encapsulación.No es necesario que expongas tu uso de las constantes fuera de la clase, tienen que ver con cómo has elegido implementar tu clase y no son parte de su API (en tu ejemplo).

Esto puede provocar problemas de compatibilidad con versiones anteriores. Otra persona podría venir y escribir código como este:

public interface Constants { 
    static final int CONST = 2; 
} 

public class MyClass implements Constants { 
    int doSomething(int input) { 
    return CONST * input; 
    } 
} 

public class ThirdPartyClass { 
    int doSomethingElse(int input) { 
    return MyClass.CONST + input; 
    } 
} 

Ahora, si usted decide que ya no necesita utilizar CONST en MiClase está atascado. Porque ThirdPartyClass ha creado una dependencia en CONST estando disponible en MyClass.

Puede terminar con esto. Donde MyClass no está utilizando ninguna de las constantes en la interfaz, pero aún tiene que implementarlo.

public interface Constants { 
    static final int CONST = 2; 
} 

public class MyClass implements Constants { 
    int doSomething(int input) { 
    return input; 
    } 
} 

public class ThirdPartyClass { 
    int doSomethingElse(int input) { 
    return MyClass.CONST + input; 
    } 
} 

En resumen; nunca hagas esto!

+0

No tenía la intención de hacerlo, solo tenía curiosidad por qué se ha hecho en una API proporcionada por el sol – Bozho

+0

¿Inexperiencia tal vez? Lo hice en el pasado, antes de darme cuenta del tipo de problemas que puede causar. O tal vez se decidió hace mucho tiempo como una convención de código, y ahora los desarrolladores en el sol sienten que están atascados siguiéndolo? Supongo que ... – lexicalscope

Cuestiones relacionadas