Considérez une situation où une classe implémente le même comportement de base, les mêmes méthodes, et cetera, mais plusieurs versions différentes de cette classe peuvent exister pour différentes utilisations. Dans mon cas particulier, j'ai un vecteur (un vecteur géométrique, pas une liste) et ce vecteur pourrait s'appliquer à n'importe quel espace euclidien à N dimensions (1 dimension, 2 dimensions, ...). Comment définir cette classe / type?
Ce serait facile en C ++ où les modèles de classe peuvent avoir des valeurs réelles comme paramètres, mais nous n'avons pas ce luxe en Java.
Les deux approches auxquelles je peux penser qui pourraient être adoptées pour résoudre ce problème sont les suivantes:
Avoir une implémentation de chaque cas possible au moment de la compilation.
public interface Vector { public double magnitude(); } public class Vector1 implements Vector { public final double x; public Vector1(double x) { this.x = x; } @Override public double magnitude() { return x; } public double getX() { return x; } } public class Vector2 implements Vector { public final double x, y; public Vector2(double x, double y) { this.x = x; this.y = y; } @Override public double magnitude() { return Math.sqrt(x * x + y * y); } public double getX() { return x; } public double getY() { return y; } }
Cette solution est évidemment très longue et extrêmement fastidieuse à coder. Dans cet exemple, cela ne semble pas trop mauvais, mais dans mon code actuel, je traite avec des vecteurs qui ont plusieurs implémentations chacun, avec jusqu'à quatre dimensions (x, y, z et w). J'ai actuellement plus de 2000 lignes de code, même si chaque vecteur n'a vraiment besoin que de 500.
Spécification des paramètres lors de l'exécution.
public class Vector { private final double[] components; public Vector(double[] components) { this.components = components; } public int dimensions() { return components.length; } public double magnitude() { double sum = 0; for (double component : components) { sum += component * component; } return Math.sqrt(sum); } public double getComponent(int index) { return components[index]; } }
Malheureusement, cette solution nuit aux performances du code, entraîne un code plus désordonné que l'ancienne solution et n'est pas aussi sûre au moment de la compilation (il ne peut pas être garanti au moment de la compilation que le vecteur avec lequel vous traitez est en réalité bidimensionnel, par exemple).
Je suis actuellement en train de développer dans Xtend, donc si des solutions Xtend sont disponibles, elles seraient également acceptables.