Est-ce que l'interface en tant qu'étiquettes est une mauvaise pratique en Java OO?

StackOverflow https://stackoverflow.com/questions/1436674

  •  08-07-2019
  •  | 
  •  

Question

Lors de l'analyse de certains fichiers xml, je suis tombé sur une situation où je devais utiliser une interface en tant qu'étiquettes pour identifier certaines balises appartenant à une catégorie. J'ai par exemple créé une interface Balise pour Indiquez que ces classes sont utilisées pour représenter les balises XML et que ContainableTag indique que certaines balises peuvent être l'une des balises enfants de certaines balises.

Ensuite, je tombe sur cette page: http://xahlee.org/java-a -day / interface.html (Recherchez la session " Interface en tant qu'étiquettes "). Il dit:

  

L’essentiel du problème est qu’il est   un morceau de pertinence mathématique dans   la langue. En tant que mécanisme d'étiquetage   dans une langue, pour le possible   bénéficier de l'ingénierie logicielle   perspective, alors il ne devrait pas être   conçu dans le cadre de la classe   Interface, depuis le concept de   étiquetage et concept de programmation   interface, sont sémantiquement disparates.

L’interface en tant qu’étiquette est-elle donc forcément une mauvaise pratique? En tant que programmeur Java, avons-nous d’autres alternatives?

Était-ce utile?

La solution

Les interfaces en tant que marqueurs ont été en grande partie remplacées par le mécanisme d'annotation de Java version 5 ou ultérieure. Ils vous permettent d'ajouter des méta-données arbitraires. Si vos interfaces sont vides et ne servent que de marqueurs de classe, utilisez plutôt des annotations.

Autres conseils

Bien que les annotations puissent offrir une alternative à ce que les interfaces de marqueur accomplissent, elles ne sont disponibles qu'en Java et ne s'intègrent pas bien aux IDE: j'utilise également des interfaces de marqueur pour baliser des concepts liés à mon projet, puis je peux utiliser le type navigateur hiérarchique pour trouver tous les membres (je suppose que cela sera éventuellement supporté par les principaux IDE pour les annotations bientôt).

En ce qui concerne l’article que vous avez mentionné, je ne vois pas l’intérêt de dire que si une classe est syntaxiquement / structurellement "accomplit" " une interface, cette interface peut / devrait être appliquée automatiquement à la classe ("Toute classe peut la déclarer [RandomAccess] comme une interface ..."). C’est une réflexion en arrière, à mon avis.

Je dirais que les endroits, où une telle interface de marqueur est utilisée dans une instruction `instanceof ', utilisent une logique inversée, mais tant que vous êtes coincé dans une langue sans héritage, aspects et annotations multiples, je ne vois pas mieux moyen de le faire sans sortir de la langue de base.

Notez également que cet argument de temps mort relatif à une interface vide toujours applicable peut également être appliqué aux annotations.

Les annotations ne sont pas nécessairement ce que vous voulez. Les interfaces de balisage permettent de transformer une propriété d'un type dans le type lui-même. Par exemple, si vous êtes sur le point de commencer à écrire du code ressemblant à ceci:

@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
}

Ensuite, réfléchissez si cela ne vous va pas mieux, à votre avis:

interface ContainableTag {}

public class Foo implements ContainableTag {}

// ... elsewhere...

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

Bien sûr, l’interface de marquage ne fournit aucune information sur le comportement du type lui-même, mais elle autorise à autoriser d’autres types à appliquer cette propriété non comportementale. On aurait certainement évité beaucoup de bugs ennuyeux si ObjectOutputStream avait une méthode writeObject (Serializable) plutôt que writeObject (Object) .

Modifier: J'ai support non négligeable ici.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top