È meglio usare cattive pratiche preesistenti o buone pratiche che non si adattano bene al vecchio codice?


25

Ci stavo pensando perché stavo cercando di scrivere un'estensione per un software di terze parti esistente e il loro database è orribilmente denormalizzato. Avevo bisogno di usare le loro tabelle esistenti e aggiungere un sacco di nuovi campi.

Ho avuto la possibilità di creare nuove tabelle nel loro stile di progettazione (che consiste in quasi tutte le proprietà che si trovano in una grande tabella) o di creare un nuovo set di tabelle nel loro insieme e di utilizzare qualcosa in più come Trigger per sincronizzare i dati tra il nuovo e vecchi tavoli.

Ho finito con la prima opzione di utilizzare lo stile di progettazione scadente esistente, ma mi è rimasta questa domanda: è meglio andare con le cattive pratiche preesistenti o implementare buone pratiche che non giocano bene con il codice esistente? Ci sono alcune situazioni in cui dovrei scegliere l'una sull'altra?

NOTA: molte risposte finora hanno a che fare con il refactoring lento del codice errato, tuttavia non sono in grado di farlo. Il codice non è nostro e viene spesso aggiornato dal venditore. Posso solo costruirci sopra.


3
possibile duplicato della manutenzione
Péter Török,

Grazie Peter, non ho visto quella domanda. È molto simile a quello che sto chiedendo, tranne per il fatto che le risposte sembrano essere legate al refactoring del codice esistente, non all'aggiunta di un codice errato esistente. Non riesco a riformattare il codice esistente, posso solo costruirlo.
Rachel,

Dipende da quanto tempo vuoi rimanere con il tuo attuale datore di lavoro;)
Lavoro

Risposte:


21

Dovresti scegliere un design migliore se:

  1. Stai per assumere gran parte della codifica futura

  2. Una progettazione migliore non è più costosa per il cliente nel lungo periodo. Ad esempio, ho assistito a "refactoring" pluriennali per progetti che erano stati interrotti entro la fine dell'anno.

Dovresti scegliere "stesso cattivo stile" se:

  1. Stai solo dando una mano. Non è realistico pensare di poter prendere un gruppo esistente e farli raggiungere standard di progettazione più elevati se si è solo un riempimento part-time sul progetto. Un design migliore è soggettivo e ha quasi sempre una curva di apprendimento. Se quel nuovo design non viene appreso dal resto del team, il progetto finirà con un miscuglio di stili e il tuo codice meglio progettato potrebbe finire nella pila di cose che nessuno cambia perché non riescono a capire esso. Nel tuo esempio sopra, cosa succede se ci sono aggiornamenti al software di terze parti?

  2. Sacrificare un design "migliore" ti darà un vantaggio commerciale tangibile. Come aggiungere male la funzione X, otterrai un contratto di grandi dimensioni, ma il mancato rispetto della scadenza non ti farà finire nulla. È qui che entra in gioco lo storico conflitto tra mgmt e il team tecnico. Come per ristrutturare una casa, qualcuno deve decidere quando pagare. Puoi pagare il debito inizialmente vivendo senza elettricità o impianti idraulici per un anno. Oppure puoi pagare 3 volte tanto con il vantaggio di avere quelle utility.


Grandi esempi di quando andare con un buon design rispetto a un cattivo design e viceversa, grazie :)
Rachel

11

A lungo termine, è meglio usare le buone pratiche. Ciò consentirà di risparmiare tempo e fatica poiché i cambiamenti impiegheranno meno tempo per essere implementati.

Se possibile, fare piccoli passi per rifattorizzare le buone pratiche (ad esempio: in SQL che spezzerebbe le tabelle denoramlizzate in una normalizzata e usando le viste con i vecchi nomi delle tabelle).

Noterai che ho detto a lungo termine: qui si applica anche il triangolo "qualità, tempo, denaro" (cioè scegli due). Se non hai tempo, potresti dover ricorrere a vecchie pratiche, ma ciò significa che stai aggiungendo al problema e che anche il tuo progetto dovrà essere riparato.

Se continui a lavorare e aggiungi codice di cattiva progettazione, non finirai mai con una base di codice che utilizza una buona progettazione. Per quanto possibile, cerca di usare un buon design e un refactor per un buon design.


Non ho mai pensato a quella soluzione per i dati SQL. Sfortunatamente, non sono autorizzato a modificare la loro base di codice perché rilasciano aggiornamenti regolari. Tutto ciò che aggiungo deve essere completamente separato.
Rachel,

1
@ Rachel - Se hai il controllo delle nuove tabelle, utilizza un buon design per esse (suppongo che gli aggiornamenti del vecchio design non influiranno sulle nuove tabelle). Quando è necessario modificare il codice, i costi di manutenzione saranno inferiori.
Oded,

Gli aggiornamenti alla frequenza del software includono aggiornamenti del database e nuovi campi, quindi eliminare tabelle esistenti e riscriverle come viste non è un'opzione praticabile per me. Gli utenti usano ancora la parte esistente del software che utilizza queste tabelle, hanno solo bisogno di un'estensione. Se questo fosse il nostro codice anziché un fornitore di terze parti, lo implementerei in un batter d'occhio :) Nel complesso un buon punto di vista per la mia domanda originale.
Rachel,

1

Bene, penso che dipenda molto da ogni caso. Se le prestazioni e il design lo consentono, è meglio utilizzare le buone pratiche. Se, ad esempio, se quella tabella è una tabella ad accesso elevato, la creazione di un trigger per la sincronizzazione potrebbe avere un impatto negativo sulle prestazioni.

Ora, il tuo client non vedrà che hai utilizzato un design migliore, vedrà solo che la tua soluzione ha rallentato il suo sistema. Questo tipo di decisione dovrebbe essere presa caso per caso e dovresti usare la tua esperienza e i criteri per decidere.

Penso che tu abbia probabilmente fatto la scelta giusta.


1

Per quanto possibile, è necessario isolare il codice dell'applicazione dalla progettazione di dati scadenti.

Stai aggiornando le loro tabelle? In caso contrario, creare viste SQL per presentare tali tabelle in modo conveniente per l'applicazione. Le viste SQL sono relativamente facili da scrivere e molto più facili da testare rispetto al codice dell'applicazione.

Se è necessario aggiornare le tabelle legacy, prendere in considerazione la scrittura di stored procedure per gestire gli aggiornamenti. Sono un po 'più complessi da scrivere, ma possono essere testati istantaneamente.


1

Mantenere il vecchio codice sincronizzato quando si normalizza un database con i trigger ia una buona soluzione se è temporanea. L'obiettivo dovrebbe essere quello di cambiare il vecchio codice, ma quando si ha a che fare con una terza parte, potrebbe non funzionare. Dovrai rimanere aggiornato sulle modifiche dello schema.

Accumulare sempre più funzionalità sul codice errato creerà problemi continui. I work-arounds diventano la norma. Gli utenti saranno frustrati perché i cambiamenti impiegheranno troppo tempo e probabilmente introdurranno altri bug o limitazioni. Chi vuole essere il programmatore per dire che non possiamo farlo invece che non dovremmo farlo?

Alcuni codici possono essere lasciati soli; non abbiamo sempre quel lusso.


-1

Qui hai a che fare con un debito tecnico. In breve, il debito tecnico implica interessi, che devi pagare nel tempo, e ad un certo punto, devi rimborsarli.

Il tempo di Develloper costa denaro, quindi il debito tecnico può essere visto proprio come il debito reale e costa denaro reale.

Hai fondamentalmente due soluzioni principali e molte soluzioni intermedie. Puoi decidere di non voler rimborsare quel debito ora e continuare a pagare gli interessi. Ovviamente, questo a lungo termine costerà di più, ma ti consentirà di ottenere risultati in questo momento. Puoi anche scegliere di rimborsare quel debito, quindi non andrai più avanti finché non lo rimborserai, ma, alla fine, sarai libero da interessi.

Di solito hai delle scadenze per la consegna e perdere una scadenza causerà sfiducia nei confronti del cliente e alla fine la perderai. Questo potrebbe essere un motivo valido per rompere il debito tecnico: ritieni che ciò che guadagni con il cliente valga l'ulteriore dispendio di debito tecnico.

Sai che alla fine, devi adottare la nuova metodologia, altrimenti, otterrai sempre più debito e alla fine fallirai (ora, quando le persone decidono di ricominciare da zero o quando il progetto fallisce male).

Devi pianificare il modo in cui cambierai la base di codice esistente e passerai alla nuova pratica nel tempo, e distribuisci la modifica bit per bit su base giornaliera. Ad un certo punto, quando questi refactoring porteranno ad altre perdite, considera quale perdita è la peggiore e scegli la migliore.

Il costo del non refactoring aumenterà nel tempo (questi sono interessi del debito tecnico). Quindi questa diventerà alla fine la scelta più costosa.

Assicurati che il tuo capo capisca il concetto di debito tecnico. Anche con precauzione, creerai un debito tecnico. Ad un certo punto, il denaro da utilizzare per rimborsarlo. Quando crei un debito tecnico di proposito, DEVI avere un motivo valido per farlo e vedere il debito come un investimento (proprio come il debito reale). In tutti gli altri casi, NON FARE un debito tecnico apposta.

Potresti essere interessato a metodologie per evolvere DB e implementare tali evoluzioni: http://richarddingwall.name/2011/02/09/the-road-to-automated-database-deployment

A proposito, è un compito difficile, quindi buona fortuna. Ne vale la pena!


-1

Questo è un tipico problema di: "Devo raccogliere i frutti del mio lavoro adesso o dopo?" e non penso che ci possa mai essere una soluzione generica a quella risposta. Solo tu conosci tutti i fattori (tecnici e umani) coinvolti in tale decisione.

Tuttavia, il tuo problema solleva una domanda interessante:

Il refactoring automatico del codice sta facendo abbastanza progressi in modo che l'uniformità del codice debba essere valutata di più?

In definitiva, un cattivo design dovrebbe cambiare o morire. Altrimenti, non è un cattivo design. La vera domanda qui è sul costo del refactoring. Sembra chiaro dalla tua domanda che tu (o il tuo datore di lavoro) non siete disposti a pagare il prezzo adesso, e allo stato attuale della tecnologia, non è probabile che lo vogliate mai.

Tuttavia, l'automazione del refactoring del codice sta facendo alcuni progressi. Se i compilatori possono ottimizzare i binari oggi, chi può dire che non ottimizzeranno il codice domani? Ad un certo punto, sta per emergere qualche strumento, che consente a sviluppatori e progettisti di riformattare il loro codice molto facilmente, al fine di adattarsi alle nuove esigenze. Dopo tutto, gestire il codice legacy è una delle maggiori sfide di oggi.

Se un tale strumento dovesse mai esistere (non sarei sorpreso che lo sia già), sarebbe bene tenerne conto quando si prende una decisione del genere.


-2

Le buone pratiche prevalgono sempre su quelle povere. Se la tua base di codice è disseminata di codice nel modo sbagliato, non dovresti semplicemente caricare le tue cose allo stesso modo, dovresti scrivere il codice correttamente e quindi provare a educare tutti gli altri nel modo corretto.


Come sviluppatore dovresti conoscere il pericolo di affermazioni assolute.
whatsisname

Conosco anche il pericolo di affrontare cattive pratiche e scrivere codice in modo errato, e IMO è il peggior pericolo di tutti.
Wayne Molina,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.