Export personalizzato con ordinamento colonne

di il
3 risposte

Export personalizzato con ordinamento colonne

Ciao a tutti!
Mi farebbe piacere ricevere qualche feedback su questo problema:
Ho una classe chiamata punto

public class Point{
	public int x;
	public int y;
	public int z;
}
Io vorrei fare in modo che l'utente che sceglie di esportare un ArrayList<Point> possa scegliere cosa esportare e in che ordine, ovvero deve poter esportare una tabella con x,y oppure y,z,x oppure solo x e così via

Io ho pensato di assegnare ad ogni variabile un "nome" e di creare un metodo fatto così


public static void exportPoints(ArrayList<Point> points, ArrayList<String> order){
	String exportString = "";
	for(Point p : points){
		for(String single : order){
			switch(single){
				case "x": 
					exportString += p.x + ";" ;
				break;
				case "y": 
					exportString += p.x + ";" ;
				break;
				case "z": 
					exportString += p.x + ";" ;
				break;
			}
		}
	}
}

Questo approccio mi sembra molto time consuming però, avete delle idee migliori?

3 Risposte

  • Re: Export personalizzato con ordinamento colonne

    lory1990 ha scritto:


    Ho una classe chiamata punto
    
    public class Point{
    	public int x;
    	public int y;
    	public int z;
    }
    
    Sì ma se non ci sono ragioni davvero valide e importanti, non mettere campi public. Campi private con i metodi "accessori" public.

    lory1990 ha scritto:


    Io vorrei fare in modo che l'utente che sceglie di esportare un ArrayList<Point> possa scegliere cosa esportare e in che ordine, ovvero deve poter esportare una tabella con x,y oppure y,z,x oppure solo x e così via

    Io ho pensato di assegnare ad ogni variabile un "nome" e di creare un metodo fatto così
    Questo approccio mi sembra molto time consuming però, avete delle idee migliori?
    In questi casi meglio ragionare un po' di più a livello object-oriented. Ad esempio:

    Innanzitutto una interfaccia che "cattura" il concetto di estrazione di un valore String da un certo oggetto. Magari la facciamo "generica" (così puoi riutilizzarla anche per altri tipi oltre che Point).
    public interface DataExtractor<T> {
        String getValue(T t);
    }
    Poi implementi DataExtractor 3 volte, per ciascuno dei campi di Point. Puoi farlo con una normale classe, con una anonymous inner class o (da Java 8 ) con una lambda expression. Ecco due esempi:
    DataExtractor<Point> xExtractor = new DataExtractor<Point>() {
        @Override
        public String getValue(Point p) {
            return String.valueOf(p.getX());
        }
    };
    Oppure con una lambda:
    DataExtractor<Point> yExtractor = p -> String.valueOf(p.getY());
    A quel punto, secondo come sarà necessario, crei un List<DataExtractor<Point>> (chiaramente es. un ArrayList) in cui inserisci i riferimenti alle implementazioni, quali e in che ordine vuoi.

    Quindi il metodo di esportazione sarà:

    exportPoints(List<Point> points, List<DataExtractor<Point>> extractors)

    Dovrai naturalmente fare un ciclo sui points e dentro un ciclo su extractors ma hai 2 vantaggi:
    - non hai più lo switch (che è brutto in questi casi)
    - hai ben separato la logica di generazione del risultato dalla logica di estrazione dei dati (e questo è più object-oriented)


    Ah, se devi comporre una lunga stringa, non usare la concatenazione, usa StringBuilder.

    P.S. DataExtractor la puoi chiamare come vuoi: così oppure es. StringExtractor, ObjectStringExtractor o che altro.
  • Re: Export personalizzato con ordinamento colonne

    andbin ha scritto:


    Sì ma se non ci sono ragioni davvero valide e importanti, non mettere campi public. Campi private con i metodi "accessori" public.
    In realtà ho semplificato per creare un MCVE ().

    In realtà la classe punto ha molti più metodi compresi setters e getters.

    Mi piace molto come hai risolto il problema se non fosse che la GUI è stata fatta in React.js (stiamo quindi parlando di web-app) quindi l'informaizone sui campi da esportare ed il loro ordine arriva in ogni caso via Stringa -.-

    Avrei pensato anche ad un'altra soluzione: mettere tutti i campi dentro una classe Map<String, Object> e poi fare un map.get("keyFromRequest") anche se c'è sempre i solito problema di quanto questo approccio sia costo-efficace.

    Volendo complicare il problema: e se avessi una classe in una classe? ovvero una situazione di questo genere:
    
    public class triangle{
    	public Point a,b,c;
    }
    

    andbin ha scritto:


    Ah, se devi comporre una lunga stringa, non usare la concatenazione, usa StringBuilder.
    Per l'export in TXT ed in XML uso uno StringBuilder, per il JSON, l'XLSX e il DOC ci sono gson e apache.poi
  • Re: Export personalizzato con ordinamento colonne

    lory1990 ha scritto:


    quindi l'informaizone sui campi da esportare ed il loro ordine arriva in ogni caso via Stringa -.-
    Associare una stringa (es. "x") ad una implementazione della DataExtractor che ho ipotizzato io, comunque è abbastanza semplice (basta una Map). Non sarebbe quello un grosso problema.

    lory1990 ha scritto:


    Avrei pensato anche ad un'altra soluzione: mettere tutti i campi dentro una classe Map<String, Object> e poi fare un map.get("keyFromRequest") anche se c'è sempre i solito problema di quanto questo approccio sia costo-efficace.
    Meno bello e sicuramente meno efficiente (se come ho capito lo fai per ogni oggetto es. Point).

    lory1990 ha scritto:


    Volendo complicare il problema: e se avessi una classe in una classe? ovvero una situazione di questo genere:
    
    public class triangle{
    	public Point a,b,c;
    }
    
    Non vedo grossi problemi, nel senso che con la interfaccia e le implementazioni come ho detto prima è perfettamente possibile e pulito. Chiaramente è un livello in più e moltiplica per 3 i dati. Ora immagino avresti nomi tipo, simili a "ax", "ay", "bx", ecc... giusto?

    lory1990 ha scritto:


    Per l'export in TXT ed in XML uso uno StringBuilder, per il JSON, l'XLSX e il DOC ci sono gson e apache.poi
    Il design che ho detto io, una interfaccia e alcune implementazioni per estrarre dati è davvero il minimo. In realtà di design ce ne possono essere svariati. Dipende molto da quanto vuoi "astrarre" e da come suddividere le responsabilità.
    A livello estremo si potrebbe anche rendere interscambiabili le logiche di generazione dei vari tipi di file, tali per cui per creare un JSON piuttosto che un TXT piuttosto che un XML, è sufficiente istanziare una implementazione piuttosto che un'altra, facendo in modo che chi le usa "veda" la stessa interfaccia di programmazione.
    Insomma, servono discrete basi di OOP ma sarebbe assolutamente possibile fare un bel lavoro dal punto di vista del "design".
Devi accedere o registrarti per scrivere nel forum
3 risposte