Come affrontare il refactoring di un'applicazione Web esistente?


11

Ultimamente ho letto e pensato molto e sono giunto alla conclusione che forse dovrei ripensare la mia strategia di sviluppo web. Sto facendo molta programmazione al volo, e in 2 anni ho lavorato su un'applicazione web PHP, quello che potrebbe essere iniziato come un piccolo strumento è diventato piuttosto il grande progetto. Ma c'è un sacco di codice legacy da parte mia e del mio predecessore, frammento di codice che potrebbe avere senso in quel momento, ma ora sto mettendo in dubbio l'utilità di detto codice nella forma in cui è effettivamente. Inoltre, cose come il test unitario e lo sviluppo guidato dai test non erano nel mio ambito fino a poco tempo fa.

Quindi come affronteresti il ​​refactoring dell'applicazione web? Quali sarebbero le cose che dovrei cercare e in quale ordine? Che dire del browser game rispetto all'app web funzionale? Ci sarebbe quindi differenza nell'approccio?


4
Se non è rotto, non aggiustarlo. Dedica più tempo alla scrittura dei test e meno tempo a apportare modifiche non necessarie.
Macneil,

Solo per interesse. Che lingua / tecnologie hai usato per scrivere la tua applicazione? Che tipo di sito è? Vedi welie.com/patterns -> Contesto del design -> Tipi di siti
JW01

@ JW01 Uso PHP per la logica interna e AJAX per la gestione della vista e la convalida dei moduli. Questa sarebbe una variante del modello di applicazione basato sul Web ma disponibile solo in un determinato ambiente, in quanto si tratta di uno strumento interno.
Eldros,

Avevo un'immagine completamente diversa della tua app nella mia testa quando ho risposto alla domanda. Hai molta più libertà di modificare l'API che se fosse di dominio pubblico.
JW01

@ JW01 Non volevo essere troppo specifico, poiché volevo che questa domanda fosse utile anche agli altri.
Eldros,

Risposte:


6

Più o meno allo stesso modo in cui approcci qualsiasi tipo di codice legacy. Trovi un pezzo che è testabile, scrivi test per questo e refactoring.

Se non riesci a trovare un pezzo facilmente testabile, dovrai renderlo testabile senza l'imbracatura di sicurezza di una suite di test, nel qual caso cambi molto attentamente un pezzo di codice quasi testabile in modo che sia testabile.

Il codice che non rende le cose al browser - codice "infrastruttura", modelli, elementi che toccano il database - potrebbe essere un buon punto di partenza.

Modifica: Test dell'interfaccia utente: Con l'avvertimento che ho poca esperienza qui, un mio amico lo fa: esegue un pezzo di codice che genera HTML. Quindi modifica il suo codice e confronta il codice appena generato con la versione precedente (usando diff; non ha automatizzato fino in fondo). Le modifiche all'HTML significano che il refactoring si è rotto.


Come consiglieresti di testare la parte "view" di un'applicazione legacy - IE, la porzione HTML / JavaScript / CSS / etc? Sono d'accordo che il test unitario sia la strada da percorrere, ma il test del codice dell'applicazione sembra difficile da automatizzare.
Justin Ethier,

durante la creazione di test per un'interfaccia utente Web - il confronto tra il vecchio HTML e il nuovo HTML è un modo un po 'fragile di fare le cose. Tendo a identificare la semantica di una pagina Web e testarla. Vale a dire "L'impronta web (titolo della pagina, titolo, parole chiave, link in uscita, moduli) è cambiata?" non "L'HTML è cambiato?".
JW01

Puoi testare le app Web con un "browser senza testa", in sostanza una libreria che è per un test unitario che cos'è un browser per un ragazzo di QA. Nel mondo Java, ci sono HTMLUnit (java puro, autonomo) e WebDriver (controlla a distanza un vero browser come FireFox). Il mio progetto ha una serie di centinaia di test scritti in questo modo.
Tom Anderson,

@ JW01 Hai perfettamente ragione, è molto fragile. È ottimo per testare un refactoring in un modo unico: puoi verificare che il refactoring non abbia modificato l'output, ma ogni volta che cambi l'HTML generato, devi salvare l'HTML "nuovo previsto".
Frank Shearar,

10

C'è un grande libro su questo intitolato "Lavorare efficacemente con il codice legacy" di Michael Feathers. Ammettiamolo, abbiamo tutti un codice legacy.

La cosa principale è testare il nuovo codice che stai creando. Dato che devi toccare altre parti di codice, troverai l'opportunità di metterle anche alla prova. È un processo lungo e lento, ma se lo fai sistematicamente, puoi davvero migliorare il prodotto complessivo nel tempo.


3
"Ammettiamolo, tutto ciò che stiamo facendo è scrivere oggi il software legacy di domani." - Martin Fowler
Frank Shearar il

3
  • Sì - Le applicazioni Web sono diverse dai siti Web

Li tratterei separatamente. Se hai una parte del tuo sito che è semplicemente una raccolta di documenti (che sembrano uguali sia per gli utenti anonimi che per gli utenti connessi), il metodo migliore per strutturarlo è molto diverso da un'app Web che offre pagine dinamicamente diverse per ogni utente. Dividi queste due parti del sito in due app / componenti e affronta ciascuna parte in modo diverso.

  • Inizia a utilizzare il controllo versione

Una volta che il tuo codice è sotto il controllo della versione, puoi passare attraverso e, con sicurezza, rimuovere tutto il codice non necessario che avevi precedentemente conservato "per ogni evenienza" ecc. Non so come sono sopravvissuto senza il controllo della versione.

  • Ridurre gli infiniti

Se quattro URL diversi puntano tutti alla stessa risorsa, il problema è molto più grande. Alla fine hai a che fare con una quantità infinita di URL. Non appena è possibile, assicurarsi di disporre di un criterio di normalizzazione URL. Una volta fatto, puoi iniziare ad associare significati semantici agli URL ed essere in grado di effettuare ricerche inverse da risorsa a url. Ciò consente di separare la "stampa web" dalle "risorse" del sito.

Devi chiederti "dato un url qual è la sua forma normalizzata?". Una volta che hai bloccato questo. Quindi è possibile ridurre di oltre 50.000 URL sul tuo sito, ad esempio 2.000. che è molto più facile da comprendere e gestire nella tua mente.

vedi: http://www.sugarrae.com/be-a-normalizer-a-c14n-exterminator/

  • Inizia modellando "ciò che è", non "ciò che vuoi che sia"

Se stai riordinando un sito legacy, che non è stato progettato pensando alle migliori pratiche fin dall'inizio, allora sei tentato di passare da "un pasticcio" a "il design ideale". Credo che sia necessario farlo in almeno due passaggi: 'pasticcio' -> 'codice legacy ben modellato' -> 'nuovo codice ideale con funzionalità aggiunte'. Smetti di aggiungere funzionalità. Concentrati sul riparare il disordine o incapsularlo dietro uno strato anticorruzione. Solo allora puoi iniziare a cambiare il design in qualcosa di meglio.

Vedi: http://www.joelonsoftware.com/articles/fog0000000069.html

Vedi: http://www.laputan.org/mud/

  • Metterlo alla prova è una buona idea.

Crea una suite / framework di test e inizia ad aggiungere test. Ma è abbastanza complicato testare un codice legacy. Quindi, non ti rompere troppo. Finché hai il framework lì, puoi aggiungere test poco a poco.

Vedi: http://www.simpletest.org/en/web_tester_documentation.html

  • Abbi coraggio nelle tue convinzioni

La maggior parte della letteratura sulle migliori pratiche di sviluppo software è incentrata sul desktop / Enterprise App Centric. Mentre il tuo sito è in disordine, leggi questi libri e puoi avere soggezione della saggezza che trasuda da loro. Ma non dimenticare che la maggior parte di questa best practice è stata accumulata in tempi prima che il web / SEO diventasse importante. Sai molto sulla rete moderna, più di quanto menzionato nei libri classici come POEA, Gof ecc. C'è molto da prendere da loro, ma non scartare completamente la tua esperienza e conoscenza.


Potrei andare avanti. Ma quelle sono alcune cose che ho scelto quando ho rifatturato un vecchio sito legacy in uno nuovo lucido.


Buoni collegamenti di riferimento!
Nilesh,

2

Prima di fare qualsiasi cosa, è meglio avere il tuo progetto nel controllo del codice sorgente. In questo modo, è possibile eseguire il rollback delle modifiche o lavorare su modifiche importanti su un ramo separato, nonché sui punti chiave dei tag.

Successivamente, scrivi i test per qualsiasi codice che prevedi di modificare. Non hai bisogno di andare tutto in una volta, scrivendo test per tutto. Proprio quello su cui prevedi di lavorare immediatamente. La teoria afferma che, dato il tempo sufficiente, la maggior parte della base di codice sarà coperta da test. Si noti che alcuni refactoring sono "sicuri" da fare senza test: questi sono documentati nel libro del Codice legacy menzionato in precedenza e senza dubbio altrove.

Con i test in atto per una sezione di codice, modificare il codice. Fai tutto il necessario, purché i test continuino.

Anche con il codice legacy, è possibile eseguire TDD se si apportano aggiunte o modifiche. Basta scrivere prima i test per le modifiche previste, vederle fallire e quindi apportare le modifiche.

Alcuni strumenti possono essere utili qui. NDepend è in grado di indicare codice altamente accoppiato e altri odori. NCover tiene traccia dei livelli di copertura del codice. FxCop è essenzialmente un controllo della correttezza del codice, oltre a quello che fa il compilatore. Questi sono tutti strumenti utili da avere a portata di mano per un progetto di qualsiasi dimensione reale, in particolare la varietà legacy.

In definitiva, è un processo in più passaggi. Non provare a farlo tutto in una volta, prendilo un po 'alla volta.


-2

Se è abbastanza brutto da farmi incazzare, è abbastanza brutto per me eliminare l'intera cosa e scrivere una goccia in sostituzione.

Scoprirai che il più delle volte, ci vuole la stessa quantità di tempo per farlo, come fa per sedersi lì e in punta di piedi attorno a un pasticcio non organizzato e non documentato e accarezzarlo delicatamente.


2
Non sono d'accordo (anche se non ti ho dato -1). joelonsoftware.com/articles/fog0000000069.html
JW01

1
È davvero troppo una decisione situazionale difendermi con precisione. Potrei non farlo quando sto lavorando su una vasta libreria Objective-C, tuttavia, non ho scrupoli a scrivere una libreria javascript completamente nuova.
Sneakyness

Pessima idea! Vorrei aver letto l'articolo di Joel Spolsky a cui @ JW01 si collegava 2 anni fa prima di decidere di riscrivere un'app PHP esistente usando Angular & Bootstrap. Angular & Bootstrap sono grandi tecnologie ma sto ANCORA cercando di convertire questa vecchia app 2 anni dopo. Avrei dovuto modificare l'app esistente e non estrarla / sostituirla.
Zack Macomber,

Sono d'accordo soprattutto quando si considera il factoring nel tuo commento. "scenario" è la cosa chiave che determina una decisione. Dovresti strappare quell'enorme API che serve tutta la tua azienda? Chissà, c'è molto da considerare. Vorresti test prima di testare in seguito. L'articolo collegato è troppo lineare, come se ci fosse una dimensione adatta a tutti, ma che dire di quando qualcosa è difettoso o è davvero un vecchio codice? L'articolo suggerisce davvero che non passiamo dall'eredità con il codice che è più recente più facile da leggere e mantenere? Non c'è bianco e nero nel mondo degli sviluppatori, solo scenari e decisioni
James,
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.