mercoledì, maggio 16, 2007

Classi Java, singleton ed Objective C

Le classi java non sono un oggetto. Si, esistono le istanze di Class, ma queste sono una supporto per l'accesso alle proprietà delle classi sottostanti (relazioni con altre classi, membri privati, metodi, annotation...). L'interfaccia esposta da Class facilita l'ispezione della classe ma non facilita l'uso di questa classe come componente applicativo. Per spiegare meglio questo concetto farò un esempio che prende spunto dal seguente problema: è meglio usare un singleton o una classe con i suoi metodi statici? Vediamo un attimo le due situazioni:

// definizione classe con metodi statici


class MiaClasse {
public static void metodo1() { ... }
public static Object metodo2(int valore) { ... }
}

// utilizzo classe con metodi statici

MiaClasse.metodo1();
...
Object r = MiaClasse.metodo2(10);

// classe singleton

class MiaClasse {
private MiaClasse() { ... }
private static MiaClasse instance = null;
public static getInstance() {
if (instance == null) instance = new MiaClasse();
return instance;
}
public void metodo1() { ... }
public Object metodo2(int valore) { ... }
}

// utilizzo classe singleton

MiaClasse.getInstance().metodo1();
...
Object r = MiaClasse.getInstance().metodo2(10);


Il singleton è indubbiamente una soluzione che aggiunge complessità, almeno in un primo momento. Però ha un vantaggio: permette di trattare il componente funzionale come un oggetto, con tutto quello che ne consegue. Ad esempio, se il singleton implementa una certa interfaccia M, è possibile passare il singleton ad un metodo che accetta un parametro di tipo M.


class MiaClasse implements M {
...
}

class AltraClasse {
public void metodoM(M param) { ... }
...
}

AltraClasse a = ...;

a.metodoM(MiaClasse.getInstance());


E' possibile fare la stessa cosa utilizzando l'oggetto Class?

La risposta è... forse... penso di si, ma in modo più complicato, così complicato che il singleton alla fine sarebbe la soluzione migliore.

Queste considerazioni mi fanno venire in mente un fatto: in Objective C le classi sono oggetti al pari di altri e potete permettervi di passarle come parametri ad un metodo ed usarle per richiamare i metodi della classe come si fa con i metodi delle istanze. Ad esempio:


@interface ClasseA
{
...
}
+ (int) metodo1: (int) valore;

...

@interface ClasseB
{
...
}
- (void) metodo2: (id) oggetto;

...

@interface ClasseC
{
...
}
- (int) metodo1: (int) valore;

...

@implementation ClasseB
- (void) metodo2: (id) oggetto
{
int y = ... ;
....
int x = [oggetto metodo1: y]
...
}

...

// utilizzo ClasseA come parametro metodo2
ClasseB* b = ... ;
[b metodo2: ClasseA];

// utilizzo istanza di ClasseC come parametro di metodo2.

ClasseC* c = ...;
[b metodo2: c];


Insomma, se Java fosse come l'Objective C, probabilmente si potrebbe evitare il ricorso ai singleton tutte quelle volte che vorrebbe trattare la classe come un oggetto. Il problema è capire quando questo è, più che necessario, possibile. Cioè, che probabilità ci sia che questo prima o poi diventi una necessità.

Nessun commento: