Considera una situazione in cui una classe implementa lo stesso comportamento di base, metodi, eccetera, ma potrebbero esistere più versioni diverse di quella classe per usi diversi. Nel mio caso particolare, ho un vettore (un vettore geometrico, non un elenco) e quel vettore potrebbe applicarsi a qualsiasi spazio euclideo N-dimensionale (1 dimensionale, 2 dimensionale, ...). Come può essere definita questa classe / tipo?
Ciò sarebbe facile in C ++ in cui i modelli di classe possono avere valori reali come parametri, ma non abbiamo quel lusso in Java.
I due approcci che posso pensare che potrebbero essere adottati per risolvere questo problema sono:
Avere un'implementazione di ogni possibile caso al momento della compilazione.
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; } }
Questa soluzione richiede ovviamente molto tempo ed è estremamente noiosa da programmare. In questo esempio non sembra troppo male, ma nel mio codice attuale ho a che fare con vettori che hanno più implementazioni ciascuno, con un massimo di quattro dimensioni (x, y, z e w). Al momento ho oltre 2.000 righe di codice, anche se ogni vettore ne ha solo 500.
Specifica dei parametri in fase di esecuzione.
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]; } }
Sfortunatamente questa soluzione danneggia le prestazioni del codice, si traduce in un codice più disordinato rispetto alla soluzione precedente e non è così sicura in fase di compilazione (non è possibile garantire in fase di compilazione che il vettore con cui si ha a che fare sia effettivamente bidimensionale, per esempio).
Attualmente sto sviluppando in Xtend, quindi se sono disponibili soluzioni Xtend, sarebbero anche accettabili.