Ottimizzazione del recupero dei dati basata sull'ingresso

2

Esiste un modo più pulito / leggibile per mantenere e iterare molti più mapping anziché più condizioni if? (Un modo sarebbe memorizzare la mappatura di ReportType - > DataSet Req. nel database)

Ad esempio, se esiste un'applicazione che dipende dai "report selezionati", genera report che utilizzano i dati delle tabelle del database richieste. Qualcosa come questo:

Daquandoidatidarecuperareinquestetabellesonoenormiecondivisiperpiùrapporti,siamoarrivaticonunnoncosìbelloapproccioperottimizzarelafunzionegetDatausandoif()condizionicomequesta:

getDataForRequiredReports(ListrequiredReports){Map<String,Object>dataMap;if(requiredReports.contains(ReportB))dataMap.add(newEntry("marketData", DAOlayer.get("MarketData")));

 if(requiredReports.contains(ReportA) || requiredReports.contains(ReportB) || requiredReports.contains(ReportE))
    dataMap.add(newEntry("pastData", DAOlayer.get("PastData")));

 if(requiredReports.contains(ReportC) || requiredReports.contains(ReportD) || requiredReports.contains(ReportE))
    dataMap.add(newEntry("manualData", DAOlayer.get("ManualData")));

 if(requiredReports.contains(ReportC) || requiredReports.contains(ReportE))
    dataMap.add(newEntry("mlOutputData", DAOlayer.get("MLOutputData")));

 return dataMap;
}
    
posta pxm 25.06.2018 - 13:48
fonte

2 risposte

2

In questo modo, stai tentando di scrivere le condizioni in base ai dati di cui avrai bisogno, quando dovresti scriverlo in termini di dati richiesti per ogni singolo rapporto.

Considera quanto segue:

Map<Class<? extends Report>, ReportHandler> reportHandlers = new HashMap<Class<? extends Report>, ReportHandler>();

Map<String,Object> getDataForRequiredReports(List<Report> requiredReports) {
    Map<String,Object> dataMap = new HashMap<String, Object>();

    for(Report report : requiredReports) {

        ReportHandler handler = reportHandlers.get(report.getClass());

        for(String entryName : handler.getEntryNames()) {
            if(!dataMap.containsKey(entryName)) {
                dataMap.put(entryName, handler.newEntry(entryName));
            }
        }
    }
    return dataMap;
}

Valuta ogni rapporto per ottenere i componenti necessari per quella particolare classe, aggiungendo solo se non è già presente.

Ecco un esempio di un possibile ReportAHandler:

public class ReportAHandler implements ReportHandler {
    private static final Map<String, String> NAME_QUERY_MAPPING = new HashMap<String, String>();

    static {
        NAME_QUERY_MAPPING.put("pastData", "PastData");
    }

    public Set<String> getEntryNames() {
        return NAME_QUERY_MAPPING.keySet();
    }

    public Entry newEntry(String entryName) {
        return newEntry(entryName, DAOlayer.get(NAME_QUERY_MAPPING.get(entryName)));
    }
}

In questo modo si caricano le informazioni esattamente una volta per ogni dato necessario di ciascun rapporto. L'unica cosa che cambia da rapporto a rapporto è il contenuto di NAME_QUERY_MAPPING, quindi potresti probabilmente generalizzare il comportamento per ogni rapporto, a meno che tu non abbia ragione di aggiungere una logica più complicata in seguito.

    
risposta data 04.07.2018 - 10:59
fonte
1

Quando si mappano informazioni professionali si dovrebbe cercare di renderlo il più chiaro e leggibile possibile.

I tipi DAO dovrebbero essere un'entità centrale:

public enum StoredDataType {
    MARKET_DATA  ("marketData",   "MarketData"),
    PAST_DATA    ("pastData",     "PastData"),
    MANUAL_DATA  ("manualData",   "ManualData"),
    MLOUTPUT_DATA("mlOutputData", "MLOutputData");

    public Reports(String entry, String dao)
}

I rapporti dovrebbero definire chiaramente i dati richiesti:

public enum Report {
    REPORT_A(PAST_DATA),
    REPORT_B(MARKET_DATA, PAST_DATA),
    REPORT_C(MANUAL_DATA, MLOUTPUT_DATA),
    REPORT_D(MANUAL_DATA),
    REPORT_E(MANUAL_DATA, MLOUTPUT_DATA, PAST_DATA);

    public Report(StoredDataTaype... requiredData)
}

E la tua logica può facilmente creare le voci richieste:

Arrays.stream(StoredDataType.values())
    .filter(d -> requiredReports.stream().anyMatch(r -> r.requires(d)))
    .forEach(d -> dataMap.add(newEntry(d.name, d.daoName)));
    
risposta data 10.07.2018 - 12:50
fonte