Questo sito è ancora in costruzione.
L'attuale sito ufficiale del JUG Padova è all'indirizzo www.jugpadova.it

Ma voi le wrappate le liste?

Ciao, in un progetto su cui sto lavorando sto provando un approccio che non avevo mai usato in passato per le liste di oggetti java, immaginate che di avere una lista tipo:

List<SomeObject> list = new ArrayList<SomeObject>();

Se volessi estrarre dalla lista tutti gli elementi aventi un certo campo valorizzato ad un dato valore, ovvero fare un filtro, farei:

class SomeObject {
  public static List<SomeObject> filterByField(List<SomeObject> input, String value) {
    // ciclo la lista input e restituisco una lista nuova con gli oggetti che hanno field=value 
  }
}

usato così:

List<SomeObject> all = new ArrayList<SomeObject>();
List<SomeObject> filtered = SomeObject.filterByField(all, "someValue");

Il fatto però di avere metodi statici ‘helper’ dentro SomeObject per aggiungere funzionalità ad una lista non mi piace molto… ho provato invece a wrappare List e a spostare il metodo filerByValue da SomeObject alla nuova classe SomeObjects:

class SomeObjects extends ArrayList<SomeObject> {
   public SomeObjects filterByField(String value){
     // filtro ciclando gli elementi in this e restituisco una nuova istanza di SomeObjects
   }
}

Il codice di utilizzo quindi diventa:

SomeObjects all = new SomeObjects();
SomeObjects filtered = all.filterByField("someValue");

Che mi pare molto più pulito e leggible, che ve ne pare?

So che non è un gran cambiamento, ma ho un parametro in meno per ogni filterByXXX che desidero aggiungere e ogni metodo è nel posto che gli compete, ovvero i medoti per filtrare una lista stanno nella lista e non come metodi helper dell’oggetto contenuto.

Un’altro punto dove questo approccio è utile è nei Dao che wrappano funzionalità di IBatis o Hibernate, dove si trova spesso codice di questo tipo per prevenire il ritorno di liste nulle:

List<SomeObject> result = new ArrayList<SomeObject>();
result.addAll( ...queryForList("your query", param));
return result;

Con i wrapper possiamo scrivere un costruttore ad hoc, che prende una lista in input e fa addAll(...) solo se è diversa da null:

public class SomeObjects extends ArrayList<SomeObject> {

    public SomeObjects () {}

    public SomeObjects (Collection<SomeObject> c) {
       if (c!=null) addAll(c);
    }
}

E il codice di utilizzo diventa magicamente:

return new SomeObjects(...queryForList("your query", param));

Fatemi sapere che ne pensate, io mi sto trovando bene con questo approccio.


Paolo Donà si occupa di sviluppo web in Java e Ruby, sviluppo progetti su commessa e formazione/training. Potete contattarlo via mail o leggere il suo blog aziendale o personale.