
Originariamente inviata da
Mrk31
Una spintarella nella giusta direzione???
Quando si vogliono fare cose di questo tipo è bene tenere presente alcuni aspetti della OOP. Uno di questi è di individuare cosa "cambia" e cosa "non cambia".
Cosa è che non cambia? Non cambia il modo di gestire un certo formato, es. CSV. Che nel CSV ci siano dati di persone, di animali o di piante, non cambia la logica di gestione. Andrai ad "aprire" il file sempre in un certo modo, leggere le righe in un certo modo, separare i dati in un certo modo, ecc... Questo non cambia e va quindi tenuto da una certa parte.
Quello che cambia e che può variare anche molto è la "mappatura" dei dati, appunto come interpretare ed estrarre i dati da ciascuna riga logica del CSV. Insomma, ci possono essere "strategie" differenti. E questo va tenuto da un'altra parte, astraendola in modo da poter avere strategie differenti.
Poi ci possono essere diverse strade per "mappare" i dati, che magari arrivano anche ad usare reflection, annotation e cose di questo tipo. Per il momento tralasciamo un momento questo aspetto un po' avanzato. Una possibile soluzione a livello di design potrebbe essere la seguente:
- Una classe generica CSVFileReader<T>
- Una interfaccia generica RowDataMapper<T> che potrebbe avere un solo metodo es.
codice:
public interface RowDataMapper<T> {
T mapRow(RowData rowData);
}
- E la classe RowData "modella" una riga (del CSV in questo caso) e potrebbe avere metodi per:
-- sapere il numero di colonne
-- estrarre i dati da una certa colonna n magari con varianti per i vari tipi es. getInt(int colonna) / getString(int colonna) ecc...
A questo punto basterebbe assegnare una implementazione di RowDataMapper nel CSVFileReader (tramite costruttore o setter ... ora non importa). Chi implementa RowDataMapper dovrà quindi implementare il mapRow per estrarre e creare un oggetto del tipo corretto. QUI puoi istanziare una certa classe, es. Persona o Animale o Pianta, perché la implementazione è concreta e conosci tu il tipo di dato.
Alla fine l'uso finale potrebbe essere qualcosa del tipo:
codice:
CSVFileReader<Persona> csvReader = new CSVFileReader<>("persona.csv", new MyPersonaRowDataMapper());
List<Persona> listaPersona = csvReader.readAll();
...
csvReader.close();
E MyPersonaRowDataMapper sarà qualcosa del tipo:
codice:
public class MyPersonaRowDataMapper implements RowDataMapper<Persona> {
public Persona mapRow(RowData rowData) {
// Qui PUOI istanziare un Persona
}
}