Quella è evidentemente un'applicazione del pattern Factory Method (inoltre rappresenta anche un'applicazione del pattern singleton). Viene usata anche dal core Java (vedi ad esempio la classe NumberFormat, anche se non è un esempio di puro factory method).

Quello che accade è questo: c'è una classe composta di metodi statici che si occupano della creazione e restituzione di oggetti appartenenti ad una super-classe astratta o, appunto, un'interfaccia. Questa classe ha il solo scopo di fornire un'implementazione concreta di un tipo di oggetto (quale sia l'effettiva implementazione concreta non è importante), che altrimenti sarebbe "difficile" o "macchinoso" reperire (o, addirittura, impossibile se è questo lo scopo della classe).

Nel caso specifico quella classe serve a fornire due "diverse" implementazioni concrete di due interfacce (ho scritto diverse tra virgolette apposta). Chiamando il metodo distanceE() si ottiene una implementazione concreta dell'interfaccia IntDistanceEuclidea, mentre invocando il metodo distanceEdit() si ottiene una implementazione concreta dell'interfaccia IntDistanceEdit. Quali che siano le due implementazioni concrete non interessa a nessuno, quello che viene garantito è che i due oggetti restituiti soddisfano il contratto imposto dalle due interfacce. Il fatto che l'oggetto restituito da entrambi i metodi sia lo stesso è solo una scelta implementativa: l'oggetto è in grado di svolgere entrambi i compiti, quindi tanto vale restituire la stessa istanza, ma non è un requisito è solo una scelta... si sarebbe tranquillamente potuto creare due classi distinte, ciascuna con l'implementazione di una delle due interfacce e restituire per ciascun metodo il corrispettivo oggetto, non cambiava (quasi) nulla.

In buona sostanza, chi deve usare un'implementazione concreta dell'interfaccia IntDistanceEuclidea non dovrà preoccuparsi né di creare un oggetto specifico, né di sapere con precisione di che tipo di oggetto si tratti, gli basterà richiedere alla Factory Class di restituire un oggetto con le caratteristiche necessarie e punto:

codice:
IntDistanceEuclidea myObj = Calcolo.distanceE();
// myObj è un oggetto che sicuramente possiede il metodo Euclidea()
// in quanto rispetta il contratto imposto da tale interfaccia...
// quindi posso usarlo senza preoccuparmi di sapere quale sia la sua reale istanza concreta
Item y1 = ...;
Item y2 = ...;
Double x = obj.Euclidea(y1, y2);

Questo porta ad un altro enorme vantaggio: il disaccoppiamento. Se un domani volessi usare una implementazione diversa di IntDistanceEuclidea (magari più performante o che agisce in modo diverso) potrei farlo semplicemente andando a modificare l'oggetto restituito dalla classe Calcolo senza dover toccare nemmeno una riga di tutti i programmi che eventualmente la usassero.

Con il tuo approccio (ovvero usare direttamente la classe ImplDistance) saresti legato a quella precisa implementazione dell'interfaccia e se un domani volessi cambiarla dovresti andare a modificare tutti i programmi in cui hai usato direttamente ImplDistance.


Ciao.