J'écris une structure de données spatiales et j'ai un doute sur la meilleure implémentation de NODE. Selon ma conception, j'ai une entité de nœud abstrait et trois classes qui en héritent: EMPTYNODE, FULLNODE, INTERNALNODE.Implémentation de l'héritage conceptuel
Le premier n'a pas de données particulières.
La seconde a 1 référence à un élément générique.
Le troisième a 2 références à d'autres nœuds.
J'ai trouvé plusieurs façons de mettre en œuvre cette situation (que j'ai déjà codé) mais je ne peux pas décider ce qui est le meilleur.
La première solution que j'ai trouvé est d'utiliser un seul nœud de classe qui effectue potentiellement toutes les opérations de cette façon:
private static class Node {
private Elem elem = null;
private Node left = null, right = null;
public Elem getElem() {
assert isFull();
return elem;
}
public boolean isEmpty() {
return elem == null && left == null;
}
public boolean isFull() {
return elem != null;
}
public boolean isInternal() {
return elem == null && left != null;
}
}
La deuxième solution consiste à écrire une division explicite des classes où chaque des offres de classe seulement ses méthodes. De toute évidence, nous sommes obligés d'effectuer plusieurs lancers sur les objets du nœud.
private static abstract class Node {
public abstract boolean isEmpty();
public abstract boolean isFull();
public abstract boolean isInternal();
}
private static class FullNode extends Node{
private ITriangle elem;
@Override
public boolean isEmpty() {
return false;
}
@Override
public final boolean isFull() {
return true;
}
@Override
public final boolean isInternal() {
return false;
}
public Elem getElem() {
return elem;
}
}
La troisième solution est d'utiliser l'héritage permettant à chaque classe d'offrir toutes les méthodes, mais le type d'objet doit par chèque par « isEmpty() » et des méthodes similaires. En cas de mauvais appel, nous allons lancer une exception.
private static abstract class Node {
public abstract boolean isEmpty();
public abstract boolean isFull();
public abstract boolean isInternal();
public abstract Elem getElem();
}
private static class Empty extends Node{
@Override
public boolean isEmpty() {
return true;
}
@Override
public final boolean isFull() {
return false;
}
@Override
public final boolean isInternal() {
return false;
}
@Override
public Elem getElem() {
throw new AssertionError();
}
}
Que pensez-vous de ces trois solutions?
Lequel utiliseriez-vous?
Toutes les idées seront appréciées.
Dans mon cas, ils doivent changer et en fait l'option 1 est la plus efficace (à la fois dans le temps et l'espace) parmi les trois. Merci pour votre aide. – TheSENDER
Je pense à ce problème d'un point de vue théorique. Qu'en est-il de l'utilisation d'un modèle d'état? – TheSENDER
Oui, c'était ce que j'essayais d'exprimer dans mon commentaire sur les nœuds mutables. J'ai ajouté un exemple d'utilisation d'enums pour implémenter le modèle d'état. Le bit qui mute les valeurs et change l'état est manquant car je ne suis pas sûr des changements que vous avez l'intention de permettre – BenM