sabato 31 marzo 2012

Design - Array e firma di un metodo

Il caso: si deve progettare un metodo dell'interfaccia InterfB che permette al componente B di restituire al chiamante (nell'esempio il componente A) un insieme di oggetti di tipo String.
B restituisce ad A un insieme di String
Come semplificazione supponiamo che, per l'elaborazione del risultato, il metodo richieda solo un parametro intero.

Ovviamente sono possibli diverse soluzioni, alcune delle quali sono:
  1. String[] calcolaElencoDiValori(int parametro)
  2. Collection<String> calcolaElencoDiValori(int parametro)
  3. void calcolaElencoDiValori(int parametro, Collection<String> risultatoDaB)
Quale scegliereste?

Personalmente trovo le soluzioni 1 e 2 abbastanza equivalenti. Dal punto di vista del chiamante occorre solo invocare il metodo e assegnare il valore restituito a una variabile nello scope corrente (di seguito b è una istanza di B).

String[] risultatoDaB = b.calcolaElencoDiValori(p);

oppure

Collection<String> risultatoDaB = b.calcolaElencoDiValori(p);

La soluzione 3 invece richiede che il chiamante passi al metodo, oltre che il parametro intero da usare per l'elaborazione, anche la lista designata a ricevere il risultato.

Collection<String> risultatoDaB = new ArrayList<String>();
b.calcolaElencoDiValori(p, risultatoDaB);

Con quest'ultima soluzione l'invocazione si complica (leggermete) ma la flessibilità che il chiamante ottiene, in molti casi, permette di migliorare sensibilmente le prestazioni del software. Il chiamante può iniettare, con l'invocazione del metodo, l'istanza di Collection<String> per lui più vantaggiosa (in termini di implementazione - ArrayList vs LinkedList vs HashSet - e in termini di parametri di inizializzazione della collection - ArrayList(n) vs ArrayList() ).

Si potrebbe inoltre pensare di implementare il metodo in modo da aggiungere i valori calcolati alla collection senza ripulirla prima; in questo modo il client potrà raccogliere (se occorre) nella stessa collection i risultati di più invocazioni senza dover effettuare scansioni/copie dei risultati temporanei.

Collection<String> risultatoDaB = new ArrayList<String>();
b.calcolaElencoDiValori(p1, risultatoDaB);
b.calcolaElencoDiValori(p2, risultatoDaB);

Eppure da un punto di vista "funzionale" (o meglio astraendo opportunamente - l'astrazione sarà oggetto di prossimi articoli) tutti e tre gli approcci sono equivalenti!

Nessun commento:

Posta un commento