Progettazione di una soluzione migliore, proveniente dalla base di codice esistente [duplicato]

5

Il codice

Ho un software giornaliero-usato per cliente di alto valore commerciale scritto in PHP e che si estende su circa 600K di linee di codice.

Il cliente da lungo tempo ha bisogno, vuole e richiede nuove funzionalità e funzionalità. Il tempo per farlo è ieri . Quindi, basta scrivere le nuove funzionalità e implementare nuove funzionalità e consegnarle al cliente, sì? Bene, no, qui ci sono alcuni problemi che hanno causato un notevole dolore agli sviluppatori attuali:

Il code-base esistente è ... una grande palla di fango .

Problemi notevoli:

    Il codice
  • è peloso - una singola caratteristica permea tutto, il codice di tracciamento è un problema e l'aggiunta di una funzione potrebbe avere un impatto su tutto il resto
  • non ci sono test
  • mix di codice procedurale e orientato agli oggetti basato su cattive pratiche di programmazione
  • file che raggiungono 6000 righe di HTML, CSS, PHP, SQL, jQuery, JavaScript, commenti
  • completa noncuranza / non esistenza del pattern MVC / separazione delle preoccupazioni. Il codice viene mescolato insieme
  • alcune logiche di business dipendono da cose volatili che non hanno alcuna relazione con il codice (come i metadati del database)
  • i valori codificati, i percorsi e la mancanza di configurabilità contribuiscono alla mancanza di sicurezza dell'architettura attuale
  • i blocchi ripetuti di sostanzialmente lo stesso codice contribuiscono a funzioni simili che funzionano in modo leggermente diverso. L'aggiornamento di uno non aggiorna l'altro
  • Il codice
  • è lento, la mancanza di documentazione., ecc. ecc. molte altre cose possono essere fatte meglio

Funziona ...

La cosa buona è che funziona ... La funzionalità che è lì, è ragionevolmente elaborata per casi aziendali reali, ma ... andare avanti è doloroso.

Il problema

È più facile ora (e più veloce) aggiungere una nuova funzionalità usando lo stile di codice esistente, principalmente usando l'approccio cut-n-paste-n-modify, così perpetuando la cattiveria, piuttosto che fare riscritture di questa cosa usando al momento le migliori pratiche moderne esistenti.

Soluzione?

Si parla di riscrivere il tutto usando uno dei framework attualmente all'avanguardia (es. ZF2), ma nel farlo significa ignorare le richieste dei clienti, impiegare molto tempo per costruire il software e essenzialmente creare nuovo software ( versione 0.0.1) per il cliente, con tutti i bug del nuovo software e la mancanza di funzionalità e funzionalità del software maturo.

Un altro pensiero è di fare uno sviluppo incrementale. Ad esempio, quando arriva una nuova funzione, scrivila usando un nuovo approccio. Attualmente non funziona per il motivo indicato nel titolo "Il problema" sopra.

Ancora un'altra idea è di fare un lento refactoring della base di codice esistente ... Potrebbe funzionare a ripulire cose come MVC e una miriade di altre cose, e ci vorrà molto tempo, e sarà essenzialmente come dipanare un gomitolo di lana annodato strettamente avvolto. Ma fare questo non affronterà le cose come test di unità, iniezione di dipendenza, principi moderni del framework e così via.

Quindi, alla fine, stanno arrivando nuove funzionalità, il codice viene aggiunto e la base di codice esistente non migliora. Cosa potresti suggerire di fare in questo caso?

    
posta Dennis 10.02.2014 - 23:03
fonte

3 risposte

3

But doing this will not address things like unit testing, dependency injection, modern framework principles, and so on.

Perché no? Non è necessario testare l'unità tutto, solo attorno a ciò che si cambia / refactoring. E se lo verifichi, aggiungerai progressivamente mock e DI.

Consiglio vivamente il libro di Michael Feather: Lavorare efficacemente con il codice legacy , in quanto descrive abbastanza bene il problema e le soluzioni.

    
risposta data 10.02.2014 - 23:57
fonte
2

Mi trovo in una situazione simile, se in uno stack tecnologico completamente distinto, e nel mio caso (e credo che anche nel tuo) è abbastanza ovvio che un'intera riscrittura del codice di produzione non è un'opzione, dovuta a limiti pratici. Ciò che ha più senso è portarlo a piccoli passi. Quando ti viene richiesto di introdurre una nuova funzionalità, lo fai in un modo più gestibile; quando devi modificare un modulo / una classe / metodo / qualsiasi, prendi l'opportunità e rifattalo. Cerca sempre di ottenere un codice migliore, se forse a scapito di ridurre la tua velocità un po 'per avere un po' di tempo per pagare il tuo debito. Inoltre, se puoi introdurre in silenzio un framework che può essere utile a lungo termine, mentre coesiste con il fango corrente, consideralo.

    
risposta data 10.02.2014 - 23:27
fonte
0

La duplicazione non è un problema, è un modo per ottenere risultati rapidi. Devi solo ricordare che hai un debito tecnologico e dedicare tempo per generalizzare il tuo codice in futuro.

Che cosa intendi per going forwards is painful - stai pianificando qualcosa di grande o sono solo funzionalità aggiuntive? C'è solo una ragione per riscrivere tutto - il caso in cui l'architettura della tua attuale applicazione non si adatta al tuo sviluppo futuro.

Una volta ho avuto un progetto che stavo sviluppando da diversi mesi e non era in particolare 'sporco'. Ho anche fatto test unitari. E poi i requisiti sono cambiati e mi ci sono voluti altri due mesi per capire che devo cambiare architettura. Dopo che me ne sono reso conto, trascorro 3 settimane per riscrivere completamente quel servizio: era uno sviluppo attivo ma sapevo cosa fare.

Penso che il tuo caso sia diverso: devi solo dedicare più tempo alla pulizia. Inizia da piccole cose. Durante il prossimo bugfix o l'implementazione di una nuova funzionalità non saltare direttamente allo sviluppo. Dedica un po 'di tempo alla pulizia. Prendi una regola per migliorare leggermente qualsiasi codice che tocchi. Ovviamente senza test unitari è rischioso - e lo capirai molto velocemente, quindi la prossima volta avrai più insenso a scrivere test unitari.

Allo stesso tempo è necessario iniziare a pensare al design di alto livello in modo da poter iniziare a generalizzare e scomporre il sistema. In senso stretto non si tratta di refactoring. Le persone tendono ad abusare di questo termine.

    
risposta data 11.02.2014 - 10:49
fonte

Leggi altre domande sui tag