Migliore approccio all'aggiunta di un nuovo metodo di conversione CSV

-1

Attualmente ho una gerarchia di classi per i parser con Parser come interfaccia con le classi CSVParser e XMLParser che la implementano. L'interfaccia ha i seguenti metodi:

List<AType>parse(File file)

Ora voglio aggiungere un altro metodo di analisi che prenda lo stesso tipo di file dell'argomento, ma restituirà List<BType> . Questo metodo è richiesto solo per il tipo di file CSV e non per i file di tipo XML.
Una semplice opzione consiste nell'aggiungere un nuovo metodo all'interfaccia Parser con un nome diverso. Fornire anche l'implementazione vuota nel file XMLParser e l'implementazione del metodo richiesto in CSVParser. Ma alcuni come non ritengo che questa sia la scelta giusta. Voglio sapere quale sarebbe una scelta alternativa migliore?

    
posta Innocuous 23.06.2017 - 09:14
fonte

2 risposte

1

Questo è un esempio perfetto per i farmaci generici combinato con il modello Metodo-modello ( Modello metodo modello ):

public interface Parser<T> {
    List<T> parse(File file);
}

public abstract class CSVParser<T> implements Parser<T> {
    public List<T> parse(File file) {
        List<String[]> lines = loadCSV(file);
        return buildResult(lines)
    }
    public abstract List<T> buildResult(List<String[]> lines);
}

public class CSVParserAType extends CSVParser<AType> {
    public List<AType> buildResult(List<String[]> lines) {
        ...
    }
}

public class CSVParserBType extends CSVParser<BType> {
    public List<BType> buildResult(List<String[]> lines) {
        ...
    }
}

public class XMLParser implements Parser<AType> {
    public List<AType> parse(File file) {
        ...
    }
}

Il tipo generico viene utilizzato per mantenere flessibile il tipo di risultato per le implementazioni future.

Il pattern Metodo modello viene utilizzato per riutilizzare il meccanismo di caricamento di csv e assicurarsi che sia fatto prima di costruire il risultato.

Elenco di String [] contiene le righe del file CSV separate in colonne (String [], String-Array). Se il tuo CSV è enorme, potresti considerare qualcosa come un cursore o uno stream in modo da poter astrarre dal modo in cui i dati vengono effettivamente letti in memoria per avere un impatto migliore sulla memoria.

    
risposta data 24.06.2017 - 21:50
fonte
3

Se ti capisco correttamente, desideri aggiungere un secondo metodo parser in CSVParser che restituisca un tipo diverso? È corretto? Quindi suppongo che entrambi questi metodi possano analizzare i file CSV?

Il problema deriva dai conflitti di denominazione come lo vedo io. Il modo in cui hai strutturato il tuo codice, c'è un Parser per ogni tipo di file, in questo caso un XMLParser per i file xml e un CSVParser per i file csv. Questo è tutto a posto se hai un solo parser per ogni tipo di file, ma a quanto pare non è più il tuo caso.

Mentre potresti aggiungere un secondo metodo in Parser e lanciare un NotImplementedException nel metodo XmlParser secondo, devi davvero chiediti se XmlParser è l'eccezione per regola o se è la regola. In altre parole, se domani deciderai di aggiungere un altro parser, questo nuovo parser restituirà sia un elenco di AType sia un elenco di BType ? In questo caso, XmlParser è il dispari fuori, e potrebbe essere una buona idea estendere questo comportamento a Parser , ma suppongo che non sia il caso qui.

Pertanto sarebbe molto probabilmente una cattiva idea aggiungere un secondo metodo a Parser . Per fortuna ci sono alternative! Poiché un'implementazione Parser non è più legata solo al tipo di file, una soluzione semplice potrebbe avere un CSVToATypeParser e un CSVToBTypeParser . In questo modo, puoi usarne uno come faresti con qualsiasi altro parser.

Una seconda soluzione sarebbe combinare AType e BType in qualche modo come CType in modo che una chiamata a CSVParser restituisca tutte le informazioni richieste da AType e BType in un singolo metodo. Considera che stai ancora eseguendo un passaggio a prescindere, quindi a parte un aumento dell'utilizzo della memoria, non ci sarebbe alcun svantaggio aggiunto.

Spero che ti aiuti!

    
risposta data 23.06.2017 - 09:45
fonte

Leggi altre domande sui tag