Costruire un codice dinamico che può ancora gestire molti pezzi unici?

0

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.

    
posta JD Davis 14.06.2018 - 18:38
fonte

2 risposte

1

Interrompi la scrittura di report nel codice e carica tutto in un data warehouse con i propri strumenti.

I rapporti cambiano spesso, sono difficili da mantenere e diventano rapidamente obsoleti. A meno che tu non abbia un rapporto altamente tecnico con requisiti immutabili, è inutile trattarlo come codice.

Le relazioni commerciali tendono ad essere "investigative". Le persone vogliono trovare qualcosa o giustificare una decisione. Ciò significa manipolare i campi e i parametri. Anche i report statici tendono ad essere esportati per eccellere e manipolare prima che vengano utilizzati.

    
risposta data 15.06.2018 - 14:08
fonte
0

Immagino che il meglio che puoi fare immediatamente sia quello di fornire un componente riutilizzabile che possa generare la clausola SQL aggiuntiva da alcuni criteri di filtro dinamico. Sarà comunque necessario chiamare quel componente in ogni posizione in cui si verifica una query SELECT e combinare la clausola con gli SQL esistenti. Questo non è niente che puoi fare facilmente in modo generico.

Come progettare esattamente il componente non è nulla che possiamo dirti proprio qui, è qualcosa che devi scoprire per il tuo contesto. Implementare alcuni proof-of-concept o alcuni prototipi è probabilmente una buona idea per scoprire cosa funziona meglio.

Inoltre, raccomanderei di non mescolare il problema del filtro con il problema di avere troppe SQL scritte manualmente nel codice. Quest'ultimo è qualcosa che non puoi risolvere rapidamente in una settimana (assumendo una base di codice di dimensioni ragionevoli). Questo è qualcosa che puoi ottenere solo come mangiare un elefante: un morso alla volta. Introdurre livelli migliori, rifattorizzare codice più pulito e SOLID, utilizzare generatori di codice e / o forse un ORM, utilizzare revisioni del codice e assicurarsi che tutto il team sia a bordo. Quindi il codice base diventerà più evolutivo nel corso degli anni.

    
risposta data 14.06.2018 - 21:19
fonte

Leggi altre domande sui tag