2009-09-17 11 views
7

Durante el análisis de ciertos archivos xml, encuentro una situación en la que tengo que usar la interfaz como etiquetas para identificar que ciertas etiquetas pertenecen a cierta categoría; por ejemplo, creé una interfaz Tag para identificar que estas clases se usan para representar etiquetas xml y ContainableTag para señalar que ciertas etiquetas pueden ser una de las etiquetas secundarias de algunas etiquetas.¿Es la interfaz como etiquetas una mala práctica en Java OO?

Luego me tropiezo con esta página: http://xahlee.org/java-a-day/interface.html (Por favor, busque la sesión "Interface as Labels"). Dice:

La esencia del problema es que es un pedazo de irrelevancia matemático en el idioma. Como mecanismo de etiquetado en un idioma, para la posible beneficio de la ingeniería de software perspectiva, entonces no debería ser diseñado como parte de la interfaz de la clase , ya que el concepto de etiquetado, y el concepto de interfaz de programación , son semánticamente dispares.

¿La interfaz como etiquetas es necesariamente una mala práctica? Como programador de Java, ¿tenemos otras alternativas?

+0

Debe indicar las consultas existentes sobre este tema en SO. También contienen muchas referencias. Sin embargo, fue interesante el artículo interesante que sacaste. – ShiDoiSi

Respuesta

8

Las interfaces como marcadores han sido sustituidas por el mecanismo de anotación en Java 5 o posterior. Le permiten agregar metadatos arbitrarios. Si sus interfaces están vacías y solo sirven para actuar como marcadores de clase, entonces debería usar anotaciones.

+0

Nunca miro los usos de las anotaciones, aunque lo uso en ciertos marcos. Gracias. Voy a google para tutoriales. ¿Podría pasarme algunos enlaces del tutorial de anotaciones si tiene algo a mano? –

+3

http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html El mayor inconveniente en el uso de anotaciones es que necesita anotar sus anotaciones con una retención de 'runtime' si quieres usarlos en tiempo de ejecución. Por defecto, son descartados por el compilador. – Jherico

+0

¡Genial! Muchas gracias. –

5

Las anotaciones no son necesariamente lo que desea. Las interfaces de etiquetado son una forma de trabajar una propiedad de un tipo en el tipo mismo. Por ejemplo, si usted está a punto de empezar a escribir código con este aspecto:

@interface ContainableTag{} 

@ContainableTag public class Foo {} 

// ... elsewhere... 

/** 
* Adds obj as a child element. 
* @throws IllegalArgumentException if obj is not tagged with 
*   the ContainableTag annotation. 
*/ 
public void addElement(Object obj){ 
    if (!obj.getClass().isAnnotationPresent(ContainableTag.class)) 
     throw new IllegalArgumentException("obj is not a ContainableTag"); 
    // add the containable tag as an element 
} 

luego considerar si realmente no cree que esto se ve mejor:

interface ContainableTag {} 

public class Foo implements ContainableTag {} 

// ... elsewhere... 

public void addElement(ContainableTag ct){ 
    // add the containable tag as an element 
} 

Claro, la interfaz de marcado no lo hace proporcione cualquier información sobre qué comportamiento proporciona el tipo en sí, pero hace permite que otros tipos hagan cumplir esta propiedad no relacionada con el comportamiento. Ciertamente me habría ahorrado muchos errores molestos si ObjectOutputStream tuviera un método writeObject(Serializable) en lugar de writeObject(Object).

Editar: Tengo not insignificant support aquí.

+0

Haha .. my "effective" java "es demasiado viejo para tener este artículo. Gracias. –

7

Si bien las anotaciones pueden proporcionar una alternativa para lo que logran las interfaces de marcado, solo están disponibles en Java y no se integran bien con IDEs: también uso interfaces de marcador para etiquetar conceptos relacionados en mi proyecto y puedo usar el escriba el navegador de jerarquía para encontrar todos los miembros (supongo que eventualmente esto será soportado por IDE principales para anotaciones pronto).

En cuanto al artículo que menciona, no veo el punto de argumentar que si una clase "cumple" una interfaz sintácticamente/estructuralmente, esa interfaz puede/debe aplicarse automáticamente a la clase ("Cualquier clase puede declararlo" [RandomAccess] como interfaz ... "). Eso es pensar hacia atrás, en mi opinión.

Yo diría que los lugares, donde una interfaz de estos marcadores se utiliza en una `instanceof' declaración, utilizar la lógica invertida, pero siempre y cuando usted está atascado dentro de un lenguaje sin la herencia múltiple, aspectos y anotaciones, no veo mejor manera de lograr esto sin salir del idioma base.

También tenga en cuenta que este argumento de dead-beat sobre una interfaz vacía siempre aplicable también podría aplicarse a las anotaciones.

+0

Nice points. Gracias. –

Cuestiones relacionadas