Mi sono imbattuto in un metodo simile allo snippet di sotto.
public void process(Data row) {
Value value1 = row.getValue1();
Value value2 = row.getValue2();
boolean saved = false;
if (value1 != null) {
if (relevantValues.contains(value1)) {
addRow(value1, row, only1collection);
if (relevantValues.contains(value2)) {
addRow(value2, row, values12collection);
}
repository.save(row);
stats.increment();
saved = true;
}
}
if (relevantValues.contains(value2)) {
addRow(value2, row, only2collection);
if (!saved) {
repository.save(row);
stats.increment();
}
}
}
private void addRow(Value date, Data row, Map<Value, List<Data>> mapping) {
mapping.computeIfAbsent(date, (p) -> new ArrayList());
mapping.computeIfPresent(date, (d, rows) -> {
rows.add(row);
return rows;
});
}
Nel codice precedente, il metodo process
verrà chiamato per ogni riga di alcuni file di dati e in base al valore in un paio di campi, la riga dovrebbe essere aggiunta a qualsiasi o tutte le 3 raccolte.
Il codice,
repository.save(row);
stats.increment();
sembra che io stia accoppiando due funzionalità / aspetti indipendenti in una sorta di "ciclo di vita" / business logic dell'elaborazione delle righe. Non riesco a utilizzare direttamente il motivo decoratore in quanto questi due passaggi devono essere eseguiti in modo condizionale e solo una volta per riga. Inoltre, se voglio estendere la funzionalità, ad esempio, invia un'email dopo l'incremento delle statistiche, il codice sarà simile,
repository.save(row);
stats.increment();
sendEmail(row);
Ciò viola chiaramente il principio Open-Closed. Sto pensando se sarebbe una buona idea prendere un Set<RowProcessor>
ed eseguirli quando la riga è interessante. Quale sarebbe un buon modo o un modello per organizzare questo?
Le condizioni nidificate di if
non sembrano buone. Qualche principio generale, modelli per renderlo più funzionale?
Come posso eliminare il controllo if(!saved)
?
Qualsiasi altro suggerimento, i miglioramenti sono più che benvenuti. Se conosci qualche libro che fornisce indicazioni pratiche per il refactoring / la pulizia del codice in scenari come questo, ti preghiamo di suggerire.