Quindi stiamo avendo un dibattito piuttosto acceso sul lavoro riguardo a quale sarebbe la migliore pratica in atto durante il refactoring del nostro sistema di segnalazione. Molti di noi hanno alcune opinioni forti in un modo o nell'altro, ma per lo più non riusciamo nemmeno ad articolare ciò che riteniamo sarebbe l'approccio migliore. Sono principalmente alla ricerca di qualche input per vedere quale approccio risulterebbe la soluzione migliore per noi.
Il nostro sistema attuale è relativamente semplice, ma è composto da un bel po 'di codice spaghetti. Abbiamo circa 10-15 dashboard / report con circa 20 metriche su ciascuno di essi. Alcune di queste metriche sono condivise tra i report, ma molte sono uniche per ciascun report. Pertanto, esistono alcuni filtri di report comuni nella maggior parte / tutti i report e altri filtri specifici per un determinato report.
Nei nostri controller, abbiamo diversi oggetti che accettano i parametri del report, in base a quali filtri sono presenti. Quindi, ad esempio, abbiamo un oggetto chiamato QueryParams
, questo oggetto contiene filtri per StartDate
, EndDate
, Company
e Division
. Su un'altra dashboard, abbiamo un oggetto parametro diverso che accetta tutti i parametri sopra menzionati, ma include anche Provider
e Gender
. E su un'altra dashboard, potremmo avere quasi tutti gli stessi parametri di prima, ma invece non hanno bisogno dei parametri di data di inizio / fine.
Questo ha portato al fatto che i nostri oggetti parametro non sono stati effettivamente utilizzati per il nostro progetto WebUI. Una volta arrivati ai livelli logico e repository, le nostre firme dei metodi stanno semplicemente cercando tutti i filtri. Quindi piuttosto che GetVisitCounts(QueryParams)
abbiamo 'GetVisitCounts (StartDate, EndDate, Company, Division). Questo non è male, tranne per il fatto che questi filtri vengono aggiornati a una frequenza non banale. Quando arriva il momento di aggiungere alcuni nuovi filtri a un report, gli sviluppatori si trovano a passare attraverso ogni livello del progetto e ogni metodo per aggiornare la firma e la logica sottostante.
Una volta raggiunto il livello di repository, la maggior parte dei parametri viene gestita allo stesso modo. Alcuni SQL vengono scritti e le clausole vengono generate in base ai parametri passati al metodo. Questo SQL è praticamente interamente scritto a mano in ogni singolo metodo. In alcuni casi, le clausole where possono essere generate dinamicamente in quanto le stesse tabelle vengono utilizzate con gli stessi alias, ma è difficile effettuare questa chiamata per tutti i metodi in quanto vi sono molti one-off.
Ora ci troviamo a dover aggiungere 3-4 filtri a tutti i nostri dashboard, e questo ci impone di esaminare e aggiornare tutto. Ci sono alcune soluzioni proposte per semplificare tutto, ma nessuna sembra super ideale. Una tale idea è creare un oggetto master QueryParams
che contenga tutti i possibili filtri in tutti i report possibili. Questo oggetto sarebbe solo una super classe che si comporta come un archivio di dati. Semplificherebbe le firme del metodo, ma l'effettiva implementazione dei metodi del repository richiederebbe comunque che tutto fosse generato a mano.
Un secondo approccio consisteva nell'usare QueryParams
come classe base e creare sottoclassi che aggiungono parametri aggiuntivi mentre procediamo. Utilizzando questo approccio potremmo costruire una sorta di adattatore che tenta di serializzare l'oggetto parametro in una clausola SQL where. Tuttavia, questo non è l'ideale perché ci sono molti casi unici in cui le tabelle stanno seguendo join non standard, o stiamo usando solo un paio di parametri per qualche motivo e non possiamo includere i parametri nel dove clausola.
Sono aperto a qualsiasi soluzione potenziale che possa semplificare il nostro approccio attuale, anche se è necessaria una riscrittura quasi completa.