Considera una situazione in cui una classe implementa lo stesso comportamento di base, i metodi, eccetera, ma possono esistere più versioni differenti di quella classe per usi diversi. Nel mio caso particolare, ho un vettore (un vettore geometrico, non una lista) e quel vettore potrebbe applicarsi a qualsiasi spazio euclideo N-dimensionale (1 dimensionale, 2 dimensionale, ...). Come si può definire questa classe / tipo?
Questo sarebbe facile in C ++ dove i modelli di classe possono avere valori reali come parametri, ma non abbiamo quel lusso in Java.
I due approcci a cui posso pensare che possano essere presi per risolvere questo problema sono:
-
Avere un'implementazione di ogni caso possibile 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 è ovviamente molto dispendiosa in termini di tempo ed estremamente noiosa per codificare. In questo esempio non sembra troppo male, ma nel mio codice attuale mi occupo di vettori che hanno implementazioni multiple ciascuna, con un massimo di quattro dimensioni (x, y, z e w). Al momento ho oltre 2000 linee di codice, anche se ogni vettore ne ha davvero bisogno solo 500.
-
Specifica dei parametri in fase di runtime.
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, genera un codice più messistico rispetto alla precedente soluzione e non è sicura al momento della compilazione (non è possibile garantire in fase di compilazione che il vettore di cui si ha effettivamente a che fare sia 2 -dimensionale, per esempio).
Attualmente sto attualmente sviluppando in Xtend, quindi se sono disponibili soluzioni Xtend, sarebbero anche accettabili.