Negli ultimi mesi, sono inciampato alcune volte sulla seguente tecnica / modello. Tuttavia, non riesco a trovare un nome specifico, né sono sicuro al 100% di tutti i suoi vantaggi e svantaggi.
Il modello è il seguente:
All'interno di un'interfaccia Java, una serie di metodi comuni è definita come al solito. Tuttavia, utilizzando una classe interna, un'istanza predefinita viene trapelata attraverso l'interfaccia.
public interface Vehicle {
public void accelerate();
public void decelerate();
public static class Default {
public static Vehicle getInstance() {
return new Car(); // or use Spring to retrieve an instance
}
}
}
Per me, sembra che il vantaggio maggiore risieda nel fatto che uno sviluppatore deve solo conoscere l'interfaccia e non le sue implementazioni, ad esempio nel caso in cui voglia rapidamente creare un'istanza.
Vehicle someVehicle = Vehicle.Default.getInstance();
someVehicle.accelerate();
Inoltre, ho visto questa tecnica utilizzata insieme a Spring per fornire dinamicamente istanze a seconda della configurazione. A questo proposito, sembra anche che questo possa aiutare con la modularizzazione.
Tuttavia, non riesco a scuotere la sensazione che si tratti di un uso improprio dell'interfaccia poiché associa l'interfaccia a una delle sue implementazioni. (Principio di inversione di dipendenza ecc.) Qualcuno potrebbe spiegarmi come si chiama questa tecnica, nonché i suoi vantaggi e svantaggi?
Aggiornare:
Dopo qualche tempo di riflessione, ho ricontrollato e ho notato che la seguente versione singleton del modello è stata utilizzata molto più spesso. In questa versione, un'istanza statica pubblica viene esposta attraverso l'interfaccia che viene inizializzata una sola volta (a causa del campo finale). Inoltre, l'istanza viene quasi sempre recuperata utilizzando Spring o una factory generica che disaccoppia l'interfaccia dall'implementazione.
public interface Vehicle {
public void accelerate();
public void decelerate();
public static class Default {
public static final Vehicle INSTANCE = getInstance();
private static Vehicle getInstance() {
return new Car(); // or use Spring/factory here
}
}
}
// Which allows to retrieve a singleton instance using...
Vehicle someVehicle = Vehicle.Default.INSTANCE;
In breve: sembra che si tratti di un modello singleton / factory personalizzato, che sostanzialmente consente di esporre un'istanza o un singleton attraverso la sua interfaccia. Per quanto riguarda gli svantaggi, alcuni sono stati indicati nelle risposte e nei commenti seguenti. Finora, il vantaggio sembra risiedere nella sua convenienza.
Vehicle.Default
dovrebbe essere spostato nello spazio dei nomi del pacchetto come una classe di fabbrica, ad es VehicleFactory
.
Vehicle.Default.getInstance() != Vehicle.Default.getInstance()