Pregunta

Durante el análisis de ciertos archivos xml, me encuentro con 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 Etiqueta para identifique 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.

Luego me encuentro con esta página: http://xahlee.org/java-a -day / interface.html (Busque la sesión " Interfaz como etiquetas "). Dice:

  

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

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

¿Fue útil?

Solución

Las interfaces como marcadores han sido reemplazadas en gran medida 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 en su lugar.

Otros consejos

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

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

Yo diría que los lugares, donde se usa dicha interfaz de marcador en una declaración de 'instancia de', usan lógica invertida, pero mientras esté atrapado dentro de un lenguaje sin herencia, aspectos y anotaciones múltiples, no veo nada mejor manera de lograr esto sin salir del lenguaje base.

También tenga en cuenta que este argumento irreal sobre una interfaz vacía que siempre es aplicable también podría aplicarse a las anotaciones.

Las anotaciones no son necesariamente lo que quieres. Las interfaces de etiquetado son una forma de trabajar una propiedad de un tipo en el tipo mismo. Por ejemplo, si está a punto de comenzar 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
}

Entonces considera si realmente no crees que esto se vea 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 etiquetado no proporciona información sobre qué comportamiento proporciona el tipo en sí, pero permite que otros tipos impongan esta propiedad de no comportamiento. Sin duda, me habría ahorrado muchos errores molestos si ObjectOutputStream tuviera un método writeObject (Serializable) en lugar de writeObject (Object) .

Editar: Tengo soporte no insignificante aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top