Esprimerò un'opinione possibilmente controversa qui.
And as the coder, how much time is it reasonable to spend preening the
code?
Quasi nessuno se me lo chiedi! Ho visto aziende assumere nuovi team di sviluppatori per mantenere codebase legacy in modi che andavano oltre il trattare il legacy codebase come qualcosa di più di una scatola nera - come qualcosa da attraversare nei dettagli dell'implementazione ... e dopo un decennio la nuova squadra non era ancora così vicino come gli autori originali del codice. Nel frattempo, mentre tentavano di sondare e sondare i dettagli dell'implementazione del codice legacy, il software diventava sempre più buggato in funzionalità esistenti e vecchie, non in quelle nuove, poiché gli sviluppatori stavano cercando di modificare il vecchio codice che non potevano comprendere così come gli autori originali.
Questo è per codice non banale, ovviamente, e generalmente codice che non è stato progettato esattamente contro standard ragionevoli.
A mio parere, tale codice legacy dovrebbe essere trattato come una libreria opaca, da chiamare, non modificata. Il vecchio codice, a condizione che non stia funzionando verso la completa obsolescenza, dovrebbe sempre più trasformarsi in una scatola nera - un pacchetto stabile destinato a essere usato, non modificato. Le interfacce dovrebbero essere identificate ed estratte, laddove possibile, dovrebbero essere creati test di correttezza e le implementazioni non devono essere toccate, né pienamente comprese a meno che non richiedano assolutamente modifiche (es: sono buggy) ... a che punto se sono buggy e spesso ho bisogno di aggiornamenti per i dettagli di implementazione, prenderei in considerazione la sostituzione di quella sezione inaffidabile del codice legacy con qualcosa di nuovo (stessa interfaccia ma nuova implementazione) come potenzialmente più veloce di sperare che qualche nuovo sviluppatore sia in grado di comprendere il vecchio codice che l'autore originale non ha 'anche scrivere correttamente e testare correttamente. Cercare di comprendere il codice che non funziona nemmeno correttamente scritto da qualcun altro molto tempo fa è spesso un tentativo infruttuoso. È come cercare di capire come funziona un motore a combustione invertendo la progettazione di uno rotto il cui design è sempre incline a far esplodere a caso il motore.
Per quanto riguarda la capacità di decifrare il codice, spesso lo vedo come una funzione dell'interfaccia. Un'interfaccia ben documentata in cui ogni funzione non causa più di un singolo effetto collaterale produrrà spesso un'implementazione che è proporzionalmente facile da capire. Nel frattempo un'interfaccia controintuitiva che, di per sé, è difficile da capire e da usare, avrà spesso implementazioni che sono proporzionalmente difficili da comprendere. Che cosa dovrebbe fare qualcosa per tutti i possibili casi di input è la prima cosa da capire prima di capire come funziona, e alcune interfacce sono in realtà così complesse con così tanti disparati effetti collaterali che è difficile persino rispondere alla domanda "cosa" senza sollevando ulteriori "e se?" domande per casi limite difficili. In tal caso, l'implementazione sarà in genere senza speranza da decifrare come interfaccia.
Naturalmente a volte un'interfaccia chiara e ben documentata può ancora utilizzare un algoritmo molto complesso per l'implementazione, ma relativamente parlando, il codice sorgente sarà spesso relativamente più facile da capire se l'interfaccia è facile da capire. La prima cosa che vorrei fare prima di entrare nei dettagli di implementazione di qualcun altro è studiare l'interfaccia necessaria per interagire con il loro codice e costruire idealmente un test per verificare le mie ipotesi e per assicurarmi che l'interfaccia soddisfi correttamente i suoi requisiti documentati. Se l'interfaccia è semplice e posso facilmente comprenderla, spesso sarà anche il codice che implementa l'interfaccia e, in caso contrario, poiché l'interfaccia è così chiara e facile da capire, ci vorrà poco tempo per inventare un nuovo implementazione che soddisfa gli stessi requisiti.
Per quanto riguarda l'ultima domanda sul tempo richiesto, vorrei prima fare tutte le cose sopra menzionate. C'è un anticipo di tempo necessario, variabile ma non troppo variabile per capire come fare la prossima stima se l'obiettivo è familiarizzare con una base di codice legacy.